<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>liuyi</title><description>让世界再萌一点</description><link>https://blog.gucrin.top/</link><templateTheme>Firefly</templateTheme><templateThemeVersion>6.16.8</templateThemeVersion><templateThemeUrl>https://github.com/CuteLeaf/Firefly</templateThemeUrl><lastBuildDate>2026年10月12日 10:38:11</lastBuildDate><item><title>哔卡网申和申请进度查询攻略</title><link>https://blog.gucrin.top/posts/boc-2233msc/%E5%93%94%E5%8D%A1%E7%BD%91%E7%94%B3%E5%92%8C%E7%94%B3%E8%AF%B7%E8%BF%9B%E5%BA%A6%E6%9F%A5%E8%AF%A2%E6%94%BB%E7%95%A5/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/boc-2233msc/%E5%93%94%E5%8D%A1%E7%BD%91%E7%94%B3%E5%92%8C%E7%94%B3%E8%AF%B7%E8%BF%9B%E5%BA%A6%E6%9F%A5%E8%AF%A2%E6%94%BB%E7%95%A5/</guid><description>新的哔卡已经出现</description><pubDate>Mon, 12 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&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;🔗 网申预约入口：&lt;a href=&quot;https://open.boc.cn/bankcard/cardReserve/index.html#/?appId=8AFAF8C546EB63E9AE3202BC13DB46FC&amp;amp;prodId=P260802MYZGWK2025060515073600001&amp;amp;subProdId=JJKYY&amp;amp;funcId=cardIntroduce&amp;amp;chanId=bili_bzapp&quot; target=&quot;_blank&quot;&gt;“中国银行卡片预约页面”&lt;/a&gt;&lt;/p&gt;&lt;p&gt;🔍 进度查询入口： 进入 &lt;a href=&quot;https://open.boc.cn/bankcard/cardReserve/index.html#/?appId=8AFAF8C546EB63E9AE3202BC13DB46FC&amp;amp;prodId=P260802MYZGWK2025060515073600001&amp;amp;subProdId=JJKYY&amp;amp;funcId=cardIntroduce&amp;amp;chanId=bili_bzapp&quot; target=&quot;_blank&quot;&gt;预约页面&lt;/a&gt; 点击底部的 &lt;a href=&quot;https://open.boc.cn/bankcard/cardReserve/index.html#/?appId=8AFAF8C546EB63E9AE3202BC13DB46FC&amp;amp;prodId=P260802MYZGWK2025060515073600001&amp;amp;subProdId=JJKYY&amp;amp;funcId=cardIntroduce&amp;amp;chanId=bili_bzapp&quot; target=&quot;_blank&quot;&gt;“申请进度查询”&lt;/a&gt;&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;高级控制台代码和 JS 脚本&lt;a href=&quot;#高级控制台代码和-js-脚本&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;进入申请进度查询页面，输入你的信息查询，点击你要具体查询的卡，按 F12 打开浏览器控制台（Console），直接粘贴输入以下单行表达式，即可实时返回完整卡号与对应制卡状态：&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;document.getElementsByClassName(&quot;progress-result-wrap&quot;)[0].__vue__.$parent.recordInfo.cardNo.replace(/\s+/g, &apos;&apos;) + &quot; | &quot; + document.getElementsByClassName(&quot;progress-result-wrap&quot;)[0].__vue__.$parent.recordInfo.mkcrdProgreSts + &quot; (&quot; + ({&apos;00&apos;:&apos;待制卡&apos;,&apos;01&apos;:&apos;制卡中&apos;,&apos;03&apos;:&apos;寄送中&apos;,&apos;04&apos;:&apos;待领卡&apos;,&apos;06&apos;:&apos;已领卡&apos;,&apos;02&apos;:&apos;流程异常&apos;,&apos;05&apos;:&apos;流程异常&apos;,&apos;07&apos;:&apos;流程异常&apos;}[document.getElementsByClassName(&quot;progress-result-wrap&quot;)[0].__vue__.$parent.recordInfo.mkcrdProgreSts] || &quot;未知&quot;) + &quot;)&quot;&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;或者你也可以使用我使用 DeepSeek V4.1 Flash 制作的 JS 脚本：&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;// ==UserScript==&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;// @name         中银制卡进度提取&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;// @namespace    https://viayoo.com/&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;// @version      1.2.0&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;// @description  从 open.boc.cn 预约开户进度页读取 Vue recordInfo，输出卡号+状态，并自动枚举其余字段&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;// @author       lianlian&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;// @run-at       document-idle&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;// @noframes&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;// @match        https://open.boc.cn/bankcard/cardReserve/*&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;// @grant        none&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;// ==/UserScript==&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;/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;(function () {&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;&apos;use strict&apos;;&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;&lt;span&gt;if (window.top !== window.self) return;&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;/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;&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;/span&gt;&lt;/span&gt;&lt;span&gt;const CFG = {&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;&lt;/span&gt;&lt;span&gt;selector: &apos;.progress-result-wrap&apos;,&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;&lt;/span&gt;&lt;span&gt;autoCopy: false,                   // 首次拿到结果自动复制&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;&lt;/span&gt;&lt;span&gt;showPanel: true,                   // false = 只往 console 打&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;fields: &apos;auto&apos;,                    // &apos;none&apos; 只卡号+状态 | &apos;auto&apos; 自动附加全部字段 | &apos;json&apos; 附完整 JSON&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;includeEmpty: false,               // auto 模式是否输出空值字段&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;&lt;/span&gt;&lt;span&gt;maxValueLen: 80,                   // auto 模式单个值超长截断&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;&lt;/span&gt;&lt;span&gt;skipKeys: [&apos;cardNo&apos;, &apos;mkcrdProgreSts&apos;], // 已经单独输出了，不再重复&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;&lt;/span&gt;&lt;span&gt;recheckDelay: 400,&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;idleInterval: 1500,&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;giveUpAfterMs: 3 * 60 * 1000&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;/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;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const STS = {&lt;/span&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;&lt;/span&gt;&lt;span&gt;&apos;00&apos;: &apos;待制卡&apos;, &apos;01&apos;: &apos;制卡中&apos;, &apos;03&apos;: &apos;寄送中&apos;, &apos;04&apos;: &apos;待领卡&apos;,&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;&lt;/span&gt;&lt;span&gt;&apos;06&apos;: &apos;已领卡&apos;, &apos;02&apos;: &apos;流程异常&apos;, &apos;05&apos;: &apos;流程异常&apos;, &apos;07&apos;: &apos;流程异常&apos;&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;&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;/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;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const padCode = (c) =&amp;gt; {&lt;/span&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;&lt;/span&gt;&lt;span&gt;const s = String(c == null ? &apos;&apos; : c).trim();&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;&lt;/span&gt;&lt;span&gt;return /^\d$/.test(s) ? &apos;0&apos; + s : s;&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;&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;/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;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/* ============ 1. 找元素所属的 Vue 实例 ============ */&lt;/span&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;&lt;/span&gt;&lt;span&gt;function findVm(elm) {&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;&lt;/span&gt;&lt;span&gt;if (elm.__vue__) return { v2: elm.__vue__ };&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;&lt;/span&gt;&lt;span&gt;let p = elm.parentElement, d = 0;&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;&lt;/span&gt;&lt;span&gt;while (p &amp;amp;&amp;amp; d++ &amp;lt; 60) {&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;&lt;/span&gt;&lt;span&gt;if (p.__vue__) return { v2: p.__vue__ };&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;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;p = p.parentElement;&lt;/span&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;&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;if (elm.__vueParentComponent) return { v3: elm.__vueParentComponent };&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;p = elm.parentElement; d = 0;&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;/span&gt;&lt;/span&gt;&lt;span&gt;while (p &amp;amp;&amp;amp; d++ &amp;lt; 60) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;52&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (p.__vueParentComponent) return { v3: p.__vueParentComponent };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;53&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;p = p.parentElement;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;54&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;55&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return null;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;56&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;57&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;58&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/* ============ 2. 取 recordInfo ============ */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;59&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const pickInfo = (o) =&amp;gt; !o ? null :&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;60&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;o.recordInfo || (o.$data &amp;amp;&amp;amp; o.$data.recordInfo) || (o.$props &amp;amp;&amp;amp; o.$props.recordInfo) || null;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;61&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;62&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function infoFromV2(vm) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;63&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;let cur = vm;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;64&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;for (let i = 0; i &amp;lt; 8 &amp;amp;&amp;amp; cur; i++) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;65&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const info = pickInfo(cur);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;66&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (info &amp;amp;&amp;amp; info.cardNo) return info;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;67&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;cur = cur.$parent;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;68&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;69&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return searchV2(vm.$root, 0);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;70&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;71&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function searchV2(vm, d) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;72&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (!vm || d &amp;gt; 12) return null;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;73&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const info = pickInfo(vm);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;74&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (info &amp;amp;&amp;amp; info.cardNo) return info;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;75&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const kids = vm.$children || [];&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;76&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;for (let i = 0; i &amp;lt; kids.length; i++) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;77&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const r = searchV2(kids[i], d + 1);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;78&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (r) return r;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;79&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;80&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return null;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;81&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;82&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function infoFromV3(inst) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;83&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;let cur = inst;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;84&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;for (let i = 0; i &amp;lt; 8 &amp;amp;&amp;amp; cur; i++) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;85&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const info = pickInfo(cur.ctx || cur.proxy || cur);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;86&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (info &amp;amp;&amp;amp; info.cardNo) return info;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;87&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;cur = cur.parent;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;88&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;89&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return null;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;90&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;91&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;92&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&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;93&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function dumpKeys(info) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;94&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const set = new Set(Object.keys(info));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;95&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;// 兜底：有些字段是 getter / 挂在 $data 上，不在 Object.keys 里&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;96&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;try {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;97&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Object.getOwnPropertyNames(info).forEach((k) =&amp;gt; set.add(k));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;98&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (info.$data) Object.keys(info.$data).forEach((k) =&amp;gt; set.add(k));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;99&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} catch (e) { /* ignore */ }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;100&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;101&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return Array.from(set).filter((k) =&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;102&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;k !== &apos;__ob__&apos; &amp;amp;&amp;amp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;103&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;!/^(_|\$)/.test(k) &amp;amp;&amp;amp;                 // 过滤 __ob__ / _isVue / $data 等&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;104&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;CFG.skipKeys.indexOf(k) === -1 &amp;amp;&amp;amp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;105&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;typeof readVal(info, k) !== &apos;function&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;106&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;107&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;108&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;109&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function readVal(info, k) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;110&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;try { return info[k]; } catch (e) { return undefined; } // getter 抛错就跳过&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;111&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;112&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;113&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function fmtValue(v, maxLen) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;114&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;let s;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;115&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (v === null || v === undefined) s = &apos;&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;116&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;else if (typeof v === &apos;object&apos;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;117&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;try { s = JSON.stringify(v); } catch (e) { s = String(v); }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;118&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (s &amp;amp;&amp;amp; s.length &amp;gt; maxLen) s = s.slice(0, maxLen) + &apos;…&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;119&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} else s = String(v);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;120&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return s.replace(/\s+/g, &apos; &apos;).trim();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;121&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;122&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;123&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function autoPairs(info) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;124&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const out = [];&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;125&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;dumpKeys(info).forEach((k) =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;126&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const s = fmtValue(readVal(info, k), CFG.maxValueLen);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;127&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (!s &amp;amp;&amp;amp; !CFG.includeEmpty) return;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;128&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;out.push(k + &apos;:&apos; + (s || &apos;-&apos;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;129&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;130&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return out;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;131&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;132&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;133&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&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;134&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function formatOne(info) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;135&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const cardNo = String(info.cardNo).replace(/\s+/g, &apos;&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;136&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const raw = info.mkcrdProgreSts;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;137&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const text = STS[padCode(raw)] || &apos;未知&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;138&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;let line = cardNo + &apos; | &apos; + raw + &apos; (&apos; + text + &apos;)&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;139&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;140&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (CFG.fields === &apos;json&apos;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;141&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;let j;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;142&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;try { j = JSON.stringify(info); } catch (e) { j = String(info); }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;143&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return line + &apos; | &apos; + j;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;144&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;145&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (CFG.fields === &apos;auto&apos;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;146&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;autoPairs(info).forEach((p) =&amp;gt; { line += &apos; | &apos; + p; });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;147&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;148&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return line;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;149&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;150&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;151&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function scan() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;152&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const wraps = document.querySelectorAll(CFG.selector);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;153&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const lines = [], infos = [];&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;154&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;for (let i = 0; i &amp;lt; wraps.length; i++) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;155&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const vm = findVm(wraps[i]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;156&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (!vm) continue;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;157&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const info = vm.v2 ? infoFromV2(vm.v2) : infoFromV3(vm.v3);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;158&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (!info || !info.cardNo) continue;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;159&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lines.push(formatOne(info));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;160&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;infos.push(info);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;161&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;162&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;163&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const seen = {}, uLines = [], uInfos = [];&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;164&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lines.forEach((l, i) =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;165&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (seen[l]) return;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;166&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;seen[l] = 1;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;167&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;uLines.push(l);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;168&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;uInfos.push(infos[i]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;169&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;170&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return { lines: uLines, infos: uInfos };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;171&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;172&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;173&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/* ============ 5. 复制 ============ */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;174&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function fallbackCopy(text) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;175&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;try {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;176&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const ta = document.createElement(&apos;textarea&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;177&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ta.value = text;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;178&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ta.setAttribute(&apos;readonly&apos;, &apos;&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;179&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ta.style.cssText = &apos;position:fixed;top:0;left:0;width:1px;height:1px;opacity:0;&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;180&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;document.body.appendChild(ta);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;181&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ta.focus(); ta.select();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;182&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ta.setSelectionRange(0, text.length);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;183&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const ok = document.execCommand(&apos;copy&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;184&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ta.remove();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;185&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return ok;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;186&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} catch (e) { return false; }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;187&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;188&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function copy(text) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;189&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return new Promise((res) =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;190&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (navigator.clipboard &amp;amp;&amp;amp; window.isSecureContext) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;191&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;navigator.clipboard.writeText(text).then(() =&amp;gt; res(true), () =&amp;gt; res(fallbackCopy(text)));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;192&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} else res(fallbackCopy(text));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;193&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;194&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;195&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;196&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/* ============ 6. 悬浮面板 ============ */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;197&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;let panel, titleEl, bodyEl, tipEl, tipTimer, fieldBtn;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;198&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;199&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function mkBtn(label, onclick) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;200&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const b = document.createElement(&apos;button&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;201&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;b.textContent = label;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;202&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;b.style.cssText = &apos;all:unset;cursor:pointer;padding:2px 7px;border-radius:6px;&apos; +&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;203&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&apos;background:rgba(255,255,255,.12);font-size:12px;line-height:1.5&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;204&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const stop = (e) =&amp;gt; e.stopPropagation();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;205&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;b.addEventListener(&apos;mousedown&apos;, stop);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;206&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;b.addEventListener(&apos;touchstart&apos;, stop, { passive: true });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;207&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;b.addEventListener(&apos;click&apos;, (e) =&amp;gt; { e.stopPropagation(); onclick(b); });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;208&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return b;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;209&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;210&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;211&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function flash(msg, ok) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;212&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (!tipEl) return;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;213&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tipEl.textContent = msg;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;214&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tipEl.style.color = ok ? &apos;#8fd18f&apos; : &apos;#ff9a9a&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;215&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;clearTimeout(tipTimer);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;216&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tipTimer = setTimeout(() =&amp;gt; { tipEl.textContent = &apos;&apos;; }, 1500);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;217&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;218&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;219&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const FIELD_LABEL = { none: &apos;简&apos;, auto: &apos;全&apos;, json: &apos;JSON&apos; };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;220&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;221&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function setFieldMode(mode) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;222&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;CFG.fields = mode;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;223&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fieldBtn.textContent = &apos;字段:&apos; + FIELD_LABEL[mode];&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;224&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lastText = &apos;&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;225&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tick();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;226&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;227&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;228&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function ensurePanel() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;229&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (panel || !CFG.showPanel) return;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;230&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;panel = document.createElement(&apos;div&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;231&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;panel.style.cssText = &apos;position:fixed;left:8px;bottom:8px;z-index:2147483647;max-width:min(92vw,400px);&apos; +&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;232&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&apos;background:rgba(18,20,24,.93);color:#e9eaed;border:1px solid rgba(255,255,255,.16);border-radius:10px;&apos; +&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;233&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&apos;font:13px/1.55 -apple-system,BlinkMacSystemFont,&quot;PingFang SC&quot;,&quot;Microsoft YaHei&quot;,sans-serif;&apos; +&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;234&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&apos;box-shadow:0 8px 28px rgba(0,0,0,.4);overflow:hidden;&apos; +&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;235&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&apos;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;236&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;237&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const head = document.createElement(&apos;div&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;238&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;head.style.cssText = &apos;display:flex;align-items:center;gap:5px;padding:6px 8px;&apos; +&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;239&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&apos;background:rgba(255,255,255,.07);cursor:move;touch-action:none&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;240&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;241&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;titleEl = document.createElement(&apos;div&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;242&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;titleEl.textContent = &apos;制卡进度&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;243&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;titleEl.style.cssText = &apos;flex:1;min-width:0;font-weight:600;white-space:nowrap;overflow:hidden;&apos; +&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;244&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&apos;text-overflow:ellipsis;-webkit-user-select:none;user-select:none&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;245&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;246&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tipEl = document.createElement(&apos;span&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;247&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tipEl.style.cssText = &apos;font-size:11px;color:#8fd18f;white-space:nowrap&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;248&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;249&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fieldBtn = mkBtn(&apos;字段:&apos; + FIELD_LABEL[CFG.fields], () =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;250&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const order = [&apos;none&apos;, &apos;auto&apos;, &apos;json&apos;];&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;251&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;setFieldMode(order[(order.indexOf(CFG.fields) + 1) % order.length]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;252&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;253&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;254&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;head.appendChild(titleEl);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;255&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;head.appendChild(tipEl);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;256&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;head.appendChild(mkBtn(&apos;复制&apos;, () =&amp;gt; copyAll()));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;257&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;head.appendChild(fieldBtn);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;258&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;head.appendChild(mkBtn(&apos;↻&apos;, () =&amp;gt; { lastText = &apos;&apos;; tick(); }));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;259&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const collapse = mkBtn(&apos;－&apos;, () =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;260&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const hidden = bodyEl.style.display === &apos;none&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;261&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;bodyEl.style.display = hidden ? &apos;&apos; : &apos;none&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;262&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;collapse.textContent = hidden ? &apos;－&apos; : &apos;＋&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;263&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;264&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;head.appendChild(collapse);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;265&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;266&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;bodyEl = document.createElement(&apos;div&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;267&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;bodyEl.style.cssText = &apos;max-height:45vh;overflow:auto;-webkit-overflow-scrolling:touch&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;268&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;269&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;panel.appendChild(head);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;270&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;panel.appendChild(bodyEl);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;271&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;document.body.appendChild(panel);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;272&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;273&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;let dragging = false, sx = 0, sy = 0, ox = 0, oy = 0;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;274&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const onDown = (e) =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;275&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const t = e.touches ? e.touches[0] : e;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;276&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const r = panel.getBoundingClientRect();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;277&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;dragging = true; sx = t.clientX; sy = t.clientY; ox = r.left; oy = r.top;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;278&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;e.preventDefault();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;279&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;280&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const onMove = (e) =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;281&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (!dragging) return;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;282&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const t = e.touches ? e.touches[0] : e;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;283&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const x = Math.min(Math.max(0, ox + t.clientX - sx), innerWidth - panel.offsetWidth);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;284&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const y = Math.min(Math.max(0, oy + t.clientY - sy), innerHeight - panel.offsetHeight);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;285&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;panel.style.left = x + &apos;px&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;286&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;panel.style.top = y + &apos;px&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;287&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;panel.style.right = &apos;auto&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;288&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;panel.style.bottom = &apos;auto&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;289&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;e.preventDefault();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;290&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;291&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const onUp = () =&amp;gt; { dragging = false; };&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;292&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;head.addEventListener(&apos;mousedown&apos;, onDown);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;293&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;head.addEventListener(&apos;touchstart&apos;, onDown, { passive: false });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;294&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;document.addEventListener(&apos;mousemove&apos;, onMove);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;295&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;document.addEventListener(&apos;touchmove&apos;, onMove, { passive: false });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;296&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;document.addEventListener(&apos;mouseup&apos;, onUp);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;297&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;document.addEventListener(&apos;touchend&apos;, onUp);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;298&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;299&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;300&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function render(lines) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;301&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (!CFG.showPanel) return;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;302&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;ensurePanel();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;303&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;titleEl.textContent = &apos;制卡进度 · &apos; + lines.length + &apos; 条&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;304&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;bodyEl.innerHTML = &apos;&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;305&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lines.forEach((line) =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;306&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const row = document.createElement(&apos;div&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;307&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;row.textContent = line;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;308&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;row.style.cssText = &apos;padding:6px 9px;border-top:1px solid rgba(255,255,255,.09);&apos; +&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;309&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&apos;cursor:pointer;word-break:break-all;-webkit-user-select:text;user-select:text&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;310&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;row.addEventListener(&apos;click&apos;, () =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;311&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;copy(line).then((ok) =&amp;gt; flash(ok ? &apos;已复制&apos; : &apos;复制失败&apos;, ok));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;312&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;313&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;bodyEl.appendChild(row);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;314&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;315&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;316&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;317&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function copyAll() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;318&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (!lastText) return flash(&apos;暂无数据&apos;, false);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;319&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;copy(lastText).then((ok) =&amp;gt; flash(ok ? &apos;已复制全部&apos; : &apos;复制失败&apos;, ok));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;320&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;321&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;322&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;/* ============ 7. 调度 ============ */&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;323&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;let lastText = &apos;&apos;, found = false, autoCopied = false, queued = null, lastActive = Date.now(), loggedOnce = false;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;324&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;325&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function tick() {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;326&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const res = scan();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;327&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const lines = res.lines;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;328&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (lines.length) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;329&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;found = true;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;330&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const text = lines.join(&apos;\n&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;331&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (text !== lastText) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;332&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lastText = text;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;333&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.log(&apos;[制卡进度]\n&apos; + text);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;334&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (!loggedOnce) {                  // 顺手把原始对象也丢进控制台，方便核对字段&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;335&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;loggedOnce = true;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;336&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.log(&apos;[制卡进度] 原始 recordInfo:&apos;, res.infos);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;337&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;338&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;render(lines);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;339&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (CFG.autoCopy &amp;amp;&amp;amp; !autoCopied) { autoCopied = true; copy(text); }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;340&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;341&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;342&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;343&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;344&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;function schedule(delay) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;345&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (queued) return;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;346&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;queued = setTimeout(() =&amp;gt; { queued = null; tick(); }, delay == null ? CFG.recheckDelay : delay);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;347&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;348&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;349&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const mo = new MutationObserver(() =&amp;gt; schedule());&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;350&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;351&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const boot = () =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;352&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (!document.documentElement) return setTimeout(boot, 200);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;353&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;mo.observe(document.documentElement, { childList: true, subtree: true, characterData: true });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;354&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tick();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;355&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;356&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;boot();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;357&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;358&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;window.addEventListener(&apos;hashchange&apos;, () =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;359&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lastActive = Date.now();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;360&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lastText = &apos;&apos;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;361&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;found = false;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;362&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;schedule(600);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;363&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;364&lt;/div&gt;&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;365&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;const iv = setInterval(() =&amp;gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;366&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;if (Date.now() - lastActive &amp;gt; CFG.giveUpAfterMs) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;367&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;clearInterval(iv);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;368&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.log(&apos;[制卡进度] 长时间未找到 .progress-result-wrap，已停止轮询。&apos;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;369&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;return;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;370&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;371&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;tick();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;372&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}, CFG.idleInterval);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;373&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;</content:encoded></item><item><title>自建 Discord 来了！Fluxer 部署教程</title><link>https://blog.gucrin.top/posts/fluxer/%E8%87%AA%E5%BB%BA-discord-%E6%9D%A5%E4%BA%86fluxer-%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/fluxer/%E8%87%AA%E5%BB%BA-discord-%E6%9D%A5%E4%BA%86fluxer-%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/</guid><description>带你了解最新的语音软件</description><pubDate>Fri, 07 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;使用 Docker Compose 运行你自己的 Fluxer 实例。本指南将带你从一台全新的服务器开始，部署一个完整可用的自托管实例，包括：Web 应用、API 服务、网关服务（Gateway）、管理后台、媒体文件上传、搜索功能、存储系统、语音信令服务，所有服务都会通过一个公网域名统一访问。&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;该自托管技术栈由一个 Docker Compose 项目组成：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Caddy&lt;/strong&gt; 负责终止公共 HTTP(S) 流量，或接收来自 Cloudflare Tunnel 的流量。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;App proxy（应用代理）&lt;/strong&gt; 用于提供 Fluxer Web 客户端服务，并注入实例的引导数据（bootstrap data）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API&lt;/strong&gt; 处理账户、身份验证、社区、消息、文件上传、管理员 API 以及实例发现。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Admin dashboard（管理员仪表盘）&lt;/strong&gt; 是必需的，并在 &lt;code&gt;/admin&lt;/code&gt; 路径下提供服务。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gateway（网关）&lt;/strong&gt; 处理 WebSocket 会话、在线状态、事件调度、推送分发（push fanout）以及实时事件。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Messages service（消息服务）&lt;/strong&gt; 构建消息响应并提供历史消息服务。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Media proxy（媒体代理）&lt;/strong&gt; 处理附件上传的中继、媒体元数据、缩略图以及对象读取。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Static proxy（静态代理）&lt;/strong&gt; 在同一主机名下提供 Fluxer 字体、图标、表情符号、徽章、默认头像和语音客户端资源。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LiveKit&lt;/strong&gt; 处理语音与视频信令以及 WebRTC 媒体。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Postgres、Valkey、NATS、Meilisearch&lt;/strong&gt; 和 &lt;strong&gt;SeaweedFS&lt;/strong&gt; 提供数据、缓存、事件、搜索以及兼容 S3 的对象存储。
应用包由自托管的 app-proxy 镜像提供；共享静态资源由独立的 &lt;code&gt;static-proxy&lt;/code&gt; 容器提供。该技术栈不依赖 Fluxer 的公共静态资源主机。&lt;/li&gt;
&lt;/ul&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;ul&gt;
&lt;li&gt;一台可以运行 Docker Engine 的 Linux 服务器或虚拟机。&lt;/li&gt;
&lt;li&gt;Docker Engine 以及 Docker Compose 插件。&lt;/li&gt;
&lt;li&gt;实例的主机名，例如 &lt;code&gt;chat.example.com&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;需开放公共入站端口 &lt;code&gt;80/tcp&lt;/code&gt; 和 &lt;code&gt;443/tcp&lt;/code&gt;，或者使用 Cloudflare Tunnel 将主机名路由至 Caddy 容器。&lt;/li&gt;
&lt;li&gt;生产环境下的语音与视频媒体服务，需要开放通往 &lt;code&gt;7881/tcp&lt;/code&gt; 和 &lt;code&gt;7882/udp&lt;/code&gt; 的公共路径。&lt;/li&gt;
&lt;li&gt;至少 2 个 vCPU、4 GB 内存和 20 GB 磁盘空间。对于小型活跃社区，建议使用 4 个 vCPU 和 8 GB 及以上内存。&lt;/li&gt;
&lt;li&gt;该技术栈在空闲时占用几 GB 内存，启动阶段是负载最高的时刻，因为所有服务镜像会同时进行初始化。&lt;/li&gt;
&lt;/ul&gt;&lt;section&gt;&lt;h2&gt;步骤 1：安装 Docker&lt;a href=&quot;#步骤-1安装-docker&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;根据适用于你 Linux 发行版的 Docker 官方指南安装 Docker Engine：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.docker.com/engine/install/&quot; target=&quot;_blank&quot;&gt;安装 Docker Engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.docker.com/compose/install/linux/&quot; target=&quot;_blank&quot;&gt;安装 Compose 插件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.docker.com/engine/install/linux-postinstall/&quot; target=&quot;_blank&quot;&gt;Linux 安装后续步骤&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;确认所安装的 Docker 版本：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--version&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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;version&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;请使用 Docker Engine 24 或更高版本以及 Compose v2 插件。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;步骤 2：下载技术栈&lt;a href=&quot;#步骤-2下载技术栈&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;创建一个工作目录并下载技术栈文件：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;mkdir&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fluxer&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;cd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fluxer&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;/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;base&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;https://raw.githubusercontent.com/fluxerapp/fluxer/main/deploy/self-hosting&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;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-fsSLO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$base&lt;/span&gt;&lt;span&gt;/docker-compose.yml&quot;&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;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-fsSLO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$base&lt;/span&gt;&lt;span&gt;/Caddyfile&quot;&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;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-fsSLO&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$base&lt;/span&gt;&lt;span&gt;/livekit.yaml&quot;&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;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-fsSL&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$base&lt;/span&gt;&lt;span&gt;/.env.example&quot;&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;.env&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;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;Caddyfile&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;docker-compose.yml&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;livekit.yaml&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;.env&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;步骤 3：配置 .env&lt;a href=&quot;#步骤-3配置-env&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;在 &lt;code&gt;.env&lt;/code&gt; 文件顶部设置公共主机名。
对于由 Caddy 直接获取证书的普通公共服务器：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;FLUXER_DOMAIN&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;chat.example.com&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;FLUXER_PUBLIC_SCHEME&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;https&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;FLUXER_PUBLIC_PORT&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;443&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;FLUXER_CADDY_SITE_ADDRESS&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;chat.example.com&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;FLUXER_VAPID_EMAIL&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;admin@example.com&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;对于由 Cloudflare 终止 HTTPS 并将 HTTP 转发至 Caddy 的 Cloudflare Tunnel 配置：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;FLUXER_DOMAIN&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;chat.example.com&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;FLUXER_PUBLIC_SCHEME&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;https&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;FLUXER_PUBLIC_PORT&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;443&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;FLUXER_CADDY_SITE_ADDRESS&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;:80&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;FLUXER_VAPID_EMAIL&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;admin@example.com&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;FLUXER_PUBLIC_SCHEME&lt;/code&gt; 和 &lt;code&gt;FLUXER_PUBLIC_PORT&lt;/code&gt; 描述用户在浏览器中看到的协议与端口。&lt;code&gt;FLUXER_CADDY_SITE_ADDRESS&lt;/code&gt; 描述 Caddy 在技术栈内部监听的地址。&lt;/p&gt;&lt;p&gt;生成所需的密钥：&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;for&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;MEILI_MASTER_KEY&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FLUXER_S3_SECRET_KEY&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;FLUXER_SUDO_MODE_SECRET&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FLUXER_CONNECTION_INITIATION_SECRET&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;FLUXER_GATEWAY_RPC_AUTH_TOKEN&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FLUXER_MEDIA_PROXY_SECRET_KEY&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;FLUXER_ADMIN_SECRET_KEY_BASE&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;FLUXER_ADMIN_OAUTH_CLIENT_SECRET&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;LIVEKIT_API_SECRET&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;do&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;sed&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;&quot;s|^&lt;/span&gt;&lt;span&gt;$key&lt;/span&gt;&lt;span&gt;=.*|&lt;/span&gt;&lt;span&gt;$key&lt;/span&gt;&lt;span&gt;=$(&lt;/span&gt;&lt;span&gt;openssl&lt;/span&gt;&lt;span&gt; rand &lt;/span&gt;&lt;span&gt;-hex&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt;)|&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;.env&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;done&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;/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;sed&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;&quot;s|^FLUXER_MEDIA_PROXY_UPLOAD_RELAY_SECRET_BASE64=.*|FLUXER_MEDIA_PROXY_UPLOAD_RELAY_SECRET_BASE64=$(&lt;/span&gt;&lt;span&gt;openssl&lt;/span&gt;&lt;span&gt; rand &lt;/span&gt;&lt;span&gt;-base64&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt;)|&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;.env&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;VAPID&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;/span&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;node:24-alpine&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;npx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--yes&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;web-push&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;generate-vapid-keys&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--json&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;pub&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;/span&gt;&lt;span&gt;printf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;%s&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$VAPID&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;grep&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;&apos;&quot;publicKey&quot;:&quot;[^&quot;]*&quot;&apos;&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;cut&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-d&lt;/span&gt;&lt;span&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f4&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;priv&lt;/span&gt;&lt;span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;/span&gt;&lt;span&gt;printf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;%s&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$VAPID&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;grep&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;&apos;&quot;privateKey&quot;:&quot;[^&quot;]*&quot;&apos;&lt;/span&gt;&lt;span&gt; | &lt;/span&gt;&lt;span&gt;cut&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-d&lt;/span&gt;&lt;span&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f4&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;sed&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;&quot;s|^FLUXER_VAPID_PUBLIC_KEY=.*|FLUXER_VAPID_PUBLIC_KEY=&lt;/span&gt;&lt;span&gt;$pub&lt;/span&gt;&lt;span&gt;|&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;.env&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;sed&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;&quot;s|^FLUXER_VAPID_PRIVATE_KEY=.*|FLUXER_VAPID_PRIVATE_KEY=&lt;/span&gt;&lt;span&gt;$priv&lt;/span&gt;&lt;span&gt;|&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;.env&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;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;LIVEKIT_API_KEY=fluxer&lt;/code&gt;；密钥为 &lt;code&gt;LIVEKIT_API_SECRET&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FLUXER_S3_ACCESS_KEY=fluxer&lt;/code&gt;；密钥为 &lt;code&gt;FLUXER_S3_SECRET_KEY&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;电子邮件功能初始状态为禁用。后续可通过 &lt;code&gt;.env&lt;/code&gt; 和管理员仪表盘启用 SMTP。&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;保持 &lt;code&gt;.env&lt;/code&gt; 的私密性&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;code&gt;​.env&lt;/code&gt; 包含该实例的所有密钥。请勿将其提交到代码库、粘贴到技术支持工单中或放入截图内。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;步骤 4：发布主机名&lt;a href=&quot;#步骤-4发布主机名&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;为主机名创建 DNS 记录：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;从 &lt;code&gt;chat.example.com&lt;/code&gt; 指向服务器 IPv4 地址的 &lt;code&gt;A&lt;/code&gt; 记录。&lt;/li&gt;
&lt;li&gt;（可选）从 &lt;code&gt;chat.example.com&lt;/code&gt; 指向服务器 IPv6 地址的 &lt;code&gt;AAAA&lt;/code&gt; 记录。
保持 &lt;code&gt;FLUXER_CADDY_SITE_ADDRESS=chat.example.com&lt;/code&gt;。当端口 &lt;code&gt;80/tcp&lt;/code&gt; 和 &lt;code&gt;443/tcp&lt;/code&gt; 可以访问服务器时，Caddy 将自动申请并续订证书。&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;步骤 5：开放防火墙&lt;a href=&quot;#步骤-5开放防火墙&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;如果你使用的是直接暴露在公网上的服务器，请允许以下入站流量：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;22/tcp&lt;/code&gt; 或你的 SSH 端口。&lt;/li&gt;
&lt;li&gt;用于 Caddy 的 &lt;code&gt;80/tcp&lt;/code&gt; 和 &lt;code&gt;443/tcp&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;用于 LiveKit 媒体的 &lt;code&gt;7881/tcp&lt;/code&gt; 和 &lt;code&gt;7882/udp&lt;/code&gt;。
如果你对 Web 流量使用了 Cloudflare Tunnel，可以在云服务商的防火墙处拦截入站的 &lt;code&gt;80/tcp&lt;/code&gt; 和 &lt;code&gt;443/tcp&lt;/code&gt;。同时保持 LiveKit 媒体端口关闭，除非你意图开放语音/视频媒体或正在使用 TURN 服务器。&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;优先使用云服务商防火墙&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;Docker 发布的端口可能会绕过 UFW 等主机防火墙，因为 Docker 会安装自己的数据包过滤规则。请优先使用云服务商的防火墙或安全组来制定面向互联网的安全策略。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;步骤 6：启动技术栈&lt;a href=&quot;#步骤-6启动技术栈&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;启动 Fluxer：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;up&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-d&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;如果你使用了上述的 Cloudflare 覆盖配置，请同时启动这两个文件：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;docker-compose.yml&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cloudflared.compose.yml&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;up&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-d&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;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ps&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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;logs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;api&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;seaweedfs-init&lt;/code&gt; 在创建对象存储桶后会退出，这是正常现象。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;步骤 7：验证实例&lt;a href=&quot;#步骤-7验证实例&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;在 Shell 中设置你的域名：&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;export FLUXER_DOMAIN=chat.example.com&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;检查每一个公共 HTTP 入口点：&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;for path in /_health /api/_health /gateway/_health /media/_health /admin/_health; do&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;curl -fsS -o /tmp/fluxer-check -w &quot;$path %{http_code}\n&quot; &quot;https://$FLUXER_DOMAIN$path&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;done&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;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;/_health 200&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;/api/_health 200&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;/gateway/_health 200&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;/media/_health 200&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;/admin/_health 200&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;检查实例发现（instance discovery）：&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;curl -fsS &quot;https://$FLUXER_DOMAIN/api/.well-known/fluxer&quot; | jq &apos;.features.self_hosted, .endpoints.admin, .endpoints.gateway, .endpoints.media, .endpoints.static_cdn&apos;&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;true&lt;/code&gt;、以 &lt;code&gt;/admin&lt;/code&gt; 结尾的管理员 URL、以 &lt;code&gt;/gateway&lt;/code&gt; 结尾的网关 URL、以 &lt;code&gt;/media&lt;/code&gt; 结尾的媒体 URL，以及与实例源（origin）相同的静态资源 URL。
检查 Web 应用、管理员登录页面、应用包以及静态资源容器：&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;curl -fsSI &quot;https://$FLUXER_DOMAIN&quot; | sed -n &apos;1,8p&apos;&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;curl -fsSI &quot;https://$FLUXER_DOMAIN/admin/login&quot; | sed -n &apos;1,8p&apos;&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;/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;asset=$(curl -fsS &quot;https://$FLUXER_DOMAIN&quot; | grep -o &apos;src=&quot;[^&quot;]*/assets/[^&quot;]*&quot;&apos; | head -n1 | cut -d&apos;&quot;&apos; -f2)&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;case &quot;$asset&quot; in&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;http*) curl -fsSI &quot;$asset&quot; | sed -n &apos;1,8p&apos; ;;&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;/*) curl -fsSI &quot;https://$FLUXER_DOMAIN$asset&quot; | sed -n &apos;1,8p&apos; ;;&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;esac&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;/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;curl -fsSI &quot;https://$FLUXER_DOMAIN/fonts/ibm-plex.css?v=3&quot; | sed -n &apos;1,8p&apos;&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;curl -fsSI &quot;https://$FLUXER_DOMAIN/web/favicon-32x32.png&quot; | sed -n &apos;1,8p&apos;&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;如果你使用了 Cloudflare Tunnel 并遇到了 HTTP 530 错误，这说明 Tunnel 连接器当前未建立连接，或者公共主机名路由指向了错误的服务。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h2&gt;步骤 8：创建所有者账户&lt;a href=&quot;#步骤-8创建所有者账户&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;打开 Web 应用：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;https://chat.example.com&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;注册第一个账户。在自托管实例上，第一个被接受注册的账户将获得通配符管理员权限（wildcard admin access）。使用该账户进行首次管理员登录：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;https://chat.example.com/admin&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;/li&gt;
&lt;li&gt;注册模式：开放、审核或关闭。&lt;/li&gt;
&lt;li&gt;电子邮件发送。&lt;/li&gt;
&lt;li&gt;验证码策略（如果你开放了公共注册）。&lt;/li&gt;
&lt;li&gt;单一社区模式（如果你希望使用一个默认社区，而非由用户创建多个社区）。&lt;/li&gt;
&lt;li&gt;语音区域与 LiveKit 可达性（如果你启用了语音功能）。&lt;/li&gt;
&lt;/ul&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;电子邮件默认处于禁用状态。要启用 SMTP，请在 &lt;code&gt;.env&lt;/code&gt; 中设置以下变量，并重启 &lt;code&gt;api&lt;/code&gt;、&lt;code&gt;worker&lt;/code&gt; 和 &lt;code&gt;admin&lt;/code&gt; 服务：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;FLUXER_EMAIL_ENABLED&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;true&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;FLUXER_EMAIL_PROVIDER&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;smtp&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;FLUXER_EMAIL_FROM_EMAIL&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;noreply@example.com&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;FLUXER_EMAIL_FROM_NAME&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;Fluxer&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;FLUXER_EMAIL_SMTP_HOST&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;smtp.example.com&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;FLUXER_EMAIL_SMTP_PORT&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;587&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;FLUXER_EMAIL_SMTP_USERNAME&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;example&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;FLUXER_EMAIL_SMTP_PASSWORD&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;example-secret&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;FLUXER_EMAIL_SMTP_SECURE&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;true&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;/admin/instance-config&lt;/code&gt; 页面测试 SMTP 配置。&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;Fluxer 使用 LiveKit 处理语音和视频。Caddy 将 /livekit 路由至 LiveKit 的 HTTP/WebSocket 信令端口，但浏览器的媒体流通过 WebRTC 传输：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;7882/udp&lt;/code&gt; 是正常的媒体路径。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;7881/tcp&lt;/code&gt; 是 TCP 回退路径。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;7880/tcp&lt;/code&gt; 保持私有，位于 Caddy 后端用于信令传输。
在开放了 &lt;code&gt;7881/tc&lt;/code&gt; 和 &lt;code&gt;7882/udp&lt;/code&gt; 的 VPS 上，LiveKit 通常可以自动检测公网 IP。在 NAT、Cloudflare Tunnel 或受限网络环境下，请添加 TURN 服务器并为其配置 LiveKit。&lt;/li&gt;
&lt;/ul&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;在升级前和定期计划中备份以下项目：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.env&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;postgres-data&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;seaweedfs-data&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如需进行冷备份：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;stop&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;api&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;gateway&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;admin&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app-proxy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;media-proxy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;static-proxy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;livekit&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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fluxer_postgres-data:/data&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$PWD&lt;/span&gt;&lt;span&gt;/backups:/backup&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;alpine&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tar&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;czf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/backup/postgres-data.tgz&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-C&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;/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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fluxer_seaweedfs-data:/data&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$PWD&lt;/span&gt;&lt;span&gt;/backups:/backup&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;alpine&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tar&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;czf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/backup/seaweedfs-data.tgz&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-C&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;/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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;up&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-d&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;对于生产环境，优先使用 Postgres 原生转储（dump）加上对象存储备份，这样无需停止实例运行。&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;默认的镜像标签为 &lt;code&gt;v1&lt;/code&gt;，它会跟踪最新的兼容版本：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pull&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;docker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;compose&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;up&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-d&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;fluxer-static&lt;/code&gt; 镜像属于默认技术栈的一部分，因此静态资源的更新会通过相同的拉取和重启流程同步完成。
要锁定特定版本，请将 &lt;code&gt;.env&lt;/code&gt; 中的 &lt;code&gt;FLUXER_IMAGE_TAG&lt;/code&gt; 设置为你希望使用的版本标签，然后执行拉取并重启。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>努力调适就业心理，充分做好就业准备</title><link>https://blog.gucrin.top/posts/classwork/%E5%8A%AA%E5%8A%9B%E8%B0%83%E9%80%82%E5%B0%B1%E4%B8%9A%E5%BF%83%E7%90%86%E5%85%85%E5%88%86%E5%81%9A%E5%A5%BD%E5%B0%B1%E4%B8%9A%E5%87%86%E5%A4%87/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/classwork/%E5%8A%AA%E5%8A%9B%E8%B0%83%E9%80%82%E5%B0%B1%E4%B8%9A%E5%BF%83%E7%90%86%E5%85%85%E5%88%86%E5%81%9A%E5%A5%BD%E5%B0%B1%E4%B8%9A%E5%87%86%E5%A4%87/</guid><description>非毕业班的《就业指导》期末考核是每位学生提交一篇 2000 字左右的手写论文...</description><pubDate>Thu, 11 Jun 2026 00:00:00 GMT</pubDate><content:encoded>本文已加密保护，请访问网站查看。</content:encoded></item><item><title>去除 获取打开此&apos;ms-gamebar&apos;链接的应用 的弹窗</title><link>https://blog.gucrin.top/posts/tanchaung/no/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/tanchaung/no/</guid><description>这个好烦啊</description><pubDate>Sun, 19 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&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;如果你删过了系统自带的原生xbox组件，那你很大概率见过这个弹窗&lt;br /&gt;
为什么会出现这个弹窗？&lt;br /&gt;
我受够了 Win11 自带的 Xbox 组件。它的本意是好的，在接入手柄的时候，它会在后台默默启动，然后你可以使用手柄上的按键快捷截图。但有些时候，我们需要安静的游戏时间，或者要顾及电脑性能，所以决定删掉 Xbox 组件。&lt;br /&gt;
这就是噩梦的开端。你一定会发现，每次接入 Xbox 手柄时，系统都会弹出一个弹窗，进程名叫 OpenWith.exe。它的功能就是弹出“你要如何打开这个文件 / 选取应用”的对话框。&lt;br /&gt;
问题不是这个进程本身带来的，它只是 Windows 自带的兜底机制。背后的原因就是你删掉的 Xbox 组件：底层硬件服务在手柄接入时，依然试图在后台默默通过协议唤醒组件；因为它找不到被删除的软件，无法处理这个协议，所以弹窗出现了。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;极简 Debug 过程&lt;a href=&quot;#极简-debug-过程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;为了找出具体是哪条协议在作祟，常规的系统事件查看器（Event Viewer）是无效的，因为在系统底层逻辑里，唤醒操作本身没有报错，只是应用层没有响应。&lt;br /&gt;
通过使用 Process Monitor (Procmon) 抓取手柄接入瞬间的底层日志，得出了以下结论：&lt;br /&gt;
手柄接入时，svchost.exe (即插即用服务) 会向 Explorer.exe 发出指令，疯狂查询当前用户注册表下的 HKCU\Software\Classes\ms-gamebar 协议。很多人（包括我）最初的直觉是进注册表把 ms-gamebar 彻底删掉。但这是一个陷阱——你删得越干净，系统越是找不到处理程序，就越会触发防呆机制，强制弹出 OpenWith.exe 让你手动选应用。&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;既然系统的底层逻辑是“必须找到一个程序来处理这个协议”，堵不如疏，我们直接给它造一个伪装的空协议。
将系统的呼叫重定向到 %SystemRoot%\System32\systray.exe。这是一个极其小巧的 Windows 古董内置组件，不带参数运行时，它会瞬间静默退出，不会有任何界面和后台残留。系统以为任务完成了，弹窗也就彻底消失了。&lt;br /&gt;
新建一个文本文档，将以下代码复制进去，保存并重命名为 FakeGameBar.bat。直接双击运行一次，即可永久解决。&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;@&lt;/span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;off&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;title&lt;/span&gt;&lt;span&gt; Final Fix &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; Gamepad Popup - Black Hole Protocol&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;color&lt;/span&gt;&lt;span&gt; 0A&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;echo&lt;/span&gt;&lt;span&gt; Injecting fake protocol handler...&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;:: Create a black hole for ms-gamebar protocol&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;reg&lt;/span&gt;&lt;span&gt; add &lt;/span&gt;&lt;span&gt;&quot;HKCU\Software\Classes\ms-gamebar&quot;&lt;/span&gt;&lt;span&gt; /f /ve /d &lt;/span&gt;&lt;span&gt;&quot;URL:ms-gamebar&quot;&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt;nul&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;reg&lt;/span&gt;&lt;span&gt; add &lt;/span&gt;&lt;span&gt;&quot;HKCU\Software\Classes\ms-gamebar&quot;&lt;/span&gt;&lt;span&gt; /f /v &lt;/span&gt;&lt;span&gt;&quot;URL Protocol&quot;&lt;/span&gt;&lt;span&gt; /d &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt;nul&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;reg&lt;/span&gt;&lt;span&gt; add &lt;/span&gt;&lt;span&gt;&quot;HKCU\Software\Classes\ms-gamebar&quot;&lt;/span&gt;&lt;span&gt; /f /v &lt;/span&gt;&lt;span&gt;&quot;NoOpenWith&quot;&lt;/span&gt;&lt;span&gt; /d &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt;nul&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;reg&lt;/span&gt;&lt;span&gt; add &lt;/span&gt;&lt;span&gt;&quot;HKCU\Software\Classes\ms-gamebar\shell\open\command&quot;&lt;/span&gt;&lt;span&gt; /f /ve /d &lt;/span&gt;&lt;span&gt;&quot;\&quot;&lt;/span&gt;&lt;span&gt;%SystemRoot%&lt;/span&gt;&lt;span&gt;\System32\systray.exe\&lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt;nul&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;:: Create a black hole for ms-gamingoverlay protocol&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;reg&lt;/span&gt;&lt;span&gt; add &lt;/span&gt;&lt;span&gt;&quot;HKCU\Software\Classes\ms-gamingoverlay&quot;&lt;/span&gt;&lt;span&gt; /f /ve /d &lt;/span&gt;&lt;span&gt;&quot;URL:ms-gamingoverlay&quot;&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt;nul&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;reg&lt;/span&gt;&lt;span&gt; add &lt;/span&gt;&lt;span&gt;&quot;HKCU\Software\Classes\ms-gamingoverlay&quot;&lt;/span&gt;&lt;span&gt; /f /v &lt;/span&gt;&lt;span&gt;&quot;URL Protocol&quot;&lt;/span&gt;&lt;span&gt; /d &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt;nul&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;reg&lt;/span&gt;&lt;span&gt; add &lt;/span&gt;&lt;span&gt;&quot;HKCU\Software\Classes\ms-gamingoverlay&quot;&lt;/span&gt;&lt;span&gt; /f /v &lt;/span&gt;&lt;span&gt;&quot;NoOpenWith&quot;&lt;/span&gt;&lt;span&gt; /d &lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt;nul&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;reg&lt;/span&gt;&lt;span&gt; add &lt;/span&gt;&lt;span&gt;&quot;HKCU\Software\Classes\ms-gamingoverlay\shell\open\command&quot;&lt;/span&gt;&lt;span&gt; /f /ve /d &lt;/span&gt;&lt;span&gt;&quot;\&quot;&lt;/span&gt;&lt;span&gt;%SystemRoot%&lt;/span&gt;&lt;span&gt;\System32\systray.exe\&lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt;nul&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;echo&lt;/span&gt;&lt;span&gt; Injection complete! Protocol routed to void.&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;echo&lt;/span&gt;&lt;span&gt; Please plug in your controller to test.&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;pause&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;</content:encoded></item><item><title>Windows 常用软件</title><link>https://blog.gucrin.top/posts/cyrjtj/1/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/cyrjtj/1/</guid><description>运行库一类的</description><pubDate>Mon, 06 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&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;为了方便在干净安装 Windows 后快速查找运行库等驱动，特写本期博客分享&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;&lt;a href=&quot;https://www.nvidia.cn/software/nvidia-app/&quot; target=&quot;_blank&quot;&gt;NVIDIA app&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://www.nvidia.cn/drivers/&quot; target=&quot;_blank&quot;&gt;特定版本的 NVIDIA 驱动&lt;/a&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;&lt;a href=&quot;https://developer.microsoft.com/zh-cn/microsoft-edge/webview2/&quot; target=&quot;_blank&quot;&gt;Microsoft Edge Webview 2&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://zhangyue667.lanzouh.com/DirectXRepairEnhanced&quot; target=&quot;_blank&quot;&gt;DirectX Repair 增强版&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://423down.lanzouo.com/ibFny3c118de&quot; target=&quot;_blank&quot;&gt;Microsoft 常用运行库合集&lt;/a&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;&lt;a href=&quot;https://www.azul.com/downloads/&quot; target=&quot;_blank&quot;&gt;Zulu JDK&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://www.python.org/downloads/windows/&quot; target=&quot;_blank&quot;&gt;Python&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://abdownloadmanager.com/&quot; target=&quot;_blank&quot;&gt;AB Download Manager&lt;/a&gt;&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>用 OpenWrt 实现同 Wifi 双密码不同响应</title><link>https://blog.gucrin.top/posts/wifi-pay/%E7%94%A8-openwrt-%E5%AE%9E%E7%8E%B0%E5%90%8C-wifi-%E5%8F%8C%E5%AF%86%E7%A0%81%E4%B8%8D%E5%90%8C%E5%93%8D%E5%BA%94/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/wifi-pay/%E7%94%A8-openwrt-%E5%AE%9E%E7%8E%B0%E5%90%8C-wifi-%E5%8F%8C%E5%AF%86%E7%A0%81%E4%B8%8D%E5%90%8C%E5%93%8D%E5%BA%94/</guid><description>其实也可以用来做 Pay Wall</description><pubDate>Sat, 04 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&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;最近入手了个路由器，用来接校园网的宽带（神秘校园网只允许一个设备同时接入..）&lt;br /&gt;
正当我在想Wifi名的时候，突然想整个活，于是便设置成了Ciallo～ (∠・ω )⌒☆，密码也是喜闻乐见的0d000721。
但设置好后突然感觉不对：这不是相当于公开了我花钱办的宽带了吗🤔于是便想改&lt;br /&gt;
但最后思来想去还是不想放弃这个Wifi名称，于是便设法实现了使用两个不同密码连接会有不同响应的Wifi。具体来说，同一个名为Ciallo～ (∠・ω )⌒☆的网络，使用0d000721连接就只会弹一个带图片的网址，而使用另外一个密码连接才能正常上网。&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;想要实现上述效果，需要：
一台已刷OpenWrt的路由器（关于路由器的选购与刷机这里不赘述）&lt;br /&gt;
基础Shell操作知识&lt;br /&gt;
正常的网络连接&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;搞机有风险，操作需谨慎🥹&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;本教程使用的OpenWrt版本为25.XX，不建议在更早的版本上使用本教程，因为不同版本间的差异较大，可能会无法使用或造成故障。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;section&gt;&lt;h3&gt;创建Wifi&lt;a href=&quot;#创建wifi&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;我们创建需要使用不同密码连接的Wifi。
点击任意radio的添加按钮打开网络扫描，在弹出的框中翻到最下面，
在ESSID框中输入要使用的Wifi名称。
切换到无线安全，将加密改为WPA2-PSK，之后在密钥中输入真实的密码（之后能够正常联网的密码）
点击保存，最后点击最下面的保存并应用，等待设置更新。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;升级dnsmasq-full&lt;a href=&quot;#升级dnsmasq-full&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;首先由于我使用的是OpenNDS来做弹出的页面，所以需要将dnsmasq包升级为完整版。&lt;br /&gt;
在Shell中输入以下命令：&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;apk update &amp;amp;&amp;amp; apk add dnsmasq-full&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;看到形如 OK: XXX MiB in XXX packages 的结果即可&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;配置Multi-PSK&lt;a href=&quot;#配置multi-psk&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;使用Shell编辑/etc/config/wireless，以下是一个示例：&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;config wifi-device &apos;radio0&apos;&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;......&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;config wifi-iface &apos;default_radio0&apos;&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;......&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;config wifi-device &apos;radio1&apos;&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;......&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;config wifi-iface &apos;wifinet3&apos;&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;option device &apos;radio1&apos;&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;option network &apos;lan&apos;&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;option mode &apos;ap&apos;&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;option ssid &apos;hyw&apos;&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;option encryption &apos;psk2&apos;&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;option key &apos;ThisIsTheTruePassword&apos;&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;config wifi-iface &apos;wifinet2&apos;&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;&lt;span&gt;option device &apos;radio1&apos;&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;&lt;/span&gt;&lt;span&gt;option network &apos;wwan&apos;&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;&lt;/span&gt;&lt;span&gt;option ssid &apos;ExampleWifi&apos;&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;/span&gt;&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;可以看到，在config wifi-iface ‘default_radio1’配置块中有我们刚刚创建的Wifi，在config wifi-iface ‘wifinet2’配置块中有我们刚刚连接的Wifi。&lt;br /&gt;
接下来对配置文件做以下更改：&lt;/p&gt;&lt;section&gt;&lt;h4&gt;启用MultiPSK&lt;a href=&quot;#启用multipsk&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;在创建的Wifi的配置块中加入option multi_psk ‘1’
之后你的配置应该像这样：&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;config wifi-iface &apos;wifinet3&apos;&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;option device &apos;radio1&apos;&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;option network &apos;lan&apos;&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;option mode &apos;ap&apos;&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;option ssid &apos;hyw&apos;&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;option encryption &apos;psk2&apos;&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;option key &apos;ThisIsTheTruePassword&apos;&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;option multi_psk &apos;1&apos;&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;h4&gt;添加wifi-vlan块&lt;a href=&quot;#添加wifi-vlan块&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;config wifi-vlan&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;option name &apos;g_v&apos;&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;option network &apos;guest&apos;&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;option vid &apos;10&apos;&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;option iface &apos;wifinet3&apos;&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;注意：
这里的wifinet3为我们创建的wifi的wifi-iface的名字，见上面的示例配置。
这里的name可以任取但是不能太长，具体限制在不同设备上
可能不同，但建议只使用3~4个字符。
vid的10和network的guest均可自定义，不过之后需要保证配置能够对的上。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;添加wifi-station块&lt;a href=&quot;#添加wifi-station块&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;config wifi-station&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;option key &apos;0d000721&apos;&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;option vid &apos;10&apos;&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;option iface &apos;wifinet3&apos;&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;注意：
这里的key即为假密码，即无法正常上网的密码。
这里的vid和iface要和上面匹配。
编辑完成，保存文件进行下一步。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;添加设备与接口&lt;a href=&quot;#添加设备与接口&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;打开OpenWrt管理面板，进入网络&amp;gt;接口，切换到设备页面，点击最下面的添加设备配置。
在弹出的窗口中，将设备类型选为网桥设备,
设备名称设为br-guest（可以自己改），选中允许启动空网桥，然后点击保存。
接着切换回接口页面，点击下面的添加新接口，
将名称设置为guest（注意和上面的匹配），将协议设置为静态地址，将设备选为br-guest（和上面创建的匹配）,然后点击创建接口。
接着在弹出的窗口中，将IPv4 地址设置为192.168.72.1（可以任意设置，但要和你正常使用的主网络不同），将IPv4 子网掩码设置为255.255.255.0。
然后点击上面的防火墙设置，点击创建/分配防火墙区域，在最下面的自定义框中输入guest_zone（可以自己起名）然后按回车。
最后点击上面的DHCP 服务器，然后点击配置 DHCP 服务器按钮，不用变更配置。
最后点击保存关闭配置窗口，点击最下面的保存并应用，等待设置更新。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;安装OpenNDS&lt;a href=&quot;#安装opennds&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;OpenNDS的作用本来一般是提供上网认证界面，但这里我们使用它来做弹出图片的效果。
打开Shell，输入以下命令：&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;apk update &amp;amp;&amp;amp; apk add opennds&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;之后编辑/etc/config/opennds，找到option gatewayinterface行
（我设备上是第308行，可以使用查找功能查找），
将其取消注释并把后面的值换成上面配置的设备的名称。
更换之后配置应该如下：&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;...&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;# GateWayInterface&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;# Default br-lan&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;# Use this option to set the device opennds will bind to.&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;# The value may be an interface section in /etc/config/network or adevice name such as br-lan.&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;# The selected interface must be allocated an IPv4 address.&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;# In OpenWrt this is normally br-lan, in generic Linux it might besomething else.&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;div&gt;&lt;div&gt;&lt;div&gt;9&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;option gatewayinterface &apos;br-guest&apos;&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;/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;p&gt;保存文件，进行下一步。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;配置弹出页面&lt;a href=&quot;#配置弹出页面&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;编辑/usr/lib/opennds/theme_click-to-continue-basic.sh，
将里面的内容全部删除，替换成下面的：&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;#!/bin/sh&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;cat /etc/opennds/htdocs/splash.html&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;exit 0&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;之后保存文件。
然后编辑/etc/opennds/htdocs/splash.html（即上面配置的文件），将原有内容（如果有）全部删除，替换成你想要的内容。
在使用假密码登录时，OpenNDS会拦截链接并把/etc/opennds/htdocs/splash.html里面的HTML提供给登录者作为登录界面，所以这里可以自由发挥。
值得注意的是，由于使用假密码连接的时候没有网络连接，所以如果想要插入图片的话不能使用图床，因为无法访问。这里我为了方便直接使用了Base64硬编码图片到splash.html里。
另外，由于存在缓冲区大小限制，splash.html不能太长，所以如果要使用Base64添加图片的话需要对图片进行充分压缩。
以下是我的配置：&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;&amp;lt;!DOCTYPE html&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;html&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;head&amp;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;&amp;lt;title&amp;gt;Ciallo～ (∠・ω )⌒☆&amp;lt;/title&amp;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;&amp;lt;/head&amp;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;&amp;lt;body&amp;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;&amp;lt;h1&amp;gt;Ciallo～ (∠・ω )⌒☆&amp;lt;/h1&amp;gt;&amp;lt;br&amp;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;&amp;lt;img width=&quot;300px&quot; id=&quot;ciallo&quot; alt=&quot;ciallo&quot; src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAIAAADvz6...(太长了省略)&quot; /&amp;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;&amp;lt;/body&amp;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;&amp;lt;/html&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;p&gt;保存文件，至此配置已经全部完成。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;重启服务&lt;a href=&quot;#重启服务&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;/etc/init.d/network restart&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;wifi reload&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;/etc/init.d/dnsmasq restart&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;/etc/init.d/opennds restart&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;之后应该就可以看到创建的Ciallo～ (∠・ω )⌒☆Wifi了。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;遇到问题？&lt;a href=&quot;#遇到问题&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;由于本人之前也没有接触过OpenWrt，在尝试实现这个效果的过程中也是在摸索，
所以如果各位遇到了一些问题我可能无法进行有效的解答。不过这里有些我
遇到过的问题，供大家参考。&lt;/p&gt;&lt;p&gt;在配置完OpenNDS并重启后无法访问LuCI？
这一般是因为OpenNDS没有被正确配置（即gatewayinterface没有与前面
创建的设备匹配），导致它将所有网络连接全部拦截。&lt;/p&gt;&lt;p&gt;遇到这种情况时，使用Shell登录，并执行/etc/init.d/opennds stop
来停止OpenNDS，之后应该就能恢复LuCI访问。
为了解决问题，请参照上面的步骤正确配置之后，再运行/etc/init.d/opennds start
恢复OpenNDS，看看是否正常工作。&lt;/p&gt;&lt;p&gt;重启服务后找不到添加的Wifi？
这可能是因为你的wifi-vlan块中的name过长，
请参照上面的步骤将其改短后再执行wifi reload看看。&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>让 Windows 用上 mac OS 26 同款图标</title><link>https://blog.gucrin.top/posts/win-icon/%E8%AE%A9-windows-%E7%94%A8%E4%B8%8A-mac-os-26-%E5%90%8C%E6%AC%BE%E5%9B%BE%E6%A0%87/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/win-icon/%E8%AE%A9-windows-%E7%94%A8%E4%B8%8A-mac-os-26-%E5%90%8C%E6%AC%BE%E5%9B%BE%E6%A0%87/</guid><description>哎呦我大玻璃图标</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&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;我很喜欢 mac OS 的图标设计，于是研究出了一个方法可以把 mac OS 的图标引入到 Windows 使用。&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;section&gt;&lt;h3&gt;HQ ICON&lt;a href=&quot;#hq-icon&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;a href=&quot;https://github.com/YuKongA/HQ-ICON&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;YuKongA&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;HQ-ICON&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;[Web] Get app icons from App Store&lt;/div&gt;&lt;div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;MIT&lt;/div&gt;&lt;span&gt;JavaScript&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;https://icon.yukonga.top/&quot; target=&quot;_blank&quot;&gt;作者自己域名&lt;/a&gt; 或 &lt;a href=&quot;https://yukonga.github.io/HQ-ICON/&quot; target=&quot;_blank&quot;&gt;Github Page&lt;/a&gt;&lt;br /&gt;
这个网站可以从 App Store 获取高清应用图标&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;注意&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;由于 Apple 有时会对 Android UA 进行限制，Android 设备查询时可能只会返回一个名称完全匹配的结果。如遇此问题，可以尝试使用 &lt;a href=&quot;https://github.com/YuKongA/HQ-ICON_Compose/releases&quot; target=&quot;_blank&quot;&gt;App&lt;/a&gt; 版本绕过这个限制。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;PNG 转 ICO&lt;a href=&quot;#png-转-ico&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://www.aconvert.com/cn/icon/png-to-ico/&quot; target=&quot;_blank&quot;&gt;PNG转ICO - 在线转换图标文件&lt;/a&gt;
简单的图片转换网站，支持多分辨率 (最高512×512) 的 ICO 格式转换&lt;/p&gt;&lt;/section&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;section&gt;&lt;h3&gt;下载图标&lt;a href=&quot;#下载图标&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在 HQ ICON 中搜索对应软件的图标，点击图标即可下载&lt;/p&gt;&lt;section&gt;&lt;h4&gt;筛选条件&lt;a href=&quot;#筛选条件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;查询类型  一般选 iOS&lt;br /&gt;
查询数量  按个人喜好选择&lt;br /&gt;
国家地区  CN 搜不到的切 US 或其他国家地区&lt;br /&gt;
裁切方式  推荐官方圆角&lt;br /&gt;
图像格式  PNG&lt;br /&gt;
图像尺寸  1024px&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;转换图标文件&lt;a href=&quot;#转换图标文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;打开 PNG 转 ICO 网站&lt;br /&gt;
图标类型：多分辨率图标&lt;br /&gt;
图标尺寸：16x16 至 256x256 全部勾选&lt;br /&gt;
然后将转换好的文件下载下来&lt;/p&gt;&lt;/section&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;右键桌面上的任意图标，点击属性 - 快捷方式 - 更改图标&lt;br /&gt;
然后选择对应转换好的图标文件即可&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>比 N 卡回放还好用？OBS Studio 回放配置教程</title><link>https://blog.gucrin.top/posts/obs-replay/%E6%AF%94-n-%E5%8D%A1%E5%9B%9E%E6%94%BE%E8%BF%98%E5%A5%BD%E7%94%A8obs-studio-%E5%9B%9E%E6%94%BE%E9%85%8D%E7%BD%AE%E6%95%99%E7%A8%8B/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/obs-replay/%E6%AF%94-n-%E5%8D%A1%E5%9B%9E%E6%94%BE%E8%BF%98%E5%A5%BD%E7%94%A8obs-studio-%E5%9B%9E%E6%94%BE%E9%85%8D%E7%BD%AE%E6%95%99%E7%A8%8B/</guid><description>OBS 真不错</description><pubDate>Sun, 29 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&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;我在玩游戏的过程中总会打出精彩操作，为了能够保存下来我选择使用 OBS Studio 的回放缓存功能，并配合插件来满足我的使用需求~&lt;br /&gt;
我会在接下来的部分介绍我的 OBS 设置以及插件设置方法，希望能够帮到你&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;section&gt;&lt;h3&gt;OBS Studio&lt;a href=&quot;#obs-studio&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;a href=&quot;https://github.com/obsproject/obs-studio&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;obsproject&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;obs-studio&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;OBS Studio - Free and open source software for live streaming and screen recording&lt;/div&gt;&lt;div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;GPL-2.0&lt;/div&gt;&lt;span&gt;C&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;p&gt;也可以前往 &lt;a href=&quot;https://obsproject.com/download&quot; target=&quot;_blank&quot;&gt;OBS 官网&lt;/a&gt; 下载&lt;/p&gt;&lt;p&gt;用于直播和屏幕录制的免费开源软件&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;OBS Notifier&lt;a href=&quot;#obs-notifier&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;a href=&quot;https://github.com/DmitriySalnikov/OBSNotifier&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;DmitriySalnikov&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;OBSNotifier&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Simple program for displaying notifications from OBS on your desktop.&lt;/div&gt;&lt;div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;MIT&lt;/div&gt;&lt;span&gt;C#&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;p&gt;也可以前往 &lt;a href=&quot;https://obsproject.com/forum/resources/obs-notifier.1625/&quot; target=&quot;_blank&quot;&gt;OBS 论坛&lt;/a&gt; 下载&lt;/p&gt;&lt;p&gt;一款简单的插件，用于在桌面上显示 OBS 的通知&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Replay Buffer - move to folder&lt;a href=&quot;#replay-buffer---move-to-folder&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;a href=&quot;https://github.com/YelovSK/replay-buffer-move-to-folder&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;YelovSK&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;replay-buffer-move-to-folder&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Moves OBS replay buffer recordings into folders based on the active window.&lt;/div&gt;&lt;div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;GPL-2.0&lt;/div&gt;&lt;span&gt;C&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;p&gt;也可以前往 &lt;a href=&quot;https://obsproject.com/forum/resources/replay-buffer-move-to-folder.2055/&quot; target=&quot;_blank&quot;&gt;OBS 论坛&lt;/a&gt; 下载&lt;/p&gt;&lt;p&gt;一款简单的插件，会根据当前活动窗口，将 OBS 回放缓存录制的内容移动到相应的文件夹中&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;CoreAudio - AAC&lt;a href=&quot;#coreaudio---aac&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;a href=&quot;https://github.com/kiki-kiko/iTunes-12.3.1.23&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;kiki-kiko&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;iTunes-12.3.1.23&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;iTunes.exe Bundle&lt;/div&gt;&lt;div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;no-license&lt;/div&gt;&lt;span&gt;Unavailable&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;p&gt;只需要下载 AppleApplicationSupport64.msi 和 AppleMobileDeviceSupport6464.msi 即可&lt;/p&gt;&lt;p&gt;来自 Apple 的 ACC 320 Kbps 高音质编码器&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;OBS Studio 配置&lt;a href=&quot;#obs-studio-配置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;直播设置&lt;a href=&quot;#直播设置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;音频编码器：CoreAudio AAC&lt;br /&gt;
视频编码器：NVIDIA NVENC H.264&lt;br /&gt;
重新缩放输出：已禁用&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;录制设置&lt;a href=&quot;#录制设置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;录像路径：自定义或保持默认&lt;br /&gt;
录像格式：Matroska 视频 (.mkv)&lt;br /&gt;
视频编码器：NVIDIA NVENC H.264&lt;br /&gt;
音频编码器：CoreAudio AAC&lt;br /&gt;
音轨：1 2 3 4 5 6 全选&lt;br /&gt;
重新缩放输出：已禁用&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;编码器设置&lt;a href=&quot;#编码器设置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;比特率控制：恒定比特率 ( CBR )&lt;br /&gt;
比特率：10000 Kbps&lt;br /&gt;
关键帧间隔 (秒，0 ＝ 自动)：0 s&lt;br /&gt;
预设： P4&lt;br /&gt;
调节：高质量&lt;br /&gt;
多次编码模式：二次编码 (1/4 分辨率)&lt;br /&gt;
配置文件：high&lt;br /&gt;
前向考虑：关闭&lt;br /&gt;
自适应量化：开启&lt;br /&gt;
B 帧：2&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;快捷键设置&lt;a href=&quot;#快捷键设置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在 OBS Studio 的设置 - 快捷键中，可以修改回放缓存的快捷键&lt;br /&gt;
我设置的是 Ctrl + Alt + Shift&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;快捷方式设置&lt;a href=&quot;#快捷方式设置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;属性&lt;a href=&quot;#属性&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;在桌面右键 OBS Studio 图标，选择属性，在目标栏的 obs64.exe 后加入下方的启动参数&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;--startreplaybuffer --minimize-to-tray&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;/section&gt;&lt;section&gt;&lt;h4&gt;兼容性&lt;a href=&quot;#兼容性&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;转到兼容性面板，勾选 以管理员身份运行此程序&lt;/p&gt;&lt;p&gt;这是为了OBS快捷键能够在游戏内正常生效&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;OBS Notifier 设置&lt;a href=&quot;#obs-notifier-设置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;连接 WebSocket 服务器&lt;a href=&quot;#连接-websocket-服务器&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;打开 OBS Studio，在上方工具栏中选择 工具 - WebSocket 服务器设置&lt;br /&gt;
选择 开启 WebSocket 服务器
然后选择 显示连接信息，复制服务器密码&lt;/p&gt;&lt;p&gt;回到 OBS Notifier, WebSocket 服务器地址如下填写&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;localhost:4455&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;服务器密码则是刚刚在 OBS Studio 复制的服务器密码，复制粘贴即可连接到 OBS Studio 了&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;开机启动和跟随关闭&lt;a href=&quot;#开机启动和跟随关闭&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;选择 开机启动，并点击右边的 从OBS开始，OBS Notifier 会生成一个自动启动脚本，并将该脚本的路径自动复制到你的剪贴板&lt;/p&gt;&lt;p&gt;回到 OBS Studio，在上方工具栏中选择 工具 - 脚本&lt;br /&gt;
点击 + 号，在新弹出的窗口中点击文件地址栏并粘贴进去，删除 obs_notifier_autostart.lua 再回车，即可成功添加脚本&lt;br /&gt;
跟随 OBS Studio 关闭只需要选择 退出OBS时关闭此程序 (设置窗口关闭时)&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;附加参数&lt;a href=&quot;#附加参数&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;BackgroundColor = #DD0031&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;ForegroundColor = #000000&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;TextColor = #E4E4E4&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;SlideDuration = 400&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;SlideOffset = 180&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;LineWidth = 6.0&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;Scale = 1.0&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;MaxPathChars = 32&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;ClickThrough = False&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;ShowQuickActions = false&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;ShowQuickActionsColoredLine = false&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;QuickActionsOffset = 8.0&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;IconHeight = 64.0&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;IconPath = branding_rsx.ico&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;h2&gt;Replay Buffer - move to folder 设置&lt;a href=&quot;#replay-buffer---move-to-folder-设置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;安装后自动启用，可以在 OBS Studio 的工具 - 插件中查看启用情况&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;现在你的 OBS Studio 应该可以承担游戏录制回放的任务了~&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>Apple Music 也被破解了！音质最好的音乐平台免费下载？</title><link>https://blog.gucrin.top/posts/amdl/amdl/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/amdl/amdl/</guid><description>Apple Music 音源下载与解密</description><pubDate>Sat, 14 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;提示&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;本教程仅供技术交流与学习研究，请勿用于商业用途或侵犯版权。请在下载后 24 小时内删除。&lt;/p&gt;&lt;/div&gt;&lt;/div&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;本教程利用 Termux 在 Android 上运行 Linux 环境，并部署 AppleMusicDecrypt 项目。&lt;/p&gt;&lt;p&gt;特点：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;支持无损 (ALAC)、杜比全景声 (Atmos) 下载&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无需 Apple Music 订阅即可解密 （利用公共实例)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;支持简体中文元数据，自动保存歌词（LRC)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&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;section&gt;&lt;h3&gt;下载 Termux&lt;a href=&quot;#下载-termux&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;a href=&quot;https://github.com/termux/termux-app&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;termux&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;termux-app&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Termux - a terminal emulator application for Android OS extendible by variety of packages.&lt;/div&gt;&lt;div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;NOASSERTION&lt;/div&gt;&lt;span&gt;Java&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;p&gt;或者：&lt;a href=&quot;https://f-droid.org/en/packages/com.termux/&quot; target=&quot;_blank&quot;&gt;F-Droid 下载&lt;/a&gt;&lt;/p&gt;&lt;section&gt;&lt;h4&gt;授予存储权限&lt;a href=&quot;#授予存储权限&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;打开 Termux，输入以下命令并允许权限：&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;termux-setup-storage&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;h3&gt;安装 Debian&lt;a href=&quot;#安装-debian&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;section&gt;&lt;h4&gt;更新软件源&lt;a href=&quot;#更新软件源&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;pkg update -y&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;h4&gt;安装 Proot-distro&lt;a href=&quot;#安装-proot-distro&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;pkg install proot-distro -y&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;h4&gt;安装 Debian&lt;a href=&quot;#安装-debian-1&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;pd i debian&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;section&gt;&lt;h2&gt;安装基础环境&lt;a href=&quot;#安装基础环境&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;进入 Debian 环境&lt;a href=&quot;#进入-debian-环境&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;pd login debian&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;h4&gt;安装 git 和 Python 环境管理器&lt;a href=&quot;#安装-git-和-python-环境管理器&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;apt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pipx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span&gt;pipx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;poetry&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span&gt;pipx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ensurepath&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span&gt;source&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;~/.bashrc&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;section&gt;&lt;h2&gt;部署 AppleMusicDecrypt&lt;a href=&quot;#部署-applemusicdecrypt&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;section&gt;&lt;h3&gt;克隆项目源码&lt;a href=&quot;#克隆项目源码&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;git clone https://github.com/WorldObservationLog/AppleMusicDecrypt&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;h4&gt;切换到项目目录&lt;a href=&quot;#切换到项目目录&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;cd AppleMusicDecrypt&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;h4&gt;编译安装依赖&lt;a href=&quot;#编译安装依赖&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;重要&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;执行此命令后，屏幕可能会长时间没有输出，或者滚动大量代码。这是正在从源码编译 MP4Box，非常耗时，通常需要 10 到 20 分钟。请保持手机常亮，千万不要关闭 Termux。如果长时间完全无反应，可以考虑 Ctrl+C 停止后重试。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;bash&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;./tools/install-deps.sh&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;h4&gt;安装 Python 依赖&lt;a href=&quot;#安装-python-依赖&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;poetry env use /usr/bin/python3 &amp;amp;&amp;amp; poetry install&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;h3&gt;生成配置文件&lt;a href=&quot;#生成配置文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&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;cp config.example.toml config.toml&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;h4&gt;修改配置文件&lt;a href=&quot;#修改配置文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&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;sed -i &apos;s/url = &quot;127.0.0.1:8080&quot;/url = &quot;wm.wol.moe&quot;/g&apos; config.toml&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;sed -i &apos;s/secure = false/secure = true/g&apos; config.toml&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;figure&gt;&lt;figcaption&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;sed -i &apos;s|dirPathFormat = &quot;downloads/{album_artist}/{album}&quot;|dirPathFormat = &quot;/sdcard/Music/AppleMusic&quot;|g&apos; config.toml&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;sed -i &apos;s|playlistDirPathFormat = &quot;/sdcard/Music/playlists/{playlistName}&quot;|playlistDirPathFormat = &quot;/sdcard/Music/AppleMusic&quot;|g&apos; config.toml&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;figure&gt;&lt;figcaption&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;sed -i &apos;s|songNameFormat = &quot;{disk}-{tracknum:02d} {title}&quot;|songNameFormat = &quot;{title} - {artist}&quot;|g&apos; config.toml&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;figure&gt;&lt;figcaption&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;sed -i &apos;s/language = &quot;zh-Hant-HK&quot;/language = &quot;zh-Hans-CN&quot;/g&apos; config.toml&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;h3&gt;设置 “一键启动” 捷径&lt;a href=&quot;#设置-一键启动-捷径&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;为了以后使用方便，我们设置一个别名，以后只需要输入 AppleMusic 就能启动程序。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;退出 Debian 环境&lt;a href=&quot;#退出-debian-环境&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;exit&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;h4&gt;写入启动命令到配置文件&lt;a href=&quot;#写入启动命令到配置文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;echo &quot;alias am=&apos;pd login debian -- bash -c \&quot;cd ~/AppleMusicDecrypt &amp;amp;&amp;amp; poetry run python main.py\&quot;&apos;&quot; &amp;gt;&amp;gt; ~/.bashrc&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;h4&gt;刷新配置&lt;a href=&quot;#刷新配置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;source&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;~/.bashrc&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;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;打开 Termux，输入：&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;am&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;看到出现 &amp;gt; 符号，就说明启动成功了！&lt;/p&gt;&lt;p&gt;常用下载命令：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;下载歌曲/专辑/歌单 （默认 ALAC 无损) ：&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;dl https://music.apple.com/example&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;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;alac=无损, aac=有损, ec3=杜比全景声&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;dl -c ec3 https://music.apple.com/example&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;/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;dl -l zh-Hans-CN https://music.apple.com/example&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;/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;qa https://music.apple.com/example&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;/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;exit&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;对歌曲的后期处理&lt;a href=&quot;#对歌曲的后期处理&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;下载器会自动生成 .lrc 歌词文件，但很多播放器不自动识别。我们可以使用 “音乐标签” 这款 App 将歌词写入音乐文件内部。&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;下载并打开“音乐标签”App。&lt;/li&gt;
&lt;li&gt;进入 /sdcard/Music/AppleMusic 目录。&lt;/li&gt;
&lt;li&gt;选中需要处理的歌曲（可全选）。&lt;/li&gt;
&lt;li&gt;点击“编辑” -&amp;gt; 找到“歌词”栏。&lt;/li&gt;
&lt;li&gt;点击导入图标，选择同名的 .lrc 文件。&lt;/li&gt;
&lt;li&gt;保存。&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;这样处理后，即使你删除了 .lrc 文件，Poweramp、foobar2000 等播放器也能正常显示歌词。&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h2&gt;常见问题 (FAQ)&lt;a href=&quot;#常见问题-faq&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Q1: 执行 bash ./tools/install-deps.sh 时一直没反应，是不是卡死了？&lt;/p&gt;&lt;p&gt;A: 不一定是卡死。这是在编译 MP4Box，在 Android 手机上非常慢。请保持耐心等待 10-20 分钟。如果 CPU 没有占用或者 Termux 闪退，才需要重来。&lt;/p&gt;&lt;p&gt;Q2: 下载时卡在 Decrypting… 不动？&lt;/p&gt;&lt;p&gt;A: 这通常是公共服务器 拥堵或短暂故障。按 Ctrl+C 停止，重启 Termux 再次输入 am 重试即可。如果终端下方显示的 Decrypt Speed: xx.xx 数字在跳动，那就是正常的，请耐心等待。&lt;/p&gt;&lt;p&gt;Q3: 为什么有的歌没有歌词？&lt;/p&gt;&lt;p&gt;A: 取决于 Apple Music 官方数据。如果在 Apple Music App 里播放这首歌也没有歌词，那下载器自然也抓不到。可以尝试用 -l en-US 或 -l ja 指定其他地区语言试一试。&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>给 Steam 加点得劲魔法❤️ — Steam 优化小技巧</title><link>https://blog.gucrin.top/posts/steam-extension/steam-extension/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/steam-extension/steam-extension/</guid><description>这样舒服多了</description><pubDate>Mon, 09 Mar 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;Steam 作为全球最大的游戏平台，可以说是必装软件之一了。但是它的客户端缺失的一些功能却又恰恰是玩家们需要的，而且在中国大陆地区 Steam 的访问速度也是不尽如人意… 那么在本期文章中，我将给你的 Steam 施展得劲の魔法❤️让它变得更加好用(＾.＾)✌️&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;优化与 Steam 服务器的连接&lt;a href=&quot;#优化与-steam-服务器的连接&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;首先来解决一下访问速度的问题，大家可能首先想到的是 Steam++，也就是现在的 Watt Toolkit&lt;/p&gt;&lt;a href=&quot;https://github.com/BeyondDimension/SteamTools&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;BeyondDimension&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;SteamTools&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;🛠「Watt Toolkit」是一个开源跨平台的多功能 Steam 工具箱。&lt;/div&gt;&lt;div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;GPL-3.0&lt;/div&gt;&lt;span&gt;C#&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;p&gt;是的，它很好用，但是现在的它广告多，启动速度很慢。
因此，我推荐使用另一位大佬 &lt;a href=&quot;https://www.dogfight360.com/blog/author/wu360463231/&quot; target=&quot;_blank&quot;&gt;羽翼城 | Dogfight360&lt;/a&gt; 开发的软件：Steamcommunity 302
&lt;a href=&quot;https://www.dogfight360.com/blog/18682/&quot; target=&quot;_blank&quot;&gt;Steamcommunity 302 下载&lt;/a&gt;
软件界面简洁，无广，且支持多种平台加速&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;给 Steam 安装扩展&lt;a href=&quot;#给-steam-安装扩展&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Steam 客户端是基于 Chromium 的，某种意义上 Steam 客户端就是一个浏览器套壳，基于此我们可以加装扩展，来拓展 Steam 的使用体验~&lt;/p&gt;&lt;section&gt;&lt;h4&gt;查看史低价格&lt;a href=&quot;#查看史低价格&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;安装 SteamDB，首先正常启动 Steam，并打开 商店 页面
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;商店 页面&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1032&quot; src=&quot;/_astro/steam-1.8zaqeSmT_ZL6kmP.webp&quot; /&gt;&lt;figcaption&gt;商店 页面&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;然后，用鼠标滚轮（中键）点击任意一款游戏，Steam 会弹出新窗口
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;新窗口&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1032&quot; src=&quot;/_astro/steam-2.DJ8oBem0_2g1p9e.webp&quot; /&gt;&lt;figcaption&gt;新窗口&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;在地址栏输入 “chrome://extensions”，然后敲击键盘 回车（Enter）
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;chrome://extensions&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;774&quot; src=&quot;/_astro/steam-3.D-GIcPDU_2rlBMB.webp&quot; /&gt;&lt;figcaption&gt;chrome://extensions&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;点击左侧 “Chrome 应用商店”，进入 Chrome 网上应用商店
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;Chrome 网上应用商店&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;774&quot; src=&quot;/_astro/steam-4.KyhjEptm_Z1wX2ue.webp&quot; /&gt;&lt;figcaption&gt;Chrome 网上应用商店&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;搜索 SteamDB，点击 添加至 Chrome，新弹出的窗口会询问你保存位置，直接点击保存即可
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;保存&quot; loading=&quot;lazy&quot; width=&quot;1281&quot; height=&quot;774&quot; src=&quot;/_astro/steam-5.C1KxucgG_X4iKr.webp&quot; /&gt;&lt;figcaption&gt;保存&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;此时 SteamDB 扩展已安装完成，回到 商店 页面，随意点击一款游戏，能看到 SteamDB 数据，安装完成~
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;安装完成&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1032&quot; src=&quot;/_astro/steam-6.Crxs_l1a_1VM8Fg.webp&quot; /&gt;&lt;figcaption&gt;安装完成&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;市场比价、批量上架，批量购买、一键徽章合成等&lt;a href=&quot;#市场比价批量上架批量购买一键徽章合成等&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;安装 Steam Inventory Helper，操作同上&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;Steam 崩溃了怎么办？&lt;a href=&quot;#steam-崩溃了怎么办&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;首先在 文件资源管理器 中，打开 显示隐藏文件，然后进入以下位置&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;C:\Users\你的用户名\Appdata\Local\Steam\htmlcache\Default\Extensions&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;删除拓展后重启 Steam 即可&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;</content:encoded></item><item><title>Fedora 新手进！必看教程来了</title><link>https://blog.gucrin.top/posts/fedora-setup/fedora-setup/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/fedora-setup/fedora-setup/</guid><description>一起加入 Fedora 的世界吧❤️</description><pubDate>Mon, 02 Mar 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;👋 嘿，你好！
既然你来到了这里，想必你刚刚安装完 Fedora，正盯着全新的桌面发愁：“接下来该干嘛？” 我也经历过这个阶段。Fedora 在刚安装完后确实需要“推一把”才能达到最佳状态 :)。这就是我编写这份指南的原因，它汇总了我从多个渠道收集的 Fedora 切换经验。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;[!ABSTRACT] 摘要
这不是官方指南。这只是分享我个人的配置方案和偏好，你可以根据需要选择性跳过。在复制粘贴任何命令之前，请务必先阅读说明。&lt;/p&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;关于命令的小提示&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;
&lt;li&gt;看到开头的 sudo，意味着“以管理员身份运行”，它会要求输入密码。&lt;/li&gt;
&lt;li&gt;-y 标签意味着“对所有确认提示都回答 Yes”，这样你就不用一直按回车了。&lt;/li&gt;
&lt;li&gt;复制粘贴是你的好伙伴，但 运行前请务必确认命令内容。&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;/div&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;section&gt;&lt;h4&gt;RPM Fusion - 软件源大补帖&lt;a href=&quot;#rpm-fusion---软件源大补帖&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;由于法律原因，Fedora 预装的软件非常精简。RPM Fusion 是存放那些“真正有用”的东西的地方（如编解码器、驱动等）。你肯定需要它。&lt;/p&gt;&lt;p&gt;获取 free 仓库 (包含大部分你需要的东西)&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\ &lt;/span&gt;&lt;span&gt;https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;rpm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-E&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%fedora&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.noarch.rpm&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;获取 nonfree 仓库 (包含 NVIDIA 驱动和部分专有编解码器)&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\ &lt;/span&gt;&lt;span&gt;https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;rpm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-E&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%fedora&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.noarch.rpm&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;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;upgrade&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;core&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;check-update&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;blockquote&gt;&lt;p&gt;[!FAQ] Free 和 Nonfree 有什么区别？&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Free: 法律上允许自由分发的开源软件。&lt;/li&gt;
&lt;li&gt;Nonfree: 专有软件（如 NVIDIA 驱动、部分音视频格式），由于授权原因 Fedora 官方无法直接携带。&lt;/li&gt;
&lt;/ul&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;系统更新 (枯燥但重要)&lt;a href=&quot;#系统更新-枯燥但重要&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;我知道更新很无聊，但真的请先做这一步。刚安装完的系统通常有很多过时的软件包。&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;更新所有内容&lt;a href=&quot;#更新所有内容&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;sudo dnf update -y&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;如果更新了内核，请重启&lt;a href=&quot;#如果更新了内核请重启&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;sudo reboot&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;建议&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;养成每周或每月运行一次 sudo dnf update 的习惯。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;固件更新&lt;a href=&quot;#固件更新&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;你的硬件可能有更新的固件可用，这对于改善 WiFi 稳定性和电池续航很有帮助。&lt;/p&gt;&lt;p&gt;查看有哪些设备可更新&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fwupdmgr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get-devices&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;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fwupdmgr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;refresh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--force&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;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fwupdmgr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get-updates&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;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fwupdmgr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;update&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;div&gt;&lt;/div&gt;&lt;div&gt;注意&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;固件更新后必须重启系统才能生效。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;给你的电脑起个名&lt;a href=&quot;#给你的电脑起个名&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;这纯粹是为了好看，让你更有归属感。挑个酷一点的名字吧！&lt;/p&gt;&lt;p&gt;把 hungry-beast 换成你喜欢的名字&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hostnamectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;set-hostname&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hungry-beast&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;section&gt;&lt;h4&gt;Flathub 设置&lt;a href=&quot;#flathub-设置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;Fedora 默认只开启了一个“阉割版”的 Flatpak 仓库。Flathub 才是真正的宝库。&lt;/p&gt;&lt;p&gt;移除限制版的 Fedora Flatpak 仓库&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;flatpak&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;remote-delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fedora&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;选项 1：完整仓库（最推荐）
可以访问 Flathub 上的所有应用（包括那些非开发者官方维护的社区版应用）：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;flatpak&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;remote-add&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--if-not-exists&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;flathub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https://flathub.org/repo/flathub.flatpakrepo&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;选项 2：仅限验证过的应用
如果你只信任由软件原作者维护的应用：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;flatpak&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;remote-add&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--if-not-exists&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--subset=verified&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;flathub&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https://flathub.org/repo/flathub.flatpakrepo&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;div&gt;&lt;/div&gt;&lt;div&gt;警告&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;很多流行的社区打包应用将不会显示。&lt;/p&gt;&lt;/div&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;NVIDIA (比较棘手)&lt;/p&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;警告&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;NVIDIA 在 Linux 上比较复杂。以下方法通常有效，但如果遇到问题，欢迎加入“受害者联盟”。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;📋 开始之前：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;在 BIOS 中关闭 Secure Boot（或者学习如何给内核模块签名，由你决定 ;)）。&lt;/li&gt;
&lt;li&gt;确保系统已 更新并重启过。&lt;/li&gt;
&lt;li&gt;准备好备份方案（认真的，搞砸了我不负责）。&lt;/li&gt;
&lt;/ul&gt;&lt;section&gt;&lt;h4&gt;安装内核头文件和开发工具&lt;a href=&quot;#安装内核头文件和开发工具&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kernel-devel&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kernel-headers&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;gcc&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;make&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dkms&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;acpid&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;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;libglvnd-glx&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;libglvnd-opengl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;libglvnd-devel&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pkgconfig&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;div&gt;&lt;/div&gt;&lt;div&gt;RTX 4000 及更新系列显卡特别说明&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;如果你使用的是 4000 系列或更新的 GPU，Fedora 需要在安装驱动前设置一个宏，以启用开源内核模块。&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;设置开源内核模块宏 (一次性步骤)&lt;a href=&quot;#设置开源内核模块宏-一次性步骤&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sh&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-c&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;echo &quot;%_with_kmod_nvidia_open 1&quot; &amp;gt; /etc/rpm/macros.nvidia-kmod&apos;&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;h4&gt;安装驱动程序&lt;a href=&quot;#安装驱动程序&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;akmod-nvidia&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;xorg-x11-drv-nvidia-cuda&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;现在请耐心等待。认真的，构建模块需要 5–15 分钟。你可以通过此命令查看进度：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;journalctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-u&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;akmods&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;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;reboot&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;p&gt;运行 nvidia-smi 如果你看到了 GPU 信息，那就成功了！&lt;/p&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;视频编解码器 (解决视频无法播放)
Fedora 由于专利问题基本不带编解码器。以下命令可以修复它。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;用功能完整的 ffmpeg 替换“阉割版”&lt;a href=&quot;#用功能完整的-ffmpeg-替换阉割版&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;sudo dnf swap -y ffmpeg-free ffmpeg —allowerasing&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;安装所有 GStreamer 插件&lt;a href=&quot;#安装所有-gstreamer-插件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;gstreamer1-plugins-{bad-&lt;/span&gt;&lt;span&gt;\*&lt;/span&gt;&lt;span&gt;,good-&lt;/span&gt;&lt;span&gt;\*&lt;/span&gt;&lt;span&gt;,base}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\ &lt;/span&gt;&lt;span&gt;gstreamer1-plugin-openh264&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;gstreamer1-libav&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lame&lt;/span&gt;&lt;span&gt;\*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\ &lt;/span&gt;&lt;span&gt;--exclude=gstreamer1-plugins-bad-free-devel&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;h4&gt;安装多媒体组&lt;a href=&quot;#安装多媒体组&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;multimedia&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;group&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sound-and-video&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;微软字体 (无奈但必须)
没有这些字体，网页和文档看起来会很奇怪。&lt;/p&gt;&lt;section&gt;&lt;h4&gt;安装依赖&lt;a href=&quot;#安装依赖&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cabextract&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;xorg-x11-font-utils&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fontconfig&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;h4&gt;安装字体&lt;a href=&quot;#安装字体&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rpm&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;--nodigest&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--nosignature&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm&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;h4&gt;更新字体缓存&lt;a href=&quot;#更新字体缓存&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fc-cache&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-fv&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;blockquote&gt;&lt;p&gt;[!QUOTE] 碎碎念
是的，我们仍然需要 Arial 和 Times New Roman 字体。这得怪微软)&lt;/p&gt;&lt;/blockquote&gt;&lt;/section&gt;&lt;section&gt;&lt;h4&gt;Flatpak 自动更新&lt;a href=&quot;#flatpak-自动更新&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;你可以让 Flatpak 应用自动保持最新。&lt;/p&gt;&lt;p&gt;[Unit]
Description=Update Flatpak apps automatically&lt;/p&gt;&lt;p&gt;[Service]
Type=oneshot
ExecStart=/usr/bin/flatpak update -y —noninteractive&lt;/p&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;加快开机速度
这个改动很简单，效果很明显。&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;disable&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;NetworkManager-wait-online.service&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;blockquote&gt;&lt;p&gt;[!QUESTION] 为什么？
这个服务在开机时等待网络连接。对于大多数个人用户来说，不需要这种开机时的强制延迟。&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;section&gt;&lt;h4&gt;清理软件包缓存&lt;a href=&quot;#清理软件包缓存&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;clean&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;all&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;h4&gt;移除不再需要的孤立软件包&lt;a href=&quot;#移除不再需要的孤立软件包&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;dnf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;autoremove&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&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;</content:encoded></item><item><title>自建私人云相册 — Immich 部署教程</title><link>https://blog.gucrin.top/posts/immich/%E8%87%AA%E5%BB%BA%E7%A7%81%E4%BA%BA%E4%BA%91%E7%9B%B8%E5%86%8C--immich-%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/immich/%E8%87%AA%E5%BB%BA%E7%A7%81%E4%BA%BA%E4%BA%91%E7%9B%B8%E5%86%8C--immich-%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/</guid><description>Google 相册的表弟来了说是</description><pubDate>Fri, 27 Feb 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;最近给我的小主机 HP Elite 800 G SFF 重装了 Fedora 43 WorkStation 系统，在使用 Docker Compose 安装 Immich 的时候发现了一点问题，不过顺利解决。于是决定顺便把部署过程写出来😎&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;section&gt;&lt;h3&gt;下载配置文件&lt;a href=&quot;#下载配置文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;首先新建文件夹用于存放配置文件，例如
“/home/Docker/immich&lt;/p&gt;&lt;p&gt;然后在文件夹中打开终端：&lt;/p&gt;&lt;p&gt;下载 docker-compose.yml&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;wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml&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;下载 .env file&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;wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env&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;example.env&lt;/code&gt; 重命名为 &lt;code&gt;.env&lt;/code&gt;哦！&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;自定义 .env 文件配置&lt;a href=&quot;#自定义-env-文件配置&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;下面是默认的 .env 文件配置&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;# You can find documentation for all the supported env variables at https://docs.immich.app/install/environment-variables&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;# The location where your uploaded files are stored&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;UPLOAD_LOCATION=./library&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;# The location where your database files are stored. Network shares are not supported for the database&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;DB_DATA_LOCATION=./postgres&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;/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;# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List&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;# TZ=Etc/UTC&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;/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;# The Immich version to use. You can pin this to a specific version like &quot;v2.1.0&quot;&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;IMMICH_VERSION=v2&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;# Connection secret for postgres. You should change it to a random password&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;# Please use only the characters `A-Za-z0-9`, without special characters or spaces&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;DB_PASSWORD=postgres&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;/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;# The values below this line do not need to be changed&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;/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;DB_USERNAME=postgres&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;DB_DATABASE_NAME=immich&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;ul&gt;
&lt;li&gt;可以替换 &lt;code&gt;UPLOAD_LOCATION&lt;/code&gt; 的值为你想要用于存放备份数据的位置，请填写绝对路径，并且需要是一个新目录，有充足的空间。&lt;/li&gt;
&lt;li&gt;可以考虑修改 &lt;code&gt;DB_PASSWORD&lt;/code&gt; 值，Postgres并不会公开暴露，因此该密码仅用于本地验证。为避免与 Docker 冲突，密码最好仅使用&lt;code&gt;A-Za-z0-9&lt;/code&gt;的这些字符。&lt;/li&gt;
&lt;li&gt;取消  &lt;code&gt;TZ=&lt;/code&gt; 行的注释即可自定义你的时区。&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;修改 docker -compose .yml 文件&lt;a href=&quot;#修改-docker--compose-yml-文件&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;由于 Fedora 的 SELinux 限制，我们还需要额外修改一下 &lt;code&gt;docker-compose.yml&lt;/code&gt; 文件，即在每个 &lt;code&gt;volume&lt;/code&gt; 值的后方加上 &lt;code&gt;:Z&lt;/code&gt;，这一步是为了让 Fedora 的 SELinux 不再拦截。&lt;/p&gt;&lt;p&gt;注意：timezone 不需要添加 &lt;code&gt;:Z&lt;/code&gt;&lt;/p&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;启动 Immich&lt;a href=&quot;#启动-immich&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在文件夹中打开终端，运行下方命令即可以后台服务的形式启动 Immich！&lt;/p&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;podman-compose up -d&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;如果一切正常，那么恭喜你，已经成功的在 Fedora 上运行了 Immich，接下来在浏览器中访问 localhost&amp;lt;2283&amp;gt; 即可开始配置 Immich，快去体验吧！&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>神了，中国移动也做加速器！</title><link>https://blog.gucrin.top/posts/cmccacc/%E5%B0%8F%E4%BC%97%E5%8A%A0%E9%80%9F%E5%99%A8%E6%8E%A8%E8%8D%90--%E4%B8%AD%E5%9B%BD%E7%A7%BB%E5%8A%A8%E5%8A%A0%E9%80%9F%E5%99%A8/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/cmccacc/%E5%B0%8F%E4%BC%97%E5%8A%A0%E9%80%9F%E5%99%A8%E6%8E%A8%E8%8D%90--%E4%B8%AD%E5%9B%BD%E7%A7%BB%E5%8A%A8%E5%8A%A0%E9%80%9F%E5%99%A8/</guid><description>真的是很小众的加速器了</description><pubDate>Sun, 22 Feb 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;大家好呀ヾ(＾-＾)ﾉ 这里是 Gucrin，今天打算给大家推荐一下我自己一直在用的加速器~&lt;/p&gt;&lt;p&gt;铛铛铛铛~ 它就是 —— 中国移动加速器！
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;中国移动场景化宽带&quot; loading=&quot;lazy&quot; width=&quot;1898&quot; height=&quot;1038&quot; src=&quot;/_astro/guanwang.DFjyqOP3_ZjyKQ4.webp&quot; /&gt;&lt;figcaption&gt;中国移动场景化宽带&lt;/figcaption&gt;&lt;/figure&gt;
这里把官网链接贴一下：&lt;a href=&quot;https://aifast.komect.com/&quot; target=&quot;_blank&quot;&gt;中国移动场景化宽带&lt;/a&gt;&lt;p&gt;&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;/p&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;UI
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;主界面&quot; loading=&quot;lazy&quot; width=&quot;1232&quot; height=&quot;704&quot; src=&quot;/_astro/ui.C1IKwank_ZavlOW.webp&quot; /&gt;&lt;figcaption&gt;主界面&lt;/figcaption&gt;&lt;/figure&gt;
可以看到软件 UI 还是挺简洁的，没有广告。对我来说下方的 Banner 是公告区，不算广告 不过缺点是有点老气，而且没有很多动画，用起来有点卡顿。&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;加速效果稳定
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;节点列表&quot; loading=&quot;lazy&quot; width=&quot;684&quot; height=&quot;422&quot; src=&quot;/_astro/jiedian.O0bsHIDf_Z2nYtRt.webp&quot; /&gt;&lt;figcaption&gt;节点列表&lt;/figcaption&gt;&lt;/figure&gt;
中国移动作为三大运营商之一，线路质量是很稳定有保障的，我平时主玩 PUBG，延迟能稳定在 50ms 以下，游戏体验很不错。而且线路是三网都有的，也就是移动联通电信都有加速线路~&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;价格便宜
这里需要重点提一下了，也是我推荐的前提，你需要有一条中国移动的宽带，才能办理 3 元/月的游戏加速服务，不然原价订阅的话是 20 元/月，挺贵的。
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;套餐价格&quot; loading=&quot;lazy&quot; width=&quot;808&quot; height=&quot;507&quot; src=&quot;/_astro/jiage.Db6IcNdo_Z1bbyIH.webp&quot; /&gt;&lt;figcaption&gt;套餐价格&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&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;总结下来，还是因为便宜我才推荐的 hhh，只要 3 元每月，加速时长不限，而且加速游戏支持的也很多，总之有移动宽带的值得推荐🤓&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>新年快乐🎉</title><link>https://blog.gucrin.top/posts/new-year/happynewyear/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/new-year/happynewyear/</guid><description>这是本博客创建以来过的第一次新年！</description><pubDate>Tue, 17 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;liuyi 在这里祝大家新年快乐，天天开心，吃嘛嘛香，身体健康~
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;新年好！&quot; loading=&quot;lazy&quot; width=&quot;2160&quot; height=&quot;1620&quot; src=&quot;/_astro/asaki1.BFL3rDFa_2uHYqW.webp&quot; /&gt;&lt;figcaption&gt;新年好！&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title>给你的语音服务器加点乐趣ฅ՞•ﻌ•՞ฅ — 部署 TS3 音乐机器人</title><link>https://blog.gucrin.top/posts/ts3-audio-bot/ts3-audio-bot/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/ts3-audio-bot/ts3-audio-bot/</guid><description>这里也能网抑云😵‍💫</description><pubDate>Mon, 16 Feb 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;部署好了 TeamSpeak 服务器，本着折腾精神，同时也可以为服务器增添点乐趣，我找到了这个项目&lt;/p&gt;&lt;a href=&quot;https://github.com/ZHANGTIANYAO1/TS3AudioBot-NetEaseCloudmusic-plugin&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;ZHANGTIANYAO1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;TS3AudioBot-NetEaseCloudmusic-plugin&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;这是一个用C#给TS3AudioBot编写网易云插件,让你的TS可以有一个音乐机器人。如果觉得好的话，还请给个星星支持一下&lt;/div&gt;&lt;div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;OSL-3.0&lt;/div&gt;&lt;span&gt;C#&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;p&gt;这是 &lt;a href=&quot;https://github.com/Splamy/TS3AudioBot&quot; target=&quot;_blank&quot;&gt;TS3AudioBot&lt;/a&gt; 的网易云插件版本，提供了对网易云音乐的支持，也就是说服务器内的成员可以点歌♫(/^^)/♫  只要网易有版权的话&lt;/p&gt;&lt;p&gt;还需要部署这个项目 &lt;a href=&quot;https://www.npmjs.com/package/NeteaseCloudMusicApi&quot; target=&quot;_blank&quot;&gt;NeteaseCloudMusicApi&lt;/a&gt; ，这是为了给机器人提供 API 支持，当然你也可以使用公用 API，但我更加推荐自建 API 服务*(・ω・)👉*&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;部署 API&lt;a href=&quot;#部署-api&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;NOTE&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;本文基于 Windows 平台撰写，实际部署时请注意操作系统差异！&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;section&gt;&lt;h3&gt;环境依赖&lt;a href=&quot;#环境依赖&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;在开始部署 API 之前，您需要确保系统满足以下要求：&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Node.js &amp;gt;= 20&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pnpm &amp;gt;= 9&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;&lt;a href=&quot;https://docs-firefly.cuteleaf.cn/guide/get-started/#%E5%AE%89%E8%A3%85-node-js&quot; target=&quot;_blank&quot;&gt;安装 Node.js&lt;/a&gt;&lt;a href=&quot;#安装-nodejs&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;访问 &lt;a href=&quot;https://nodejs.org/&quot; target=&quot;_blank&quot;&gt;Node.js 官网&lt;/a&gt; 下载并安装最新版本的 Node.js。建议使用 LTS 版本。&lt;/p&gt;&lt;p&gt;安装完成后，打开终端或命令提示符，运行以下命令验证 Node.js 是否安装成功：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;node&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&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;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&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;/section&gt;&lt;section&gt;&lt;h3&gt;&lt;a href=&quot;https://docs-firefly.cuteleaf.cn/guide/get-started/#%E5%AE%89%E8%A3%85-pnpm&quot; target=&quot;_blank&quot;&gt;安装 pnpm&lt;/a&gt;&lt;a href=&quot;#安装-pnpm&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;如果您尚未安装 pnpm，可以通过 npm 安装：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;npm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-g&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pnpm&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;安装完成后，打开终端或命令提示符，运行以下命令验证 pnpm 是否安装成功：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;pnpm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&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;/section&gt;&lt;section&gt;&lt;h3&gt;防火墙放行&lt;a href=&quot;#防火墙放行&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;在防火墙开放以下端口以便服务顺利运行&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;9987&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;UDP&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;30033&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TCP&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;10011&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TCP&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;41144&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TCP&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;3000&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TCP+UDP&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;58913&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TCP&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;8000&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;TCP+UDP&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;h3&gt;部署&lt;a href=&quot;#部署&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;新建一个项目文件夹，然后在文件夹里打开 CMD，输入下方命令，开始安装&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;npm&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;NeteaseCloudMusicApi&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;等待安装完成后，在文件夹里编写一个 .bat 脚本，方便后续启动 API 服务&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;npx NeteaseCloudMusicApi&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;运行一下 bat 文件，正常情况下应该可以看到如下输出：&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;Services&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;starts&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;at&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;localhost:3000&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;这样我们的网易云 API 就搭建好啦🎉&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;部署 Bot&lt;a href=&quot;#部署-bot&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;NOTE&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;本文基于 Windows 平台撰写，实际部署时请注意操作系统差异！&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;a href=&quot;https://github.com/ZHANGTIANYAO1/TS3AudioBot-NetEaseCloudmusic-plugin&quot; target=&quot;_blank&quot;&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;ZHANGTIANYAO1&lt;/div&gt;&lt;/div&gt;&lt;div&gt;/&lt;/div&gt;&lt;div&gt;TS3AudioBot-NetEaseCloudmusic-plugin&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;这是一个用C#给TS3AudioBot编写网易云插件,让你的TS可以有一个音乐机器人。如果觉得好的话，还请给个星星支持一下&lt;/div&gt;&lt;div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;—&lt;/div&gt;&lt;div&gt;OSL-3.0&lt;/div&gt;&lt;span&gt;C#&lt;/span&gt;&lt;/div&gt;&lt;/a&gt;&lt;p&gt;点击项目卡片跳转到仓库页面，然后在 releases 页面按照说明下载对应文件，本文使用 3.0.2测试版 - TS3AudioBot_WIN_64.zip 作为演示。&lt;/p&gt;&lt;p&gt;解压文件，然后运行 TS3AudioBot.exe&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;INFO&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt;Core&lt;/span&gt;&lt;span&gt;&lt;span&gt;| [&lt;/span&gt;&lt;span&gt;============&lt;/span&gt;&lt;span&gt; TS3AudioBot started &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;2&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;INFO&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt;Core&lt;/span&gt;&lt;span&gt;| [ Date: Monday, &lt;/span&gt;&lt;span&gt;16&lt;/span&gt;&lt;span&gt; February &lt;/span&gt;&lt;span&gt;2026&lt;/span&gt;&lt;span&gt; 09:31:44&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;INFO|Core| [ Version: 0.12.2/master/4c6be036&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;INFO|Core| [ Build: Release&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;INFO|Core| [ Platform: Windows &lt;/span&gt;&lt;span&gt;6.2.9200.0&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt;bit)&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;INFO|Core| [ Runtime: .NET Framework &lt;/span&gt;&lt;span&gt;3.1.32&lt;/span&gt;&lt;span&gt; ServerGC:True GC:SustainedLowLatency&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;INFO|Core| [ Opus: libopus 1.2.1-fixed (&lt;/span&gt;&lt;span&gt;x64&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;INFO|Core| [&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;INFO|Core| Starting Webserver on port &lt;/span&gt;&lt;span&gt;58913&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;It seems like there are no bots configured.&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;Fill out this quick setup to get started.&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;Please enter the ip, domain or nickname (&lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;9987&lt;/span&gt;&lt;span&gt;) where to connect to:&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;这里是让我们输入 TeamSpeak 服务器的 IP 地址，也支持域名以及昵称，默认连接 9987 端口，输入好之后回车&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;Please&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;enter&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;the&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;server&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;password&lt;/span&gt;&lt;span&gt; (or &lt;/span&gt;&lt;span&gt;leave&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;empty&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;none&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;这里是填写 TeamSpeak 服务器密码，没设置的直接回车即可，设置了的输入好之后回车&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;09:37:58.7697&lt;/span&gt;&lt;span&gt;| &lt;/span&gt;&lt;span&gt;INFO&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt;Core&lt;/span&gt;&lt;span&gt;| &lt;/span&gt;&lt;span&gt;Bot&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;default&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;connecting&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;to&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;localhost:9987&quot;&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;09:37:59.2042&lt;/span&gt;&lt;span&gt;| &lt;/span&gt;&lt;span&gt;INFO&lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt;Core&lt;/span&gt;&lt;span&gt;| &lt;/span&gt;&lt;span&gt;Client&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;connected.&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;看到如上输入就代表着 Bot 已经加入你的服务器了🎉&lt;/p&gt;&lt;section&gt;&lt;h3&gt;接入网易云 API&lt;a href=&quot;#接入网易云-api&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;打开 Bot 文件夹，找到 plugins 文件夹，修改 neteaseApi 参数&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;version&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&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;playMode&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;SeqPlay&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;neteaseApi&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;http://localhost:3000&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;isPrivateFMMode&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&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;isQrlogin&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;false&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;cookieUpdateIntervalMin&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;30&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;autoPause&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;true&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;前面我们本地部署的 API 运行在 &lt;a href=&quot;http://localhost:3000%EF%BC%8C%E5%9B%A0%E6%AD%A4%E6%88%91%E4%BB%AC%E5%B0%B1%E4%BF%AE%E6%94%B9%E4%B8%BA%E6%AD%A4%E5%9C%B0%E5%9D%80%E3%80%82&quot; target=&quot;_blank&quot;&gt;http://localhost:3000，因此我们就修改为此地址。&lt;/a&gt;&lt;/p&gt;&lt;/section&gt;&lt;/section&gt;
&lt;section&gt;&lt;h1&gt;配置 Bot&lt;a href=&quot;#配置-bot&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Bot 默认启动在端口 58913 上，使用云服务器的宝子可以用你服务器的公网 IP 访问这个端口即可看到 Web 配置页面~
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;Web 配置页面示例&quot; loading=&quot;lazy&quot; width=&quot;1903&quot; height=&quot;910&quot; src=&quot;/_astro/web.DyFzIQw5_7Blli.webp&quot; /&gt;&lt;figcaption&gt;Web 配置页面示例&lt;/figcaption&gt;&lt;/figure&gt;
如图所示我们需要填写 Client UID，获取它的方式也很简单，打开 TeamSpeak 客户端，连接到你的服务器，找到刚刚加入频道的 Bot 并发起文字聊天，输入下方指令：&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&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;!&lt;/span&gt;&lt;span&gt;api&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;token&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;然后机器人就会返回一个 Client UID，将这个 UID 填入即可开始配置 Bot 了。&lt;/p&gt;&lt;p&gt;点击 Jump to your Bots overview，然后点击空白图标 其实是设置
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;示例图&quot; loading=&quot;lazy&quot; width=&quot;252&quot; height=&quot;117&quot; src=&quot;/_astro/overview.BypUtsii_Z2cBojl.webp&quot; /&gt;&lt;figcaption&gt;示例图&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;在 Server 选项卡里可以修改 Bot 所在频道以及名称。
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;Server 选项卡示例&quot; loading=&quot;lazy&quot; width=&quot;887&quot; height=&quot;380&quot; src=&quot;/_astro/server.tp3vaERY_87xF7.webp&quot; /&gt;&lt;figcaption&gt;Server 选项卡示例&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Settings 选项卡可以修改服务器地址 密码 频道密码以及机器人音量。
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;Settings 选项卡示例&quot; loading=&quot;lazy&quot; width=&quot;890&quot; height=&quot;506&quot; src=&quot;/_astro/settings.BDChRtdu_p5MzT.webp&quot; /&gt;&lt;figcaption&gt;Settings 选项卡示例&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Playlist 选项卡可以播放本地音乐，如图所示 File Name 处只要填写音频文件的绝对路径即可~
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;Playlist 选项卡示例&quot; loading=&quot;lazy&quot; width=&quot;958&quot; height=&quot;329&quot; src=&quot;/_astro/playlist._Co0WxWz_ZFnHlo.webp&quot; /&gt;&lt;figcaption&gt;Playlist 选项卡示例&lt;/figcaption&gt;&lt;/figure&gt;
例如：C:\Users\Gucrin\Music\NURTURE MEGAMIX.mp3&lt;p&gt;&lt;/p&gt;&lt;section&gt;&lt;h3&gt;登录网易云&lt;a href=&quot;#登录网易云&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;有三种方式可以登录网易云：&lt;/p&gt;&lt;p&gt;二维码登录：(输入指令后扫描机器人头像二维码登录)&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;!yun login netease qr&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;验证码登录：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;!yun login netease sms &amp;lt;手机号&amp;gt; [验证码]&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;先使用 &lt;code&gt;!yun login netease sms &amp;lt;手机号&amp;gt;&lt;/code&gt; 获取验证码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在使用 &lt;code&gt;!yun login netease sms &amp;lt;手机号&amp;gt; &amp;lt;验证码&amp;gt;&lt;/code&gt; 登录&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Cookie登录:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;!yun login netease cookie &amp;lt;Cookie&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/section&gt;&lt;section&gt;&lt;h3&gt;Bot 命令&lt;a href=&quot;#bot-命令&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;先来学习一下命令用法吧&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;命令&lt;/th&gt;&lt;th&gt;命令格式&lt;/th&gt;&lt;th&gt;注释&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;login&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun login &amp;lt;登录方式&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;登录&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;play&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun play &amp;lt;歌单/专辑/歌曲/歌名/歌曲ID&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;播放&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;add&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun add &amp;lt;歌单/专辑/歌曲/歌名/歌曲ID&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;下一首播放&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;next&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun next&lt;/code&gt;&lt;/td&gt;&lt;td&gt;下一首&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;gedan&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun gedan &amp;lt;歌单/歌单名/歌单ID&amp;gt; [长度(max/1-9999)]&lt;/code&gt;&lt;/td&gt;&lt;td&gt;歌单&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;zhuanji&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun gedan &amp;lt;专辑/专辑名/专辑ID&amp;gt; [长度(max/1-9999)]&lt;/code&gt;&lt;/td&gt;&lt;td&gt;专辑&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;mode&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun mode &amp;lt;播放模式&amp;gt;&lt;/code&gt;&lt;/td&gt;&lt;td&gt;播放模式&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;list&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun list&lt;/code&gt;&lt;/td&gt;&lt;td&gt;查看播放列表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;clear&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun clear&lt;/code&gt;&lt;/td&gt;&lt;td&gt;清空播放列表&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;stop&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun stop&lt;/code&gt;&lt;/td&gt;&lt;td&gt;停止播放&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;start&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun start&lt;/code&gt;&lt;/td&gt;&lt;td&gt;开始播放&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;status&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun status&lt;/code&gt;&lt;/td&gt;&lt;td&gt;查看登录状态&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;reload&lt;/td&gt;&lt;td&gt;&lt;code&gt;!yun reload&lt;/code&gt;&lt;/td&gt;&lt;td&gt;重载插件配置&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;播放模式&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;模式&lt;/th&gt;&lt;th&gt;注释&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;&lt;td&gt;顺序播放&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;&lt;td&gt;顺序循环&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;&lt;td&gt;随机播放&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;&lt;td&gt;随机循环&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&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;!yun play Shelter&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;即可播放名为 Shelter 的歌曲&lt;/p&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;&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;点歌成功啦~&quot; loading=&quot;lazy&quot; width=&quot;759&quot; height=&quot;601&quot; src=&quot;/_astro/shelter.2VL5jqCb_Z287UUa.webp&quot; /&gt;&lt;figcaption&gt;点歌成功啦~&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;现在你的点歌机器人可以正常工作啦~ 这次我们使用了两个项目以完成目标，感谢二位项目作者的付出！&lt;/p&gt;&lt;/section&gt;</content:encoded></item><item><title>真的是最好用的语音软件吗 — TeamSpeak 从部署到使用</title><link>https://blog.gucrin.top/posts/teamspeak/teamspeak/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/teamspeak/teamspeak/</guid><description>带你了解最好用的语音软件</description><pubDate>Sun, 15 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&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;前段时间把 MC 小服开起来之后，我和朋友们就开始了愉快的开荒时期。而玩游戏时语音软件是必不可少的，而我，一个喜欢折腾的小女孩，是肯定不会错过这次机会滴，而本次折腾的目标就是… TeamSpeak！&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;TeamSpeak 是一款硬核的实时语音工具。于 2001 年发布。它以&lt;strong&gt;极低延迟&lt;/strong&gt;、&lt;strong&gt;超高语音质量&lt;/strong&gt;和&lt;strong&gt;极低系统占用&lt;/strong&gt;闻名。相较于 Discord （国内的YY、Kook、Oopz 等），TS &lt;strong&gt;无广&lt;/strong&gt;而且&lt;strong&gt;界面简洁&lt;/strong&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;div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;TIP&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;请根据您服务器实际运行的系统选择对应的安装包，本文章基于 Windows 系统讲解！&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;首先前往 &lt;a href=&quot;https://www.teamspeak.com/en/downloads/&quot; target=&quot;_blank&quot;&gt;官网&lt;/a&gt; 下载 Server 端。例如 Windows 平台的 Server 64-bit 3.13.7，下载完成后进行安装即可。&lt;/p&gt;&lt;p&gt;首次启动服务器，应有一个如下图所示的窗口!
&lt;/p&gt;&lt;figure&gt;&lt;img alt=&quot;服务器密钥&quot; loading=&quot;lazy&quot; width=&quot;982&quot; height=&quot;857&quot; src=&quot;/_astro/IMG_20260216_000037.uKnTNkvJ_Z2bhrVq.webp&quot; /&gt;&lt;figcaption&gt;服务器密钥&lt;/figcaption&gt;&lt;/figure&gt;
请 ==一定一定一定保存好 Server Admin Privilege Key== ，这个密钥 ==只会出现这一次== ，后面我们还需要使用它！&lt;p&gt;&lt;/p&gt;&lt;p&gt;接下来回到 TeamSpeak 的客户端，连接上你的服务器，首次连接客户端会提示你输入 Priviledge Key，那我们就把刚刚保存好的 Key 给输入进去，这样你就是这个服务器唯一的管理员了乀(ˉεˉ乀)&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;services&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;teamspeak&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;image&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;teamspeak&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;restart&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;always&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;ports&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;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;9987:9987/udp&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;span&gt;10011:10011&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;span&gt;30033:30033&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;environment&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;TS3SERVER_DB_PLUGIN&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ts3db_mariadb&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;TS3SERVER_DB_SQLCREATEPATH&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;create_mariadb&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;TS3SERVER_DB_HOST&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;db&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;TS3SERVER_DB_USER&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;root&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;TS3SERVER_DB_PASSWORD&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;example&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;TS3SERVER_DB_NAME&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;teamspeak&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;TS3SERVER_DB_WAITUNTILREADY&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;30&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;TS3SERVER_LICENSE&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;accept&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;span&gt;db&lt;/span&gt;&lt;span&gt;:&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;image&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;mariadb&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;restart&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;always&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;environment&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;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;example&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;MYSQL_DATABASE&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;teamspeak&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;🎉恭喜你，属于你自己的 TeamSpeak 服务器已经部署完成！&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;当然是先告诉你的朋友你的 TeamSpeak 服务器的 IP 地址啊，个人推荐绑个域名更好记也更好看一些(&lt;em&gt;/∇＼&lt;/em&gt;)
然后就是根据使用习惯调整软件设置了，TS 的语音设置十分详细各位可以自行摸索一下～&lt;/p&gt;&lt;p&gt;一些小技巧：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;创建分割线可以使用 cspacer0，这样分割线的文本就会居中了&lt;/li&gt;
&lt;li&gt;服务器横幅可以改成固定比例调整大小，这样图片就会根据你的窗口大小来自适应了&lt;/li&gt;
&lt;/ol&gt;&lt;/section&gt;</content:encoded></item><item><title>MC 服务器启动脚本的编写是如何影响玩家联机的</title><link>https://blog.gucrin.top/posts/mc-server/how-to-fix-ipv6-1/</link><guid isPermaLink="true">https://blog.gucrin.top/posts/mc-server/how-to-fix-ipv6-1/</guid><description>解决了玩家无法通过 IPv6 公网访问服务器</description><pubDate>Mon, 09 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;大家好我是 Gucrin，这是本博客的第一篇文章，打算写个简单点的先试试水~&lt;/p&gt;
&lt;section&gt;&lt;h4&gt;事件起因&lt;a href=&quot;#事件起因&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;我用自己组的 NAS 开了个 MC 服务器，邀请了朋友来玩，我们互相之间直接使用游戏客户端开的存档里 &lt;strong&gt;对局域网开放&lt;/strong&gt; 是可以正常联机的。但是朋友无法通过 IPv6 连接到我的服务器，令我百思不得其解🤔&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h4&gt;排查过程&lt;a href=&quot;#排查过程&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;很明显，和网络环境是没有关系的，因为我们之间是可以正常联机，说明问题出在服务器配置方面。于是我询问了 Gemini，得到的回复是:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;即使你系统支持 IPv6，Java 在运行时有时会由于默认设置，优先使用 IPv4 栈（IPv4 Preferred），从而导致它虽然启动了，但根本不理会从 IPv6 进来的握手请求。&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;所以问题就很明显了😉&lt;/p&gt;&lt;/section&gt;
&lt;section&gt;&lt;h4&gt;解决方案&lt;a href=&quot;#解决方案&quot;&gt;&lt;span&gt;#&lt;/span&gt;&lt;/a&gt;&lt;/h4&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;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;off&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;&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;&lt;span&gt;:: &lt;/span&gt;&lt;span&gt;Purpur&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Server&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Startup&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Script&lt;/span&gt;&lt;span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;Modular&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;Fixed&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;==========================================&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;/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;/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;1.&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;JVM&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; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;GC&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;&lt;span&gt; &lt;/span&gt;&lt;span&gt;D&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;/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;set&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;JAVA_OPTS&lt;/span&gt;&lt;span&gt;=-&lt;/span&gt;&lt;span&gt;&lt;span&gt;Xmx4G&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;Xms4G&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;/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;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;UseG1GC&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;ParallelRefProcEnabled&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;MaxGCPauseMillis&lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;200&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;/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;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;UnlockExperimentalVMOptions&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;DisableExplicitGC&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;AlwaysPreTouch&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;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;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;G1NewSizePercent&lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;30&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;G1MaxNewSizePercent&lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;40&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;G1HeapRegionSize&lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;8&lt;/span&gt;&lt;span&gt;M&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;19&lt;/div&gt;&lt;/div&gt;&lt;div&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;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;G1ReservePercent&lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;G1HeapWastePercent&lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;G1MixedGCCountTarget&lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;4&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;21&lt;/div&gt;&lt;/div&gt;&lt;div&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;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;InitiatingHeapOccupancyPercent&lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;15&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;G1MixedGCLiveThresholdPercent&lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;90&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;23&lt;/div&gt;&lt;/div&gt;&lt;div&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;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;G1RSetUpdatingPauseTimePercent&lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;SurvivorRatio&lt;/span&gt;&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;32&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;25&lt;/div&gt;&lt;/div&gt;&lt;div&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;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;PerfDisableSharedMem&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;XX&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;MaxTenuringThreshold&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;&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;/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;&lt;span&gt;Djava&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;net&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;preferIPv4Stack&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;-&lt;/span&gt;&lt;span&gt;&lt;span&gt;Djava&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;net&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;preferIPv6Addresses&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;true&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;/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;/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;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;33&lt;/div&gt;&lt;/div&gt;&lt;div&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;set&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SERVER_JAR&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;purpur&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;1.21&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;11&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;2560.&lt;/span&gt;&lt;span&gt;jar&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;/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;/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;3.&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;39&lt;/div&gt;&lt;/div&gt;&lt;div&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;set&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;SERVER_ARGS&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;nogui&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;/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;4.&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;44&lt;/div&gt;&lt;/div&gt;&lt;div&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;chcp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;65001&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;/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;span&gt;&lt;span&gt;echo&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;48&lt;/div&gt;&lt;/div&gt;&lt;div&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;java&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;JAVA_OPTS&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;jar&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;SERVER_JAR&lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%&lt;/span&gt;&lt;span&gt;SERVER_ARGS&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;/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;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;52&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;pause&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;原理： 强制 Java 允许并优先处理 IPv6 连接，使其行为与客户端联机模块保持一致。&lt;/p&gt;&lt;/section&gt;</content:encoded></item></channel></rss>