<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Shizuku</title><description>Life will change.</description><link>https://shizuku.halory.fun/</link><templateTheme>Firefly</templateTheme><templateThemeVersion>6.15.10</templateThemeVersion><templateThemeUrl>https://github.com/CuteLeaf/Firefly</templateThemeUrl><lastBuildDate>2026年11月13日 15:57:36</lastBuildDate><item><title>绵流篇游玩感想</title><link>https://shizuku.halory.fun/posts/mian-liu-pian-you-wan-gan-xiang/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/mian-liu-pian-you-wan-gan-xiang/</guid><pubDate>Wed, 28 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;终于玩到寒蝉第二篇了，跟第一篇差不多，绵流篇也是从第六章开始，剧情才逐渐开始悬疑起来的，然后又是多重的剧情反转，推完后我整个人都惊了，居然是这样吗？非常好奇【解】的时候要怎么圆回来&lt;/p&gt;
&lt;p&gt;然后我也注意到了第二篇的一个叙事技巧，我姑且称之为misdirection&lt;/p&gt;
&lt;p&gt;最初我们遇到诗音的时候，是圭一和老爸去吃甜品的时候，因为诗音和魅音非常像，游戏之前从来没有交代过魅音有一个双胞胎妹妹，并且龙宫蕾娜、北条沙都子和古手梨花都不知道有这个双胞胎妹妹，因此我们一开始和圭一一样，认为诗音就是魅音，并且是展示了女性力的魅音。这是游戏埋的第一个misdirection&lt;/p&gt;
&lt;p&gt;再接着，由于故事开篇的社团活动中，圭一没有把玩偶给魅音，这伤害到了魅音，而圭一浑然不觉，直到蕾娜提醒了之后，圭一才意识到这点不对，于是故事就有点开始往诗音和圭一的恋爱线推进了，直到诗音和魅音同台出现在玩具店中，这才清楚诗音和魅音确实是两个人，是双胞胎&lt;/p&gt;
&lt;p&gt;在故事澄清了双胞胎这一设定之后，我们自然而然就把诗音和魅音完全区分开了，这是游戏埋的第二个misdirection，以至于在绵流仪式之后，我们虽然没有见过诗音，但是始终坚信晚上跟我们通话的就是诗音，不论是情绪还是口吻，都像是诗音。直到绵流仪式的第三天，大石跟圭一提到“诗音在绵流仪式第二天就失踪了”，然后讲述了“村长”失踪的情况（在绵流仪式的第二天，村长很早就去市里看痔疮了，因为各种原因，耽搁了很久，晚上一回到雏见泽就去开会了，然后在会后回去的路上失踪的，并且没有人知道村长去市里这件事），而昨天和诗音通话时，她说“因为自己把闯进祭具殿的事跟村长说了之后，才会让村长出事的”，稍微推理一下就知道，诗音根本没有机会和村长说这件事。因此晚上等“诗音”再打电话过来的时候，圭一把这段推理和电话那头说了一遍，哭声突然变成了狂笑，这才知道原来这几天一直是在和魅音通话&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;吓我一跳&quot; title=&quot;吓我一跳&quot; loading=&quot;lazy&quot; width=&quot;2560&quot; height=&quot;1440&quot; src=&quot;/_astro/Magpie_002-20261028181833-tmdkecv.DeATaY2H_ZGBhtH.webp&quot; /&gt;&lt;figcaption&gt;吓我一跳&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;再后来，先是跟蕾娜一起去魅音家谈话，然后是圭一和魅音去地下室两人独处，在这里发现了精神已经异常的诗音（这是游戏埋的第三个misdirection），警察闯入要逮捕魅音，魅音往通道逃跑，……。经过种种之后，诗音最后进了一个私人精神医院，而魅音已经下落不明。直到有一天晚上，魅音突然到圭一家楼下把圭一捅了，好像又去诗音那里逼得诗音跳楼自杀了。圭一在医院养了一段时间伤之后，大石突然到访，提到“在地下室的井里面，发现了已经死掉的魅音，根据验尸结果，她是警察闯入逃跑的那天，由于向上爬出通道时不慎摔落，在井里面摔死的，并且头部骨折的地方和诗音跳楼时骨折的地方一致”。那么那天晚上来找圭一的到底是谁？拿刀捅圭一的又是谁？也许只能是诗音了吧（毕竟前面几章也提到过诗音有不错的演技），但是人可能是诗音，而实质上控制诗音头脑的则是鬼，就跟魅音一样。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;毕竟是双胞胎，两人都有鬼的血脉，只要体内的鬼被唤醒，就不难做出一致的吃人行为吧&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;不过这还不是最让我吃惊的，大石又提到“根据尸检，鹰野三四早在绵流仪式前几天就已经身亡了”，那么当初带圭一他们一起进祭具殿的“鹰野三四”又是谁？如果当初在绵流仪式的晚上，“鹰野三四”没有让几个人进祭具殿的话，就不会有人死掉，可以说是本篇的罪魁祸首了，但是竟然？&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;还得是我大石&quot; loading=&quot;lazy&quot; width=&quot;2560&quot; height=&quot;1440&quot; src=&quot;/_astro/Magpie_004-20261028183546-b0tqei1.BLQ-CYQI_11V2Db.webp&quot; /&gt;&lt;figcaption&gt;还得是我大石&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;‍既是游戏的misdirection，又是留下的两个谜题，😀太刺激了&lt;/p&gt;
&lt;p&gt;‍&lt;/p&gt;</content:encoded></item><item><title>WebMCP尝鲜</title><link>https://shizuku.halory.fun/posts/webmcp-chang-xian/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/webmcp-chang-xian/</guid><description>你需要给你的Web应用添加WebMCP了</description><pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h1&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;MCP一般都是运行在服务端的，一般都需要启动一个后端程序，而且一般都在本地；而WebMCP则是在客户端，这里的WebMCP Tools由网站的开发者自己开发和维护。&lt;/p&gt;&lt;p&gt;出发点是为了方便AI对Web应用进行操作。以买东西为例，从找商品、加入购物车到购买和支付，其实都可以由程序来执行，尤其是在肯德基、瑞幸、蜜雪这些商品名称不一致的餐饮店。早期的豆包手机我不知道是什么原理，大概主要还是靠图像理解吧，也能自主完成下单，但效果肯定不如理想中的MCP那么方便、那么高效。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;腾讯好像也在搞WebMCP了。试想一下，如果微信接入了AI Agent，可以访问所有的微信小程序，而像KFC、蜜雪这些小程序都做了WebMCP，支付方式又是微信支付的话，可能和AI对话了不到10秒，就已经下单并支付成功了。如果后续还支持用户自定义定时任务，比如每天早上八点都要来一杯美式，那就很方便了。预测一下，明年小程序一定会非常火。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;我之前在搞的vnweb，添加游戏的过程有点繁琐：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;选择Provider&lt;/li&gt;
&lt;li&gt;输入关键字并搜索&lt;/li&gt;
&lt;li&gt;从搜索结果里找到游戏&lt;/li&gt;
&lt;li&gt;在游戏设置页面分别在SGDB上搜索封面、背景、图标和徽标&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;正好借此来尝尝鲜。理想情况下，上述操作要是用WebMCP实现，应该只需要1秒。&lt;/p&gt;&lt;a href=&quot;https://github.com/Halory-Ito/vnweb&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Halory-Ito&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;vnweb&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Waiting for api.github.com...&lt;/div&gt;&lt;div&gt;&lt;div&gt;00K&lt;/div&gt;&lt;div&gt;0K&lt;/div&gt;&lt;div&gt;0K&lt;/div&gt;&lt;span&gt;Waiting...&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;思路&lt;a href=&quot;#思路&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;WebMCP的思路，是让网页把自己能做什么注册成一个个工具，AI Agent发现之后直接调用，而不是去截图、猜按钮、模拟点击。&lt;/p&gt;&lt;p&gt;核心就一个东西：​&lt;code&gt;document.modelContext&lt;/code&gt;。往上面注册工具即可：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;modelContext&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;registerTool&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;page-title&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;获取当前页面标题&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;inputSchema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;object&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;properties&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {} },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;execute&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;title&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;一个工具包含几个关键字段：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt;​：唯一标识，长度1~128，只能用字母数字和​&lt;code&gt;_ - .&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;description&lt;/code&gt;：写给AI看的自然语言说明，AI靠它决定用不用这个工具，很关键&lt;/li&gt;
&lt;li&gt;&lt;code&gt;inputSchema&lt;/code&gt;：JSON Schema，描述入参长什么样&lt;/li&gt;
&lt;li&gt;&lt;code&gt;execute&lt;/code&gt;：真正干活的函数&lt;/li&gt;
&lt;li&gt;&lt;code&gt;annotations&lt;/code&gt;：可选，告诉AI这工具是不是只读、有没有严重后果之类的&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;除了注册，还有​&lt;code&gt;getTools()&lt;/code&gt;​（列出工具）和​&lt;code&gt;executeTool()&lt;/code&gt;​（执行某个工具）。注册时可以传一个​&lt;code&gt;AbortSignal&lt;/code&gt;​来控制注销。另外还能给​&lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;​加​&lt;code&gt;toolname&lt;/code&gt;之类的属性做声明式注册，不过我这里用的是命令式那套。&lt;/p&gt;&lt;p&gt;这套规范目前还是W3C社区组的草案（Draft Community Group Report），Chrome也只是实验阶段，所以实际做的时候需要配一个polyfill兜底。&lt;/p&gt;&lt;p&gt;React项目里我用了两个包：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/usewebmcp&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;usewebmcp&lt;/code&gt;&lt;/a&gt;：把工具跟组件生命周期绑起来的Hook，卸载时自动注销&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@mcp-b/webmcp-polyfill&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;@mcp-b/webmcp-polyfill&lt;/code&gt;&lt;/a&gt;：浏览器没有原生实现时补上运行时，比如Firefox就不支持&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;code&gt;usewebmcp&lt;/code&gt;​有一个我比较喜欢的地方：它只用JSON Schema、不做校验，但能从schema的​&lt;code&gt;as const&lt;/code&gt;​字面量推导出入参的TypeScript类型。写代码时​&lt;code&gt;input.keyword&lt;/code&gt;是什么类型一清二楚，字段写错会直接编译报错。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;添加tool&lt;a href=&quot;#添加tool&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;我想要的功能很明确：给一个游戏名，自动搜索、匹配、加进游戏库，顺便把封面、背景、图标、徽标都配好。&lt;/p&gt;&lt;section&gt;&lt;h2&gt;目录结构&lt;a href=&quot;#目录结构&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;WebMCP的运行时是通用的，放根级​&lt;code&gt;lib/webmcp/&lt;/code&gt;​；具体工具属于游戏模块，收在​&lt;code&gt;features/game/webmcp/&lt;/code&gt;：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;lib/webmcp/                     # 通用运行时（其它模块以后也能用）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;features/game/webmcp/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── components/game-webmcp-tools.tsx   # 只注册，不渲染&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;├── hooks/use-add-game-tool.ts         # 业务逻辑&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;└── lib/&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;├── add-game-tool-schema.ts        # JSON Schema&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;└── fetch-game-images.ts           # 去SGDB抓图&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;之所以不单独建一个​&lt;code&gt;features/webmcp/&lt;/code&gt;，是因为这个项目里feature之间是零相互引用的，而工具要调用游戏模块的搜索、入库接口，放到独立feature里反而会破坏这条约定。所以运行时上提成公共的，工具留在它所属的域内。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;注册polyfill&lt;a href=&quot;#注册polyfill&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;usewebmcp&lt;/code&gt;​在注册的时候会立刻去读​&lt;code&gt;document.modelContext&lt;/code&gt;，它不会等你事后装好的运行时，所以polyfill一定要在工具注册前装。&lt;/p&gt;&lt;p&gt;我抽了一个幂等的小函数：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;lib/webmcp/runtime.ts&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;installWebMCP&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@mcp-b/webmcp-polyfill&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;installed&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ensureWebMcpRuntime&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;installed&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;typeof&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;window&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;undefined&quot;&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;// SSR或已装过，跳过&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;installWebMCP&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;installed&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;p&gt;然后在客户端组件的模块顶层就调用它，模块求值一定发生在Hook挂载之前：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&quot;use client&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;ensureWebMcpRuntime&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@/lib/webmcp&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;useAddGameTool&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;@/features/game/webmcp/hooks/use-add-game-tool&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;ensureWebMcpRuntime&lt;/span&gt;&lt;span&gt;(); &lt;/span&gt;&lt;span&gt;// 必须在useWebMCP注册之前&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;GameWebMcpTools&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;useAddGameTool&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;定义tool&lt;a href=&quot;#定义tool&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;features/game/webmcp/lib/add-game-tool-schema.ts&lt;/span&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ADD_GAME_TOOL_NAME&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;add_game_to_library&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;addGameToolInputSchema&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;object&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;properties&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;keyword&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;string&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;游戏名称关键词，用于在数据源中搜索&quot;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;provider&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;string&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;数据源id，例如vndb、bangumi、steam、steamgriddb；留空默认vndb&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;externalId&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;string&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;已知的数据源游戏ID；提供后跳过搜索，直接用这个ID&quot;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;imageSource&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;string&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;图片来源，默认steamgriddb&quot;&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;required&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;keyword&quot;&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;description&lt;/code&gt;建议认真写，因为AI选不选这个工具、参数怎么填，很大程度上看它。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;发现tool&lt;a href=&quot;#发现tool&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;整个流程就是：搜索→取详情→入库→抓图→写回→刷新缓存。&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// features/game/webmcp/hooks/use-add-game-tool.ts（节选）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;useAddGameTool&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;queryClient&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;useQueryClient&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;router&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;useRouter&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;useWebMCP&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ADD_GAME_TOOL_NAME&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;description&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;搜索游戏并自动添加到游戏库，同时从SteamGrid DB获取并配置封面、背景、图标和徽标。&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;inputSchema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;addGameToolInputSchema&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;annotations&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;readOnlyHint&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt; }, &lt;/span&gt;&lt;span&gt;// 会改数据，明确告诉AI不是只读&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;execute&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;keyword&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;keyword&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;??&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;&lt;span&gt;keyword&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;请提供游戏名称关键词keyword&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;provider&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resolveProvider&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;provider&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;imageSource&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;imageSource&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;??&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;DEFAULT_GAME_IMAGE_SOURCE&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// 1. 搜索（或按externalId直接识别）→ 取详情&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;19&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;externalId&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;externalId&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;??&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;20&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;gameInfo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;21&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;externalId&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;22&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;gameInfo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getGameInfoByIdApi&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;externalId&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;provider&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;24&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;searchGameByNameApi&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;keyword&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;provider&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;25&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;items&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;26&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`在数据源「&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;provider&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;」里没搜到「&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;keyword&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;」`&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;27&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;externalId&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;28&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;gameInfo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getGameInfoByIdApi&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;first&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;provider&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;29&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;30&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;&lt;span&gt;gameInfo&lt;/span&gt;&lt;span&gt;?.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;没拿到游戏详情&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;31&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;32&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// 2. 入库&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;33&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;created&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createGameInfoApi&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;gameInfo&lt;/span&gt;&lt;span&gt;, { &lt;/span&gt;&lt;span&gt;provider&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;externalId&lt;/span&gt;&lt;span&gt; });&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;34&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;gameId&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;created&lt;/span&gt;&lt;span&gt;?.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;?.&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;35&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;&lt;span&gt;gameId&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;游戏创建失败&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;36&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;37&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// 3. 抓图（见下一节）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;38&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;imageResult&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fetchGameImages&lt;/span&gt;&lt;span&gt;&lt;span&gt;({ &lt;/span&gt;&lt;span&gt;gameInfo&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;keyword&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;source&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;imageSource&lt;/span&gt;&lt;span&gt; });&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;39&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;images&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;span&gt;&lt;span&gt;imageResult&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;images&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;40&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;&lt;span&gt;images&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;cover&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;gameInfo&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;cover&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;&lt;span&gt;()) &lt;/span&gt;&lt;span&gt;images&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;cover&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;gameInfo&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;cover&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;41&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;42&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// 4. 写回 + 刷新前端缓存&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;43&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Object&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;keys&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;images&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;updateGameInfoById&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;gameId&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;images&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;44&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;queryClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;invalidateQueries&lt;/span&gt;&lt;span&gt;({ &lt;/span&gt;&lt;span&gt;queryKey&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;game&quot;&lt;/span&gt;&lt;span&gt;] });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;45&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;queryClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;invalidateQueries&lt;/span&gt;&lt;span&gt;({ &lt;/span&gt;&lt;span&gt;queryKey&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;game-cards&quot;&lt;/span&gt;&lt;span&gt;] });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;46&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;queryClient&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;invalidateQueries&lt;/span&gt;&lt;span&gt;({ &lt;/span&gt;&lt;span&gt;queryKey&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;game-sidebar&quot;&lt;/span&gt;&lt;span&gt;] });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;47&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;48&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;gameId&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;gameInfo&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;nameCn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;gameInfo&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;provider&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;images&lt;/span&gt;&lt;span&gt; };&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;49&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;50&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;51&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;默认数据源我选了VNDB，但这里有个细节不能写死，因为数据源是插件化的，用户可以在设置里禁用：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;DEFAULT_GAME_PROVIDER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;vndb&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resolveProvider&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;requested&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;options&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getManualSearchProviderOptions&lt;/span&gt;&lt;span&gt;(); &lt;/span&gt;&lt;span&gt;// 已启用的手动搜索数据源&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;requested&lt;/span&gt;&lt;span&gt;?.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;trim&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;&lt;span&gt;options&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;some&lt;/span&gt;&lt;span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;)) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;throw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;`不支持的数据源「&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;」，可选：&lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;options&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;join&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;、&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// 优先VNDB，被禁用了就退回到第一个可用数据源&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;16&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;options&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;some&lt;/span&gt;&lt;span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;DEFAULT_GAME_PROVIDER&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;DEFAULT_GAME_PROVIDER&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;17&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;options&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;]?.&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;??&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;DEFAULT_GAME_PROVIDER&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;18&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;全局挂载&lt;a href=&quot;#全局挂载&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;工具要挂在全局（任意页面都能被AI发现），所以我把它放进了根布局：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;app/layout.tsx&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;AppLayout&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;children&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;&amp;lt;/&lt;/span&gt;&lt;span&gt;AppLayout&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;GameWebMcpTools&lt;/span&gt;&lt;span&gt; /&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Toaster&lt;/span&gt;&lt;span&gt; /&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;测试&lt;a href=&quot;#测试&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Chrome和Edge可以借助​&lt;code&gt;WebMCP Inspector&lt;/code&gt;​这个插件来发现和使用WebMCP，这里以​&lt;code&gt;rewrite&lt;/code&gt;为例，通过和Agent对话来实现MCP的调用：&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;插件展示&quot; loading=&quot;lazy&quot; width=&quot;2488&quot; height=&quot;1533&quot; src=&quot;/_astro/image-20261009194711-7ie0xfr.BRYswAy__Z1OskRo.webp&quot; /&gt;&lt;figcaption&gt;插件展示&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;很顺利，然后再来看看执行时间，也是很快的，只用了一秒多钟，如果网速再快点，或者使用本地模型的话，基本连1秒都不需要&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;与神对话&quot; loading=&quot;lazy&quot; width=&quot;1518&quot; height=&quot;679&quot; src=&quot;/_astro/image-20261009194903-lhp8ro0.jgX83cOC_ZS354m.webp&quot; /&gt;&lt;figcaption&gt;与神对话&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;既然WebMCP是位于客户端的，那么就不要想着让你本地的OpenCode发现这个MCP了&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;总结&lt;a href=&quot;#总结&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;个人感觉还是很好用的，以后必定是Web的未来，🤪前端永生&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>人生第一次漫展</title><link>https://shizuku.halory.fun/posts/ren-sheng-di-yi-ci-man-zhan/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/ren-sheng-di-yi-ci-man-zhan/</guid><pubDate>Mon, 05 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2026年10月2日，阴雨天，重庆梦乡漫展&lt;/p&gt;
&lt;p&gt;大二上学期，有一个二次元浓度比较高的同学，曾经说过“正经人谁去漫展”一话，让我对参加漫展一事产生了些顾虑，但也只是暂时的，漫展那么多的Coser，还有老师们出的角色很多我都认识，比起去热门景点，看着这么多不认识的人，我宁愿去一次漫展；&lt;/p&gt;
&lt;p&gt;但一直没有什么机会，本科阶段一直都待在离大型漫展很远的地方，小漫展我是不愿意去的（朋友圈有个人去了一个几十个人的漫展，评价不是很好），热热闹闹的才有意思。也许可以本着去漫展，而顺便去某一个城市旅旅游的想法，比如上海、杭州、成都等，但是我要一个人吗？身边也确实找不到离我比较近，又愿意陪我去的朋友。何况，大三忙着学业和比赛，大四又忙着考驾照、写毕设、找实习，基本也就没有机会了。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;其实我会选择保到重庆的另外一个原因，就是川渝漫展多&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;国庆期间，我正式遂愿了，参加了重庆梦乡d2的漫展，相比于其他三天（都是雨天），d2的天气还过得去，而且正值降温，即使没有空调也不会热。&lt;/p&gt;
&lt;p&gt;早上七点从宿舍打车到附近的地铁站，然后坐了一个多小时地铁到了悦来站，还没有过出口的闸机呢，就看见闸机对面的区域坐着或站着一堆的Coser、妆娘、毛娘等，我算是开了眼，之前哪里见过这等景象，此时暗自窃喜，这就是我想要的&lt;/p&gt;
&lt;p&gt;出了地铁站，沿着路线，就到了&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://r2.halory.fun/gallery/ChongQing-ManZhan-2026/open.jpg&quot; alt=&quot;入场&quot; /&gt;&lt;figcaption&gt;入场&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;漫展是9点开始，我提前十分钟就到了，然后远远地就看到出胡桃（原神）和蕾塞（电锯人）的老师，我在想现在去集邮会不会早了，可能老师还没准备好，然后就先自己逛了下（后来找不到人了）&lt;/p&gt;
&lt;p&gt;等把两个场地都逛得差不多了的时候，就开始疯狂找老师集邮了，目标为胡桃和月美（TYPE-MOON）；刚开始的时候集邮合影，但是我是一个人去的，没有人帮忙拍照，自己拍也拍得不是太好，后面就改成“老师，我可以给你拍张照吗！！”&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://r2.halory.fun/gallery/ChongQing-ManZhan-2026/alice.jpg&quot; alt=&quot;久远寺有珠小姐&quot; /&gt;&lt;figcaption&gt;久远寺有珠小姐&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;前中期基本就是这么度过的，陆陆续续会刷新新的老师，虽然错过了神秘仪式（梦之泪伤那个）有点可惜，但是也不乏乐趣，而且还遇到了One Piece、Jujutsu Kaisen、Shingeki no Kyojin、Naruto等Coser团体，他们都拍了请其他摄影老师拍了大合照，还有一个乐游团（好像是叫这个名字吧）的走场活动。真好啊，一群有着相同爱好的人聚集在一起，而且这种群像就是我想要的&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://r2.halory.fun/gallery/ChongQing-ManZhan-2026/GU.jpg&quot; alt=&quot;GU&quot; /&gt;&lt;figcaption&gt;GU&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;后面主要就是在宅舞区了，之前刷B站的时候看到宅舞都看不懂，感觉跳得一般，不知道看点在哪里，但是到了线下，那感觉就不一样了，不管认不认识吧，曲子出来之后，会跳的就一起上去跳了，而且还相互打配合（宅舞有些是有舞者互动的），整整齐齐地完成了一次又一次表演，太有活力了&lt;/p&gt;

  
  您的浏览器不支持 HTML5 视频播放。

&lt;p&gt;最后的半小时，我就留在了外场，吃点饼干充下电，之前刷到漫展视频说，中午吃饭可能要自己点外卖，或者自己带点吃的，所以我昨晚还特意去了趟赵一鸣，但是我多虑了，漫展里面就有吃的，而且麦当劳的价格和外面一样，好像还更便宜，至少比里面其他小吃便宜&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;我要吐糟里面的小吃拼盘，就三四个小鸡块、三四个小洋葱圈和三四个小鸡米花，然后底下十几个锅巴片，看着是满满一盒，但是你卖我20是不是有点过分了&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;然后在场外，又遇到一个老师，不知道Cos的是哪个角色，头上戴着头套（好像是叫kigurumi），玩着电吉他（又好像是贝斯），人很高，形象也很好，挺干净的，我就上去拍了一张，直觉告诉我，这可能是全场最好看的&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://r2.halory.fun/gallery/ChongQing-ManZhan-2026/kigurumi.jpg&quot; alt=&quot;感觉超有气质的&quot; /&gt;&lt;figcaption&gt;感觉超有气质的&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;散场后，本地的同门推荐我可以去观音桥看看，那里谷子店很多，我去了，发现很多的Cos散场后也是去的观音桥，大家都在逛谷子点，并且也彻底慢下来了。Cos也是人来着，但是和Cos一起逛谷子店，潜意识就会处理为和某个动漫人物、或者游戏角色一起的场景，我很喜欢这种感觉。&lt;/p&gt;
&lt;p&gt;慢慢地，花了一两个小时把谷子店都逛完了，也顺带吃了晚餐（在造梦场吃铁板烧，蛋包饭是真好吃，酸梅汤是真好喝，团购是真便宜），虽然没有看到自己想要的，但是似乎看到了学弟想要的（前段时间跟我说正在推缘之空），我就拍了一张&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://r2.halory.fun/gallery/ChongQing-ManZhan-2026/qiong.jpg&quot; alt=&quot;穹妹键盘垫&quot; /&gt;&lt;figcaption&gt;穹妹键盘垫&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;最后花了一个小时坐车回去，回去的路上我想着，我要逛一辈子的漫展，我要爱一辈子二次元，之前我对二次元的还停留在个人的感受中，漫展之后我才真正见识到强大而有力的集体热爱，以及他们几乎人人具备的大方、活力与自信这三种素质，亦吾之所往&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://r2.halory.fun/gallery/ChongQing-ManZhan-2026/exit.jpg&quot; alt=&quot;漫展出口&quot; /&gt;&lt;figcaption&gt;漫展出口&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title>论学长</title><link>https://shizuku.halory.fun/posts/lun-xue-chang/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/lun-xue-chang/</guid><description>学长是一个短期称谓，总有失去，无法拾起的一天</description><pubDate>Sun, 27 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;对于一个不太优秀的学生而言，学长是一个阶段性的称呼，一般是学弟学妹们的求助信号，他们知道你在某些方面有自己的经验，所以过来取取经。我虽然不太优秀，但是对于学弟学妹们的困惑，我是知无不言的，不太健谈的我却在此时说了一堆又一堆的话，并且投入了真心，我真心希望他们可以取得比我更好的成果。&lt;/p&gt;
&lt;p&gt;我现在已经毕业了，只有比我小一两届的个别同学有时还称呼我学长，但也是时间问题，像这种知道提问，知道向学长取经，知道自己主动去了解某一件事的同学，毕业去向一般都不会差，那几个称呼我为学长的同学也是，肯定拥有着一个让人憧憬着的，比我更甚的未来。也许毕业后再过个两三年，等我步入社会之后，就再没有人会称呼我为学长了。我已经帮不了他们的忙了。&lt;/p&gt;
&lt;p&gt;昨晚做梦，梦见我即将离开这个城市，正当我推着行李箱，准备去火车站的时候，突然一个曾多次向我提问，最终保研上岸的学妹问我要不要一起吃饭，我当时就去了。吃饭的时候聊得不多，我还没吃完呢，学妹的盘子已经空了，这时她突然站起身，向我鞠躬，庄重地对我道再见，随后走出去，没有驻留，没有回头，再无交集般地走着。我也紧接着走了出去，不过我走的是反方向，我是想驻留的，我是想回头的，我是希望以后还能有交集的，但我做不到，因为在我身上的“学长”称呼，于她而言，已经失去了其应有的特性。我已经没有资格再自称“学长”，而她也不会再有什么问题值得让我去回答。&lt;/p&gt;
&lt;p&gt;现实和梦境是有共同点的，说起来，我已经有快两年时间没有跟任何一个学长说过话了。&lt;/p&gt;</content:encoded></item><item><title>Zen浏览器自定义</title><link>https://shizuku.halory.fun/posts/zen-liu-lan-qi-zi-ding-yi/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/zen-liu-lan-qi-zi-ding-yi/</guid><description>浏览器默认样式太丑，通过CSS修改配置文件来优化样式</description><pubDate>Sun, 27 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;虽然也是自己一步一步从AI嘴里问出来的，但是好歹烧了token，也花了时间&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;启用自定义配置：首先访问&lt;code&gt;about:config&lt;/code&gt;，将&lt;code&gt;toolkit.legacyUserProfileCustomizations.stylesheets&lt;/code&gt;设置为&lt;code&gt;true&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;开启CSS调试：将&lt;code&gt;devtools.chrome.enabled&lt;/code&gt;设置为&lt;code&gt;true&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;创建自定义文件：访问&lt;code&gt;about:support&lt;/code&gt;，找到“打开配置文件夹的按钮”，新建&lt;code&gt;chrome&lt;/code&gt;文件夹，并在其中创建&lt;code&gt;userChrome.css&lt;/code&gt;和&lt;code&gt;userContent.css&lt;/code&gt;文件&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;浏览器自定义（非内容区）需要在&lt;code&gt;userChrome.css&lt;/code&gt;中进行配置，目前只做了如下：&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/* 修改所有标签页（包括非激活状态）的圆角 */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;.tabbrowser-tab&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;.tab-background&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;border-radius: &lt;/span&gt;&lt;span&gt;&lt;span&gt;12&lt;/span&gt;&lt;span&gt;px&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/* 为几乎所有元素设置字体，但排除标题栏按钮 */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;:not&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;.titlebar-buttonbox-container&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;font-family: &lt;/span&gt;&lt;span&gt;&quot;Noto Serif SC&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;sans-serif&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;#navigator-toolbox&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;--zen-compact-float&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;px&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;border: &lt;/span&gt;&lt;span&gt;none&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;14&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;background-color: &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;--zen-main-browser-background-toolbar&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;15&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;span&gt;展开&lt;/span&gt;&lt;span&gt;收起&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果要修改内容区的样式，比如&lt;code&gt;about:*&lt;/code&gt;、&lt;code&gt;https://*&lt;/code&gt;等需要通过地址栏访问的网站，就需要在&lt;code&gt;userContent.css&lt;/code&gt;中进行修改，不过其实一般只需要对浏览器内置的页面进行修改就可以了，而且主要是字体方面&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;/* 针对 about:* 页面设置字体 */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;@-moz-document&lt;/span&gt;&lt;span&gt; url-prefix(&quot;about:&quot;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;font-family: &lt;/span&gt;&lt;span&gt;&quot;Noto Serif SC&quot;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;sans-serif&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;!important&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;</content:encoded></item><item><title>给课题组做了个主页</title><link>https://shizuku.halory.fun/posts/gei-ke-ti-zu-zuo-liao-ge-zhu-ye/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/gei-ke-ti-zu-zuo-liao-ge-zhu-ye/</guid><description>专门为课题组做了一个主页，项目已经开源，欢迎大家使用</description><pubDate>Tue, 08 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;上周组会上，导师说要提高课题组的学术影响力，我想着有一个单独的课题组主页会不会好一些，于是不管三七二十一，这几天用空闲时间做了个&lt;/p&gt;
&lt;a href=&quot;https://github.com/Halory-Ito/next-teampage&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Halory-Ito&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;next-teampage&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Waiting for api.github.com...&lt;/div&gt;&lt;div&gt;&lt;div&gt;00K&lt;/div&gt;&lt;div&gt;0K&lt;/div&gt;&lt;div&gt;0K&lt;/div&gt;&lt;span&gt;Waiting...&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;
&lt;p&gt;由于主页数据不是经常变动的，因此就没有接数据库，做了个静态站点，文本数据都存在了&lt;code&gt;src/data&lt;/code&gt;下，图片的话放在了&lt;code&gt;public/images&lt;/code&gt;下，可以根据实际情况来&lt;/p&gt;
&lt;p&gt;网站做了国际化和响应式，用起来也简单，欢迎各位老师同学使用该项目&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://next-teampage.netlify.app/&quot; target=&quot;_blank&quot;&gt;在线演示&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;虽说导师没有采用就是了，理由是“这个就做得太过了，李校长没有这个”&lt;/p&gt;&lt;/blockquote&gt;</content:encoded></item><item><title>Event Loop</title><link>https://shizuku.halory.fun/posts/Event%20Loop/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/Event%20Loop/</guid><pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;简单来说，知道了Event Loop，其实就是知道了代码执行的优先级：先call stack，后mircotask quene，最后work quene&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;call stack中存放了同步函数，例如&lt;code&gt;console.log()&lt;/code&gt;、&lt;code&gt;setTimeout()&lt;/code&gt;等&lt;/li&gt;
&lt;li&gt;mircotask quene中存放了Promise中的&lt;code&gt;resolve()&lt;/code&gt;函数&lt;/li&gt;
&lt;li&gt;work quene中存放了各种回调函数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下面的代码为例：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;setTimeout&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;timeout&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;}, &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;resolve&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;then&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Promise&quot;&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Others&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;下面是代码的执行流程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;首先&lt;code&gt;setTimeout()&lt;/code&gt;函数会进入&lt;code&gt;call stack&lt;/code&gt;中&lt;/li&gt;
&lt;li&gt;由于&lt;code&gt;setTimeout()&lt;/code&gt;中存在回调函数，因此&lt;code&gt;() =&amp;gt; console.log(&apos;timeout&apos;)&lt;/code&gt;会进入&lt;code&gt;work quene&lt;/code&gt;中&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Promise.resolve()&lt;/code&gt;进入&lt;code&gt;call stack&lt;/code&gt;中，由于&lt;code&gt;resolve()&lt;/code&gt;中的函数中没有代码执行，因此会被弹出&lt;code&gt;call stack&lt;/code&gt;，紧接着&lt;code&gt;then()&lt;/code&gt;进入&lt;code&gt;call stack&lt;/code&gt;，由于&lt;code&gt;then()&lt;/code&gt;中存在&lt;code&gt;resolve&lt;/code&gt;的中间处理逻辑，因此&lt;code&gt;() =&amp;gt; console.log(&apos;Promise&apos;)&lt;/code&gt;会进入&lt;code&gt;microtask quene&lt;/code&gt;中&lt;/li&gt;
&lt;li&gt;&lt;code&gt;console.log(&apos;Others&apos;)&lt;/code&gt;是同步函数，进入&lt;code&gt;call stack&lt;/code&gt;，执行后出栈&lt;/li&gt;
&lt;li&gt;&lt;code&gt;call stack&lt;/code&gt;栈空后，先执行&lt;code&gt;microtask quene&lt;/code&gt;中的函数，里面只有&lt;code&gt;() =&amp;gt; console.log(&apos;Promise&apos;)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;最后执行&lt;code&gt;work quene&lt;/code&gt;中的函数，里面只有&lt;code&gt;() =&amp;gt; console.log(&apos;timeout&apos;)&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因此最后函数的打印顺序为：Others、Promise、timeout&lt;/p&gt;
&lt;p&gt;最初js的代码执行逻辑还是比较复杂的，但在引入&lt;code&gt;async&lt;/code&gt;和&lt;code&gt;await&lt;/code&gt;之后，就可以将所有的异步函数进行同步处理，确保了代码的执行顺序和编写顺序一致&lt;/p&gt;
&lt;p&gt;nodejs在组成上包含了v8引擎和libuv，其中v8引擎负责代码的执行，比如&lt;code&gt;call stack&lt;/code&gt;和&lt;code&gt;microtask quene&lt;/code&gt;中的代码，event loop也是由v8引擎提供的，而&lt;code&gt;libuv&lt;/code&gt;是一个多线程模型，用于处理&lt;code&gt;work quene&lt;/code&gt;中的回调函数和一些耗时耗力的操作&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;很多网站都推荐使用Chrome进行访问，其中的原因之一，就是v8引擎是浏览器内置的js引擎中性能最好的，而Chrome中使用的就是v8&lt;/p&gt;&lt;/blockquote&gt;</content:encoded></item><item><title>Web Workers</title><link>https://shizuku.halory.fun/posts/Web%20Workers/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/Web%20Workers/</guid><pubDate>Mon, 31 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;JavaScript是一种单线程编程语言，这便意味着不论你电脑配置有多高，JS只会用单核CPU来执行任务，其余cores基本都会处在闲置状态&lt;/p&gt;
&lt;p&gt;但是事件循环（event loop）解决这这种限制，事件循环最重要的一点就是非阻塞&lt;/p&gt;
&lt;p&gt;举一个实际的例子，假设页面中有两个按钮，其中一个用来进行IO密集的计算，另外一个用于修改页面的背景颜色。如果我们先点击“计算”的按钮，再点击“修改背景颜色”的话，会出现什么情况呢？只要计算量够大，就会出现等待很长一段时间之后，背景颜色才会被修改&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;计算&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;修改背景颜色&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;计算&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;p&gt;修改背景颜色&lt;/p&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这显然是很糟糕的，而Web Workers就可以把IO密集的计算任务交给一个新的线程执行，无需占用主进程，做法如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在主进程脚本中创建一个&lt;code&gt;worker&lt;/code&gt;对象&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 这里的 worker.js 中写了我们要完成的IO密集任务&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;worker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Worker&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;worker.js&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;通过绑定点击事件，来触发 worker 执行任务&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;totalButton&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;document&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;getElementById&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;total&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;totalButton&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;addEventListener&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;click&quot;&lt;/span&gt;&lt;span&gt;, () &lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;worker&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;postMessage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Hello worker&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;将IO密集任务写入 &lt;code&gt;worker.js&lt;/code&gt; 中&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;// 这里的 message.data 就是上面的 `Hello worker`&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;onmessage&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;4&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Worker has started working&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;5&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;total&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;6&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;lt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;10000000000&lt;/span&gt;&lt;span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;/span&gt;&lt;span&gt;++&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;7&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;total&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;8&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Worker has finished working&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;10&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;11&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// 计算完成后，将数据传递给主进程&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;12&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;postMessage&lt;/span&gt;&lt;span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;total&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;13&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;从 &lt;code&gt;worker&lt;/code&gt; 获取计算结果&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;worker&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;onmessage&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;console&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;log&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`The total is &lt;/span&gt;&lt;span&gt;${&lt;/span&gt;&lt;span&gt;message&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;3&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;因此总结一下 Web Worker 的使用场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;图片/视频处理、编解码&lt;/li&gt;
&lt;li&gt;大数据排序、解析（如 JSON 解析、CSV 处理）&lt;/li&gt;
&lt;li&gt;加密、压缩、Canvas 渲染&lt;/li&gt;
&lt;li&gt;防止复杂计算阻塞 UI 交互&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>There&apos;s no speed limit</title><link>https://shizuku.halory.fun/posts/There&apos;s%20no%20speed%20limit/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/There&apos;s%20no%20speed%20limit/</guid><description>the standard pace is for chumps. If you&apos;re more driven than most people, you can do way more than anyone expects. </description><pubDate>Mon, 24 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;&lt;p&gt;the &lt;a href=&quot;https://sive.rs/kimo&quot; target=&quot;_blank&quot;&gt;article&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Whether you’re a student, a teacher, or a parent, I think you’ll appreciate this story of how one teacher can completely and permanently change someone’s life in only a few lessons.&lt;/p&gt;
&lt;p&gt;I was seventeen and about to start my first year at Berklee College of Music.&lt;/p&gt;
&lt;p&gt;I called a local recording studio with a random question about music typesetting.&lt;/p&gt;
&lt;p&gt;When the studio owner heard I was going to Berklee, he said, “I graduated from Berklee and taught there, too. I’ll bet I can teach you two years of theory and arranging in only a few lessons. I suspect you can graduate in two years if you understand there’s no speed limit. Come by my studio at 9&amp;lt;00&amp;gt; tomorrow for your first lesson, if you’re interested. No charge.”&lt;/p&gt;
&lt;p&gt;Graduate college in two years? Awesome! I liked his style. That was Kimo Williams.&lt;/p&gt;
&lt;p&gt;I showed up at his studio at 8&amp;lt;40&amp;gt; the next morning, super excited, though I waited outside before ringing his bell at 8&amp;lt;59&amp;gt;.&lt;/p&gt;
&lt;p&gt;He opened the door. A tall man in a Hawaiian shirt and a big hat, with a square scar on his nose, a laid-back demeanor, and a huge smile, sizing me up, nodding.&lt;/p&gt;
&lt;p&gt;(Recently I heard him tell the story from his perspective. He said, “My doorbell rang at 8&amp;lt;59&amp;gt; one morning and I had no idea why. I run across kids all the time who say they want to be a great musician. I tell them I can help, and tell them to show up at my studio at 9&amp;lt;00&amp;gt; if they’re serious. Nobody ever does. It’s how I weed out the really serious ones from the kids who just talk. But there was Derek, ready to go.”)&lt;/p&gt;
&lt;p&gt;After a one-minute welcome, we were sitting at the piano, analyzing the sheet music for a jazz standard. He was quickly explaining the chords based on the diatonic scale — how the dissonance of the tri-tone in the 5-chord with the flat-7 is what makes it want to resolve to the 1. Within a minute, he started quizzing me.&lt;/p&gt;
&lt;p&gt;“If the 5-chord with the flat-7 has that tri-tone, then so does another flat-7 chord. Which one?”&lt;/p&gt;
&lt;p&gt;“Uh… the flat-2 chord?”&lt;/p&gt;
&lt;p&gt;“Right! So that’s a substitute chord. Any flat-7 chord can be substituted with the other flat-7 that shares the same tri-tone. So reharmonize all the chords you can in this chart. Go.”&lt;/p&gt;
&lt;p&gt;The pace was intense, and I loved it. Finally, someone was challenging me — keeping me in over my head — encouraging and expecting me to pull myself up quickly. I was learning so fast, it felt like the adrenaline rush you get while playing a video game. He tossed every fact at me and made me prove that I got it.&lt;/p&gt;
&lt;p&gt;In our three-hour lesson that morning, he taught me a full semester of Berklee’s harmony courses. In our next four lessons, he taught me the next four semesters of harmony and arranging classes.&lt;/p&gt;
&lt;p&gt;When I got to college and took my entrance exams, I tested out of those six semesters of requirements.&lt;/p&gt;
&lt;p&gt;Then, as Kimo suggested, I bought the course materials for other required classes and taught myself, doing the homework in my own time. Then I went to the department head and took the final exam, getting full credit for those courses.&lt;/p&gt;
&lt;p&gt;By doing this in addition to completing my full course load, I graduated college in two and a half years. I got my bachelor’s degree when I was twenty.&lt;/p&gt;
&lt;p&gt;Kimo’s high expectations set a new pace for me. He taught me that “the standard pace is for chumps” — that the system is designed so anyone can keep up. If you’re more driven than most people, you can do way more than anyone expects. And this principle applies to all of life, not just school.&lt;/p&gt;
&lt;p&gt;Before I met Kimo, I was just a kid who wanted to be a musician, doing it casually. Ever since our five lessons, I’ve had no speed limit. I owe every great thing that’s happened in my life to Kimo’s raised expectations. A random meeting and five music lessons showed me that I can do way more than the norm.&lt;/p&gt;
&lt;p&gt;Twenty years later, Berklee invited me to give the opening keynote speech to incoming first-year students. Go to sive.rs/berklee to see it. Kimo knows how much he means to me, and we’re friends to this day.&lt;/p&gt;</content:encoded></item><item><title>视觉小说入坑指南</title><link>https://shizuku.halory.fun/posts/shi-jue-xiao-shuo-ru-keng-zhi-nan/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/shi-jue-xiao-shuo-ru-keng-zhi-nan/</guid><pubDate>Thu, 20 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;section&gt;&lt;h1&gt;概述&lt;a href=&quot;#概述&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;视觉小说是很有沉浸感的一类游戏，如果你也没有朋友喜欢独处，挑一个时间点，在没有人打扰的地方，拉上窗帘，开启一盏暖灯，备好一杯奶茶或者果汁，戴着耳机，看着游戏剧情，欣赏着日系音乐、精彩的配音以及精美的游戏CG，沉溺其中，绝对是一种舒适的体验。&lt;/p&gt;&lt;p&gt;下面我主要介绍一下我平常游玩视觉小说用到的网站或者工具&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;找游戏&lt;a href=&quot;#找游戏&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;视觉小说那么多，到底要玩哪一款呢？对，我们需要一个数据库，目前最大的视觉小说数据库应当是&lt;a href=&quot;https://vndb.org&quot; target=&quot;_blank&quot;&gt;VNDB&lt;/a&gt;，这里提供了最全的视觉小说信息，甚至还有游戏评分、游玩时长等信息，很容易就能找到一款玩起来感觉还不错的游戏&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;vndb页面&quot; loading=&quot;lazy&quot; width=&quot;1904&quot; height=&quot;1064&quot; src=&quot;/_astro/image-20260820203302-t94ptln.D8smEG_A_h9luw.webp&quot; /&gt;&lt;figcaption&gt;vndb页面&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;如果没有电脑或者平板，访问网站不是太方便的，或者觉得网站页面不够简约的话，那么可以安装下面的VNDB第三方客户端&lt;/p&gt;&lt;a href=&quot;https://github.com/Halory-Ito/vnlite&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Halory-Ito&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;vnlite&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Waiting for api.github.com...&lt;/div&gt;&lt;div&gt;&lt;div&gt;00K&lt;/div&gt;&lt;div&gt;0K&lt;/div&gt;&lt;div&gt;0K&lt;/div&gt;&lt;span&gt;Waiting...&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;p&gt;也有一些中文的视觉小说资料网站，主要有：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cngal.org/&quot; target=&quot;_blank&quot;&gt;CnGal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ymgal.games/&quot; target=&quot;_blank&quot;&gt;月幕&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这两个网站除了提供基本的游戏信息之外，还有其他二次元伙计写的文章、杂谈，或许可以帮助更好地选择游戏&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;找资源&lt;a href=&quot;#找资源&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;穷人看过来，富婆少爷可以走开了&lt;/p&gt;&lt;p&gt;知道要玩什么游戏后，下一步就是获取游戏实体了，正常获取游戏一般都是在官网或者在主流的游戏平台购买，我也是支持购买正版的，只不过很多正版并没有提供本土语言，让我不得不去社区寻找翻译组制作的版本（汉化组是神）&lt;/p&gt;&lt;p&gt;我找游戏的渠道一般有如下四个：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.shinnku.com/&quot; target=&quot;_blank&quot;&gt;真红小站&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.touchgal.ink&quot; target=&quot;_blank&quot;&gt;TouchGal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sayafx.vip/&quot; target=&quot;_blank&quot;&gt;月谣&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.searchgal.top&quot; target=&quot;_blank&quot;&gt;聚合搜索&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果再找不到的话，那只能去寻求社区帮助、去网盘资源网站搜索了，或许还会有意想不到的收获&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;真实经历，我当初想找一个月姬R的任天堂游戏实体，但是找到的汉化版本不支持版本比较高的模拟器，楔子部分过完后就出现了画面撕裂的情况。于是我就去一些网盘资源网站，你猜怎么着，我直接找到了月姬R的官方中文版游戏实体，这样就支持最新的模拟器了&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;游戏工具&lt;a href=&quot;#游戏工具&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;下一步就是要玩游戏了，但只是双击exe文件就可以了吗？确实可以，不过我觉得可以再做一些游玩体验的优化&lt;/p&gt;&lt;section&gt;&lt;h2&gt;游戏管理&lt;a href=&quot;#游戏管理&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;如果游戏过多的话，那么整理起来也不方便，并且面对的如果是文件夹大军的话，也不好看，那么我非常建议在本地用一个专门的工具进行游戏管理，比较推荐的是vnweb&lt;/p&gt;&lt;a href=&quot;https://github.com/Halory-Ito/vnweb&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Halory-Ito&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;vnweb&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Waiting for api.github.com...&lt;/div&gt;&lt;div&gt;&lt;div&gt;00K&lt;/div&gt;&lt;div&gt;0K&lt;/div&gt;&lt;div&gt;0K&lt;/div&gt;&lt;span&gt;Waiting...&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;p&gt;vnweb支持的内容非常多，包括：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;游戏基本信息管理（支持从vndb、bangumi、steam、ymgal等平台获取数据）&lt;/li&gt;
&lt;li&gt;游戏PV和OST管理（支持从网易云添加游戏的OST、支持将视频链接或者B站链接和游戏进行绑定，即PV）&lt;/li&gt;
&lt;li&gt;游戏角色和台词管理（如果遇到印象深刻的对话或者句子，可以随时记录保存；人物信息也可以快速进行查阅）&lt;/li&gt;
&lt;li&gt;游戏攻略（可以随时标记游戏进度，支持从&lt;a href=&quot;https://www.yjgalgame.com/&quot; target=&quot;_blank&quot;&gt;悠久&lt;/a&gt;导入攻略，支持自定义攻略，还可以利用网站提供的提示词借助ai来快速生成游戏攻略）&lt;/li&gt;
&lt;li&gt;游玩统计（记录每一次游戏时长，根据记录信息生成年报、月报等统计内容）&lt;/li&gt;
&lt;li&gt;游戏扫描（可以自动将文件夹中的游戏扫描添加到系统中）&lt;/li&gt;
&lt;li&gt;游戏自动存档（每一次游戏结束后，都可以自动将游戏存档进行备份）&lt;/li&gt;
&lt;li&gt;自定义外观（包括字体、背景图片、蒙版模糊度和透明度、CSS样式、深浅模式等）&lt;/li&gt;
&lt;li&gt;命令行工具（日常玩游戏的话，可以直接打开命令行，输入&lt;code&gt;vnweb start&lt;/code&gt;就可以启动上一次的游戏了）&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以用起来吧！&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;vnweb页面截图&quot; loading=&quot;lazy&quot; width=&quot;1904&quot; height=&quot;1064&quot; src=&quot;/_astro/image-20260820211452-zca9zph.DFWewfIx_Z23crhD.webp&quot; /&gt;&lt;figcaption&gt;vnweb页面截图&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;游戏全屏和图像优化&lt;a href=&quot;#游戏全屏和图像优化&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;有些老游戏不支持全屏，或者全屏之后游戏的画质会很差，那么就可以使用Magpie，它是一个轻量级的窗口超分辨率工具，内置众多高效的算法和滤镜，仓库地址如下，具体使用可以参考文档或者去B站搜索配置教程&lt;/p&gt;&lt;a href=&quot;https://github.com/Blinue/Magpie&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Blinue&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;Magpie&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Waiting for api.github.com...&lt;/div&gt;&lt;div&gt;&lt;div&gt;00K&lt;/div&gt;&lt;div&gt;0K&lt;/div&gt;&lt;div&gt;0K&lt;/div&gt;&lt;span&gt;Waiting...&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>或许以后不会走开发了</title><link>https://shizuku.halory.fun/posts/huo-xu-yi-hou-bu-hui-zou-kai-fa-liao/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/huo-xu-yi-hou-bu-hui-zou-kai-fa-liao/</guid><pubDate>Mon, 17 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;开发对于我而言意味着什么呢？我最近开始思考这个问题，回想四年前我刚升大一的时候，那时候心里想着的其实是信安方面的东西，觉得当个黑客白客红客是很帅的，虽然过于感性，但是对开发却是一点想法都没有。&lt;/p&gt;
&lt;p&gt;第一次接触应该是计算机导论课上时，提到过&lt;code&gt;html&lt;/code&gt;，知道了有这么个东西，后来在图书馆开始了看书自学前端（只有一段时间，并且学得很慢）&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;有一个插曲，本来想着拿蹩脚的&lt;code&gt;html&lt;/code&gt;写一个简单的页面给一个故人，当作是生日祝福，可是当时我并不知道&lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt;标签有什么用，以为有没有都无所谓，并且在本地删了之后页面好像也是正常的，于是我就把删了&lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt;标签的&lt;code&gt;html&lt;/code&gt;页面用邮件发送给故人，故人说页面打不开，我以为是故人不知道用什么工具打开，我只是说用浏览器打开，但是自己并没有拿手机出来进行测试，事情就告一段落了，但是没过多久两人友好互删，我看着之前给发故人的&lt;code&gt;html&lt;/code&gt;文件，想再看看，就把文件下载到手机上，在浏览器上打开，结果内容全部乱码了。这是件遗憾的事，或许故人当初以为我在整蛊，却没有被传达我真正的心意。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;后来便是为了加入学校的工作室而学习开发，经过两三次筛选，通过了考核&lt;/p&gt;
&lt;p&gt;再后来，便是为打比赛而学习开发，跟几个同学组了队，比赛准备了将近五个月，我们也熟络了起来&lt;/p&gt;
&lt;p&gt;比赛期间，又加入了另外一个工作室，便又为了做学院的项目而学习开发，老实说，有点心累，多处的bug让我产生了自我怀疑&lt;/p&gt;
&lt;p&gt;再后来，得知自己有机会保研，便又为了保研而学习开发，目的是做一个全栈项目去打比赛，期间又重构了学院的项目，但是最终比赛结果很不满意，甚至比赛之后的那几个月我没有碰过开发&lt;/p&gt;
&lt;p&gt;再后来，为了找一份实习而学习开发，但是由于之前的时间里面我接触了很多技术，但是都不是很熟，并且现在走的是nextjs全栈，国内基本只有startup才会用这类技术栈，同时startup很看重学历背景，因此学了一段时间又放弃了&lt;/p&gt;
&lt;p&gt;再后来，为了完成毕业设计而学习开发，前期我花了比较多的时间去设计整个页面布局，以及功能，后来觉得进度太慢，便全部交给ai，我只负责审查，此时又没有学，也没有学习的热情（ai扼杀）&lt;/p&gt;
&lt;p&gt;时间来到了现在，我已经是一名准研究生，再不到一个月就要读研了，那么我还有什么理由学习开发呢？回想之前的经历，都是因为有学习的需要我才去学习开发的，在研究生阶段，一方面我并不是软件开发专业的，另一方面确实想要好好提升自己的学历，想要all in research&lt;/p&gt;
&lt;p&gt;如果问平常是否会用到开发呢？会的，尤其是给自己做一些简单管理软件的时候会用上，但是这是需求很低的情况，和企业开发的代码量和业务复杂度根本没法比，因此开发便留给自己自娱自乐，已经是玩具级别的东西了，不是我要走的正道。&lt;/p&gt;</content:encoded></item><item><title>《水仙》游玩感想</title><link>https://shizuku.halory.fun/posts/galgame/%E6%B0%B4%E4%BB%99/%E6%B0%B4%E4%BB%99%E6%B8%B8%E7%8E%A9%E6%84%9F%E6%83%B3/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/galgame/%E6%B0%B4%E4%BB%99/%E6%B0%B4%E4%BB%99%E6%B8%B8%E7%8E%A9%E6%84%9F%E6%83%B3/</guid><pubDate>Sat, 30 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;我差不多是2024年上半年才入坑的视觉小说，记得最早玩的是《饿殍》，只不过没通过（陈阿姨太夹了，很出戏），后来时隔了半年吧，又玩了《弹丸论破 1》，这是算是通过了。在2025年下半年，视觉小说才成为了我的主力，依次玩过了《素晴日》、《白2序章》、《弹丸论破2》和《魔法使之夜》。《樱之诗》在玩中，只是移动固态硬盘出了点问题（T^T），读不了游戏，这几天寄出去维修了&lt;/p&gt;
&lt;p&gt;这么看下来，我玩的这些视觉小说其实还算比较长的，平均得玩 30h 才能通过，想着在硬盘修好之前，应该是不适合另起一部长篇了，那正好换换胃口。于是我就在 VNDB 上找了一款时长比较短的游戏，不到 3h 的《水仙（narcissus）》&lt;/p&gt;
&lt;p&gt;这款游戏发行得比较早了，并且篇幅比较短，整个压缩包只有不到70MB（略惊）&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;《水仙》在发行之初就是免费的，现在Steam上也有，也是免费的，只不过没有中文；感觉以后会二刷，试试英版&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;两个主角都是病人（一个20岁，一个22岁），并且是得了绝症，由于当时的医疗技术还没有那么发达，他们就被安排到医院的7楼，7楼是专门为这些得了绝症的患者安排的，说好听点是等待医疗技术的发展，来为他们的治疗提供支持；说难听点就是等死。&lt;/p&gt;
&lt;p&gt;两个人的共同点，就是在最好的年纪里，遭遇了巨大变故，这点我多少能够共情。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;以痔疮为例，在得痔疮之前，我觉得拉粑粑是一件挺惬意的事，拉完后心情舒畅；突然有一天，你发现粑粑里有血了，并且每一次都有血流出，此时你就会非常不舒服。如果是发展成了肠道癌，在此之前所有的平淡风景就都变味了&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;如果明知自己将死了，你会如何选择？这是游戏中逃不开的命题。一般来说会有三个：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;待在医院&lt;/li&gt;
&lt;li&gt;待在家里&lt;/li&gt;
&lt;li&gt;去自己想去的地方，做自己想做的事&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;主人公最开始并不知道如何选择，因为自己既讨厌医院，又讨厌家里。讨厌医院自不必说，这种等死的解决手段谁会乐意；讨厌家里则是因为现在所有展示在面前的一切都是十分虚假的，家里人的各种行为多少带着点私心，或许是出于怜悯，或许是为了送终，又或许是想积阴德……&lt;/p&gt;
&lt;p&gt;下面的描述出自原文：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;爸爸出乎意料的来探望了我，他的脸上始终挂着悲伤的表情。不过他还谈到了我的保险之类的事情。唯独谈到了这个话题的时候，悲伤会从他的脸上一扫而去。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;这里用最平淡的文字，揭示了最露骨的现实：从某种程度上，自己其实已经被放弃了。也许正是这一点，主人公拿走了车钥匙，开车逃离了医院，逃离了城市，去了想去的地方。&lt;/p&gt;
&lt;p&gt;游戏虽然没有太多华丽的演出，篇幅也比较短，但是整体的色调都是悲伤的，剧本也好，音乐也好，我觉得都非常不错，足矣让最后的一句“さよなら”夺取眼泪。&lt;/p&gt;
&lt;p&gt;水仙除了是故事的线索之外，还涉及到了希腊神话：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Echo 是山林女神，以美貌著称，因赫拉的诅咒而失去了自主言语的能力，只能重复他人话语中的末尾部分。她痴恋美少年 Narcissus，但是除非 Narcissus 对 Echo 说出“我爱你”三个字，否则 Echo 就永远无法表达自己的心意，最终 Echo 藏身山洞，在孤独中化为永恒回音，而 Narcissus 则在死后，被众神变为水仙花。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;玩游戏我最喜欢收集台词了，下面就是女主在最后的自述：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;对事物充满憧憬，努力地追求，假如心愿真的能够实现，当然很好……但是，假如无法实现的话，又该如何呢？我根本没有那么坚强，能够微笑着安慰自己……我所能做的，只有从一开始就放弃一切，不去追求任何事物……我只能告诫自己，这是不可能的，只能够以冷漠的眼光来旁观着自己啊……我只能对自己说，如果那个时候试着去追求过，或许就会有不同的结果，只能将这些作为对自己最后的安慰啊，因为我从一开始就明白一切都是不可能实现的……&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;玩过之后，突然感受到了早期电子小说的魅力，接下来的这几个月应该为以这些为主吧&lt;/p&gt;</content:encoded></item><item><title>如何借助三分钟热度来学习</title><link>https://shizuku.halory.fun/posts/i_think/%E5%A6%82%E4%BD%95%E5%80%9F%E5%8A%A9%E4%B8%89%E5%88%86%E9%92%9F%E7%83%AD%E5%BA%A6%E6%9D%A5%E5%AD%A6%E4%B9%A0/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/i_think/%E5%A6%82%E4%BD%95%E5%80%9F%E5%8A%A9%E4%B8%89%E5%88%86%E9%92%9F%E7%83%AD%E5%BA%A6%E6%9D%A5%E5%AD%A6%E4%B9%A0/</guid><description>接触东西总是三分钟热度，热度过完之后就会陷入一种矛盾的状态？我是这么看待的</description><pubDate>Wed, 15 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;我是一个极容易三分钟热度的人，不管是什么东西，一旦遇到新鲜有意思的知识、技术，马上下意识：卧槽，这个好，我要学&lt;/p&gt;
&lt;p&gt;但是通常在三天之内，我就会逐渐对此感到枯燥，继而搁置一边，选择放弃&lt;/p&gt;
&lt;p&gt;从长期主义的角度，这算是一种废物行为，这样的人是做不成什么大事的，至少在程序员这块，很少有三天内就能做成大事的，可以说三分钟热度的人和行业严重的人才特质格格不入，那么要如何改变呢？&lt;/p&gt;
&lt;p&gt;不，我们并不需要改变，因为我们也能做到三分钟热度以外的事，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;恋爱，一旦真谈上了，肯定恨不得天天都跟对方聊天吧（不是恋爱脑也会）&lt;/li&gt;
&lt;li&gt;游戏，不论是哪种游戏类型，一旦喜欢上了这种剧情发展和竞技玩法，也很容易做到经常去玩吧&lt;/li&gt;
&lt;li&gt;开发，如果是那种交付型、并且需求明确的项目开发，也可以在规定周期内完成迭代&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;三分钟热度之所以是短期主义，很大层面上是因为这只是你&lt;strong&gt;个人方面的单向输入，并且缺少了正确的输出&lt;/strong&gt;，或者说是正反馈&lt;/p&gt;
&lt;p&gt;如果学东西的时候，还能说出“卧槽，这个牛”的时候，大概率还处在热度之内，这种情况我们是还能学下去的，因为在个人层面上也给予了正向反馈，从而让我们对这个东西的热情不减&lt;/p&gt;
&lt;p&gt;因此，保持三分钟热度的关键，在于适当的正反馈，那么在一个人的情况下，如何保持这种有效正反馈呢？我只能说很难，一般而言，技术是为产品服务的，想要从这个技术中得到正反馈，还不牵扯到第二个人，那么就只有做出一个自己感兴趣的产品，但是这种小而美产品的想法，并不是随时都有、随时都想得到的&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;其实找一位合适的女朋友很关键，在人际中，很少有人会对你的行为做出正向反馈（除非你比赛拿奖、收获了名利之类的），但是女朋友则不同，因为你会经常跟她报备，作为合适你的女朋友，她就会对你的任何报备都给予回复，而且基本都是正向的（“哇，宝宝好厉害”之类的），如果她还试图跟你说出用这个技术开发一些小产品的想法，那么你肯定学得更起劲了吧（电波）&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;或许技术博客是一个好办法，学到什么东西，做个笔记记录一下，整理完成后发到博客网站，从点赞、浏览量和评论中得到正向反馈，这也是很多人正在做的事&lt;/p&gt;
&lt;p&gt;如果你跟我一样，觉得自己写的技术博客是个垃圾，博客网站上已经有这么多垃圾了，再增加垃圾纯粹是占用公共资源，那么我的想法是：保持三分钟热度吧&lt;/p&gt;
&lt;p&gt;三分钟热度是一个极短暂的时期，但于此同时也是一个人学习效率最高的阶段，那么为何不充分利用三分钟热度的这种特质来快速学习某一个知识的，我就有过这种阶段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2 天学完 Go 基础语法，1 天学完 Gin 和 Gorm 使用&lt;/li&gt;
&lt;li&gt;1 天学完 HTML，2 天学完 CSS3，3天学完 JavaScript，1天学完 Nodejs跟基础的 Express.js，3天学完 Vue（暑假学的）&lt;/li&gt;
&lt;li&gt;7 天学完 React（而且还是在大三课比较多的时候）&lt;/li&gt;
&lt;li&gt;2 天学完 Java GUI 编程&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你跟我一样的话，那么我的建议是：想学就学，不学就玩，但要保持良好学习习惯&lt;/p&gt;</content:encoded></item><item><title>梦见娜娜米</title><link>https://shizuku.halory.fun/posts/i_think/%E6%A2%A6%E8%A7%81%E5%A8%9C%E5%A8%9C%E7%B1%B3/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/i_think/%E6%A2%A6%E8%A7%81%E5%A8%9C%E5%A8%9C%E7%B1%B3/</guid><description>那一天，我梦见我和七海千秋在……</description><pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;前几天做了一场梦，那时我梦见了&lt;strong&gt;七海千秋&lt;/strong&gt;（你别笑），&lt;strong&gt;超高校级的游戏高手&lt;/strong&gt;，要问这个梦有什么特别的吗？好像很平常也很一般，在梦中，当时下着雨，天昏沉沉，地点应该是在我老家的二楼，时间是下午，我和娜娜米并排坐在地上，打着游戏。问我具体在玩什么游戏嘛，这点梦里并没有交代，我似乎是以上帝视角在一边，看着自己和娜娜米在玩，两人之间似乎也没有对话，只是静静地玩着游戏（还挺符合人物设定），直到晚上，娜娜米的老爸开着&lt;strong&gt;豪车&lt;/strong&gt;把娜娜米从我老家接回去的时候，才跟我说话， &lt;strong&gt;“下次记得还要找我玩哦~”&lt;/strong&gt; ，娜娜米如此说道。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;必要介绍一下娜娜米在梦里的形象，简单来说，不是以超还原的Coser形象出现的，而是带着立绘的棱角，被合理地立体处理了，&lt;strong&gt;不是有机体&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;梦境大抵介绍完毕，很简单，并不复杂，也许是因此我才记得很深刻吧，又或许让我深刻的不是故事本身，而是我以上帝视角看到的当时氛围（亦或者七海千秋才是我的真命天女）。&lt;/p&gt;
&lt;p&gt;我不知道其他老二次元怎么样吧，我有一个习惯，一旦喜欢上一个角色，就会到处去搜索它的图片、表情包以及Coser。如果要问做这种事情有什么意义的话，我想有如下几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;纯欣赏&lt;/li&gt;
&lt;li&gt;让角色融入自己的生活&lt;/li&gt;
&lt;li&gt;爱屋及乌&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;依我看，&lt;strong&gt;让角色融入自己的生活&lt;/strong&gt;才是最终目的，在理想情况下，角色有自己的人格和意志，性格、音容完全符合原著，并且可以和我之间产生互动，可以给予陪伴，就像女朋友一样，不假借于物而独立存在。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;我们大部分二次元，其实都是很孤独的，这种孤独是精神上的，我们极度渴求有一个我们自认为完美的存在，来消解这种孤独&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;这点和梦里的娜娜米是相符的，也是任何一个Coser都无法达到的，虽然梦里没有什么对话，但我真的感觉很美好（想起了顾城写的《门前》）&lt;/p&gt;
&lt;p&gt;说了这些虚的，那么实的呢？正好前段时间在GTC 2026上，olaf机器人惊艳出场，极大程度上还原了原著，从这一点我进行了很多幻想，但打破幻想的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没钱&lt;/li&gt;
&lt;li&gt;娜娜米只能有一个，不能批量生产！！&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;p&gt;其实梦到娜娜米老爸开着豪车来的时候，心里就有落差了&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;想到这里，理想角色好像还有很重要的一点，那就是唯一性，这并不是说世上只能有一个，而是只会去对待一个人（很难接受梦里又多出个兄弟）&lt;/p&gt;
&lt;p&gt;那么现在有什么技术可以实现吗？没有&lt;/p&gt;
&lt;p&gt;（完）&lt;/p&gt;
&lt;p&gt;‍&lt;/p&gt;</content:encoded></item><item><title>关于保研了快半年我还啥都没怎么学这件事</title><link>https://shizuku.halory.fun/posts/i_think/%E5%85%B3%E4%BA%8E%E4%BF%9D%E7%A0%94%E4%BA%86%E5%BF%AB%E5%8D%8A%E5%B9%B4%E6%88%91%E4%BC%BC%E4%B9%8E%E8%BF%98%E5%95%A5%E9%83%BD%E6%B2%A1%E6%80%8E%E4%B9%88%E5%AD%A6%E8%BF%99%E4%BB%B6%E4%BA%8B/</link><guid isPermaLink="true">https://shizuku.halory.fun/posts/i_think/%E5%85%B3%E4%BA%8E%E4%BF%9D%E7%A0%94%E4%BA%86%E5%BF%AB%E5%8D%8A%E5%B9%B4%E6%88%91%E4%BC%BC%E4%B9%8E%E8%BF%98%E5%95%A5%E9%83%BD%E6%B2%A1%E6%80%8E%E4%B9%88%E5%AD%A6%E8%BF%99%E4%BB%B6%E4%BA%8B/</guid><pubDate>Fri, 20 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;去年九月份（2025-09），我已经保研了，并且在确定保研之前，已经找好了导师，被录取后便正式进组了。&lt;/p&gt;
&lt;p&gt;可课题组面试的过程其实并不顺利，导师虽然是对着简历来提问，并且我写在简历上的都是我的真实经历，没有半点作假，但我就是无法很清楚得讲出来，有大多数是很系统的问题，我也答得不太好，尤其是在算法这一块，让人非常失望，如果没有追加考核（根据要求实现几个后端接口，很简单的）的话，我可能就无缘课题组，甚至无缘这所学校了（因为当时对其他导师都没有太大的兴趣）&lt;/p&gt;
&lt;p&gt;归根结底，还是自己一路以来对学习技术这本身的看法有问题，可直到今天，我才有所意识，才想出一个比较符合现在的自己的一个路子&lt;/p&gt;
&lt;p&gt;刚开始的时候，我是以“泛”学为主，然后可以用新学的技术做出一个简单的系统，便达到我的要求了，以至于我把很多编程语言（C、Java、Python、Go、Kotlin、Dart、JS、TS、Rust）、Web框架（SpringBoot、SpringCloud、Flask、Django、FastAPI、Gin、Express、Vue、React、NextJS）、数据库（MySQL、Oracle、Redis、Postgres、MongoDB）、对应的 ORM 框架等都学习了一遍，学的同时也做好了相应的笔记&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;甚至达成了1天学完GO语法的佳绩&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;然后我做出来都是一些简陋的管理系统，没有什么太大的实用功能，只是为了所谓的熟悉开发而去练习&lt;/p&gt;
&lt;p&gt;直到我接触到了React和NextJS，以及它们庞大的开源生态，再回头看看我的管理系统，于是我打算欣然拥抱NextJS全栈，可是然后呢？我又用NextJS开发了一两个管理系统出来……不知道是因为审美疲劳，还是思路受限，亦或者是其他原因，总之，我对开发失去了兴趣，也对自己开发的产品失去了兴趣&lt;/p&gt;
&lt;p&gt;我陷入了沉思，自己似乎把计算机这条路走死了，由于学得泛而不精，只会使用简单的API，对于高级用法和底层一概不知；专业课也是如此，所有学习似乎都是为了拿分，而不是修为，没有深入，只有考前一搏。课题组的面试就是差点这么死掉的，问了我数据库系统、LCS、深度学习、Web框架的面试题等稍微深入的问题&lt;/p&gt;
&lt;p&gt;保研后的这几个月，我在学习NextJS、稍微学了点PyTorch，并帮着做了课题组的一个项目（我只参与了修bug跟个别功能的实现）&lt;/p&gt;
&lt;p&gt;先说说课题组的项目吧，是一个医疗方向的项目，看过代码，管理端部分是用ruoyi改的，部分功能是自己写的，但是页面都很丑，项目结构也有点乱，代码也没有怎么做拆分，花了很多时间了解这个项目是做什么的，然后就是功能是怎么实现的，跟着打断点调试来慢慢改bug。成果还行，用了一两天，靠调试跟另辟蹊径把一直没有解决的bug给fix掉了。后来又给我分配了一个任务，要去做一点调研，然后实现一个新功能，难度比较大，还需要会用Canvas，我就用AI写了下，半个小时搞定，跟那边交差的时候，问了我大致的原理，我就把AI生成的回答敷衍过去了，接着又说让我学习一个开源项目，后期做一个集成。这个开源项目我看了下，基本实现了课题组的功能，而且代码很规范，那么课题组这么长时间在干嘛？好像就是做了个管理系统……于是我对这个项目也失去了兴趣，本来是看重前后端开发才选的这个课题组，现在心里也后悔了起来——我好像并不喜欢这种开发&lt;/p&gt;
&lt;p&gt;PyTorch这边，有三段时期在学，第一次是大三学机器学习这门课的时候，第二次是导师叫学习搭深度神经网络的时候，第三次是最近这几天；前两次都失败了，没有学下去，一方面是因为数学基础不是太好，另一方面是学得好空，完全没有能解决我现在需求的实践教程，虽说是为了练习用，但这种基础的东西，我直接用AI生成不就行了？这样想着&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;有了AI加持之后，至少在开发岗之间转型似乎有了阻碍，只有坐得住冷板凳的人才能胜出&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;那么第三次呢？大概是知道了我学习的目的，学PyTorch不就是为了搞科研吗？只要能把论文中的实验复现，然后在已有的代码上改个模型，改个数据，如果有更好的准确率不就可以基于此发Paper了吗？就是这么简单的一件事，因此我也不再计较到底要学得有多深，会用就行，弄懂整个流程就行，可以慢慢来&lt;/p&gt;
&lt;p&gt;对我影响最深的大抵就是接触到了NextJS了吧，之前主用SpringBoot和React做开发，因为经常要给学校这边做点项目，国内技术栈，也不过如此了。但是NextJS，或者说nodejs生态，那真是新天地，每隔几天就有新的玩具可以尝鲜，如果是做技术自媒体的话，那肯定比其他框架容易很多了吧，并且高产出，不谈技术架构，纯纯写个演示的demo就好。可能是因为这个原因吧，我萌生了加入开源社区的想法，这一方面可以让我去深入理解前端技术栈，另一方面又能把学废的专业课重新捡起，如此下去，我肯定是一个合格的硕士吧。&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;现在好多的工具都用Rust重写了，我准备从这点入手，写自己的开源工具&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;保研了快半年，我似乎还啥都没怎么学，对此我很惭愧，我们这一行追求的是稳定性，此前的我基本是一天一个想法，而且即使有这个想法也没有这个行动&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;只有半个，那就是半途而废:)&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;规则（规范）很重要，这是我们这一行的共识，那么我的规则是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;有需求，优先使用现成的产品，不要自己开发&lt;/li&gt;
&lt;li&gt;日后的产品以工具链、插件、开发框架、CLI为主&lt;/li&gt;
&lt;li&gt;保持并热爱开源，要经常技术尝鲜&lt;/li&gt;
&lt;li&gt;不急于求成，坚持做二次元还是有必要的&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;&lt;p&gt;感谢在B站刷到了这个&lt;a href=&quot;https://space.bilibili.com/3546970173999844&quot; target=&quot;_blank&quot;&gt;小姐姐&lt;/a&gt;的视频，我了解了许多，也思考了许多&lt;/p&gt;&lt;/blockquote&gt;</content:encoded></item></channel></rss>