<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://moe.best/</id>
  <title type="text">神代綺凛の随波逐流</title>
  <subtitle type="text">神代綺凛的博客</subtitle>
  <updated>2026-10-25T00:00:00.000Z</updated>
  <author><name>神代綺凛</name></author>
  <link rel="alternate" href="https://moe.best/"/>
  <link rel="self" href="https://moe.best/atom.xml"/>
  <generator uri="https://github.com/CuteLeaf/Firefly">Firefly v6.16.8</generator>
    <entry>
      <id>https://moe.best/posts/fgo-event/</id>
      <title type="text">[FGO] 日服活动攻略搬运</title>
      <published>2018-12-31T19:36:00.000Z</published>
      <updated>2020-05-30T03:43:40.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/fgo-event/"/>
      <summary type="text">自动从推特搬运 @niconikon01 制作的 FGO 攻略，如有需要可以收藏此页。</summary>
      <content type="html"><![CDATA[<p>自动从推特搬运 <a href="https://twitter.com/niconikon01" target="_blank">@niconikon01</a> 制作的 FGO 攻略，如有需要可以收藏此页。</p>
<div><div><div></div><div>Note</div></div><div><p>由于博客迁移暂时停止</p></div></div>
<section><h2>攻略制作者收集<a href="#攻略制作者收集"><span>#</span></a></h2><ul>
<li>appmedia - <a href="https://twitter.com/appmediafgo" target="_blank">推特</a>
<a href="https://appmedia.jp/fategrandorder" target="_blank">https://appmedia.jp/fategrandorder</a></li>
<li>gamewith - <a href="https://twitter.com/FGO_GW" target="_blank">推特</a>
<a href="https://gamewith.jp/fgo" target="_blank">https://gamewith.jp/fgo</a></li>
<li>推特上的攻略作者
<a href="https://twitter.com/Siro_gaming1" target="_blank">@Siro_gaming1</a>
<a href="https://twitter.com/FGO0TM" target="_blank">@FGO0TM</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/qq-robot-picfinder/</id>
      <title type="text">[开源] 二次元搜图QQ机器人</title>
      <published>2018-07-13T09:03:00.000Z</published>
      <updated>2022-07-21T02:15:44.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/qq-robot-picfinder/"/>
      <summary type="text">基于 saucenao / ascii2d / whatanime 的搜图机器人</summary>
      <content type="html"><![CDATA[<p><strong>R.I.P. CoolQ</strong></p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=53958266" target="_blank">「第六駆逐隊」/「ふわり」のイラスト [pixiv]</a></p>
<hr />
<p>QQ：<code>*</code></p>
<p>抱歉，因各种复杂的原因，本体已经转为私用，现已不再公开允许加好友或群，有兴趣可自行部署玩耍</p>
<section><h2>开源<a href="#开源"><span>#</span></a></h2><p>项目最初是使用酷Q的易语言 SDK 开发，后使用 Node.js 重写并开源</p><a href="https://github.com/Tsuk1ko/cq-picsearcher-bot" target="_blank"><div><div><div><div></div><div>Tsuk1ko</div></div><div>/</div><div>cq-picsearcher-bot</div></div><div></div></div><div>🤖 基于 saucenao / ascii2d / whatanime 的搜图机器人</div><div><div>—</div><div>—</div><div>GPL-3.0</div><span>JavaScript</span></div></a><p>开源版本不含咬人功能，因为懒得移植了……</p></section>
<section><h2>用法及功能<a href="#用法及功能"><span>#</span></a></h2><p>请见 GitHub README 以及 wiki</p></section>
<section><h2>示例<a href="#示例"><span>#</span></a></h2><section><h3>普通搜图<a href="#普通搜图"><span>#</span></a></h3><img src="/usr/uploads/2019/04/2058400109.jpg" /></section><section><h3>利用 ascii2d 搜索局部图<a href="#利用-ascii2d-搜索局部图"><span>#</span></a></h3><img src="/usr/uploads/2019/04/2704250135.jpg" /></section><section><h3>搜番<a href="#搜番"><span>#</span></a></h3><img src="/usr/uploads/2019/04/2141624122.jpg" /></section><section><h3>搜本子<a href="#搜本子"><span>#</span></a></h3><img src="/usr/uploads/2019/04/3134598854.jpg" /></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/uncategorized/migrate-to-astro/</id>
      <title type="text">博客迁移</title>
      <published>2026-10-25T00:00:00.000Z</published>
      <updated>2026-10-25T00:00:00.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/uncategorized/migrate-to-astro/"/>
      <summary type="text">托 PHP 的福，我把 Typecho 迁移到 Astro 了</summary>
      <content type="html"><![CDATA[<section><h2>突如其来的灾难<a href="#突如其来的灾难"><span>#</span></a></h2><p>前阵子的 PHP 严重 Bug，让我久违的访问了我博客的机器</p><p>不太敢就直接加个缓解配置就继续跑着，索性直接关了</p><p>虽然已经三年没写文章了，博客名存实亡，虽然也是黑历史，但至少也是个回忆，还是想留着</p><p>一查，Typecho 1.1 最高就支持 PHP 7.3，怎么办？升级 Typecho？然后我的旧版 Handsome 主题估计又要遭殃，也不是很想花精力再去修改维护</p><p>最后还是决定直接大搬家，迁移到静态博客，这样后续维护精力和服务器都省了，这也是支撑我做这件事的好理由</p></section>
<section><h2>静态博客框架有挺多的<a href="#静态博客框架有挺多的"><span>#</span></a></h2><p>作为老登，提到静态博客我第一个想到的还是 Hexo，毕竟在我还经常玩博客的时候，就它最出名</p><p>但现在都 2026 年了，肯定有更现代的静态博客框架</p><p>让 AI 查找比较了一番，并且重点考察了下主题生态，最终还是选了 Astro 加上 Firefly 主题</p></section>
<section><h2>迁移是个大工程<a href="#迁移是个大工程"><span>#</span></a></h2><p>我早在两年前就想过迁移到静态博客，但考虑到工作量、原本许多额外的魔改和功能、评论系统等方面，最终都搁置了</p><p>但现在不一样了，我有 Codex，还赶上最近 Tibo 天天发重置，再没有比这个周末更适合做这件事的了</p><p>我把原来博客的数据库、整个博客和主题源码都导了出来，花半小时初始化项目、写好要求，直接 GPT-6 Astra High Fast 开蹬</p><p>结果非常 amazing 啊，只用了 3 个小时就迁移完成了，赶在重置前搞定，并且检查了下没有什么大问题</p><p>之后断断续续花了两天进行了些修改和配置，做了一些小修改，最终也算成功迁移完成了</p></section>
<section><h2>然后<a href="#然后"><span>#</span></a></h2><p>还是有些后遗症的，比如文章链接，由于现有框架不支持旧博客的 url 组织方式，只好按新的来了，接下来还得去配一下重定向规则，或许还得给 Google Search 提交一下网址变更</p><p>以及评论，这个确实是我最不想丢的，我把几千条旧评论都导出来了，到时候看看能不能魔改一下接进去复活一下，虽然只能看，不过也是这个博客为数不多的宝贵财富</p><p>目前博客还没有配评论系统，后面有时间再复活，现在就先凑合看吧（</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/create-a-github-action/</id>
      <title type="text">GitHub Actions 踩坑之——自己造！</title>
      <published>2023-07-17T08:57:00.000Z</published>
      <updated>2023-07-18T04:22:17.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/create-a-github-action/"/>
      <summary type="text">最近闲着研究了下怎么做一个 Action，并且研究了下组合式 Action，挺好玩，但是坑还挺多的</summary>
      <content type="html"><![CDATA[<p>最近闲着研究了下怎么做一个 Action，并且研究了下组合式 Action，挺好玩，但是坑还挺多的</p>
<p>Head Pic: <a href="https://www.pixiv.net/artworks/109993410" target="_blank">#明日方舟 夏天！泳装！和整点薯条 - 八伝的插画 - pixiv</a></p>
<p>提丰真大</p>
<section><h2>背景<a href="#背景"><span>#</span></a></h2><p>最近研究完明日方舟的整个解包流程，于是把我方舟工具箱里数据自动更新的流程都换成了自己解包的流程，其中涉及到检查更新、下载数据等步骤</p><p>这些步骤都有单独的代码放在单独的仓库里，写在 Workflow 里非常繁琐，我需要检出、安装依赖、执行，至少三个步骤，<a href="https://github.com/actions/checkout/issues/197" target="_blank">而且 github 官方的 checkout action 只能检出到工作区内</a>，对工作区有一定污染，于是我想能不能整成 action，直接一个步骤就解决了不是爽多了</p></section>
<section><h2>制作 Action<a href="#制作-action"><span>#</span></a></h2><p>本文默认读者有一定的 GitHub Actions 基础，包括有 GitHub Actions 的使用经验，并多少了解 GitHub Workflow 的配置语法</p><section><h3>1. 适配 Action<a href="#1-适配-action"><span>#</span></a></h3><p>做成 Action 的一大好处就是可以直接从 Action 接收参数，而不用自己去处理命令行参数或环境变量等，引入 GitHub 官方的 <a href="https://github.com/actions/toolkit/tree/main/packages/core" target="_blank">@actions/core</a> 即可，这里有一切你想要的功能</p><p>另外我们还需要编写 <code>action.yml</code>，用于声明这个 Action 的输入和输出等，具体可以直接看官方文档 <a href="https://docs.github.com/zh/actions/creating-actions/metadata-syntax-for-github-actions" target="_blank">GitHub Actions 的元数据语法</a></p></section><section><h3>2. 编译<a href="#2-编译"><span>#</span></a></h3><p>我这都是 js 或 ts 的项目，编译方面首推 <a href="https://github.com/vercel/ncc" target="_blank">vercel/ncc</a>，这是一个零配置编译工具，并且 cjs mjs ts 都可用，很方便，一行命令即可生成产物</p></section><section><h3>3. 发布<a href="#3-发布"><span>#</span></a></h3><p>一个 Action 并不需要发布到 GitHub Marketplace 中才能被使用，你可以将它发布到一个单独的分支，甚至在分支的某个文件夹中</p><p>我个人比较推荐直接发布到单独的分支中</p><p>如果你在编写对外的 Action，需要版本管理，那么我推荐使用 <a href="https://github.com/JasonEtco/build-and-tag-action" target="_blank">JasonEtco/build-and-tag-action</a></p><p>由于我这个场景不需要，所以直接简单粗暴使用 <a href="https://github.com/casperdcl/push-dir" target="_blank">casperdcl/push-dir</a> 即可</p><p>以下是用于发布的 Workflow 示例</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>name: Publish</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>on:</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>workflow_dispatch:</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>push:</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>branches:</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>- main</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>jobs:</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>build:</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>runs-on: ubuntu-latest</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>steps:</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>- name: Checkout</span></div></div><div><div><div>14</div></div><div><span><span>        </span></span><span>uses: actions/checkout@v3</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>- name: Install dependencies</span></div></div><div><div><div>16</div></div><div><span><span>        </span></span><span>run: yarn install --frozen-lockfile</span></div></div><div><div><div>17</div></div><div><span><span>      </span></span><span>- name: Build</span></div></div><div><div><div>18</div></div><div><span><span>        </span></span><span>run: yarn build</span></div></div><div><div><div>19</div></div><div><span><span>      </span></span><span>- name: Push dist</span></div></div><div><div><div>20</div></div><div><span><span>        </span></span><span>uses: casperdcl/push-dir@v1</span></div></div><div><div><div>21</div></div><div><span><span>        </span></span><span>with:</span></div></div><div><div><div>22</div></div><div><span><span>          </span></span><span>message: ${{ github.sha }}</span></div></div><div><div><div>23</div></div><div><span><span>          </span></span><span>branch: dist</span></div></div><div><div><div>24</div></div><div><span><span>          </span></span><span>dir: build</span></div></div><div><div><div>25</div></div><div><span><span>          </span></span><span>history: false</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>其中 npm 的 build 脚本为</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ncc</span><span> </span><span>build</span><span> </span><span>src/index.mjs</span><span> </span><span>-o</span><span> </span><span>build/dist</span><span> </span><span>--target</span><span> </span><span>es2022</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>编译完成后目录结构</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>build</span></div></div><div><div><div>2</div></div><div><span>├── action.yml</span></div></div><div><div><div>3</div></div><div><span>└── dist</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>└── index.mjs</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>action.yml</code> 中指定的入口文件为 <code>dist/index.mjs</code></p><p>该 Workflow 会将 build 文件夹内的内容推送到 dist 分支，后续我们就可以在其他项目的 Workflow 中使用该 Action 了</p></section><section><h3>4. 使用自制 Action<a href="#4-使用自制-action"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>steps:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span># 使用某个分支</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>- uses: user/repo@branch</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span># 使用某个分支的某个文件夹</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>- uses: user/repo/folder@branch</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>分支是必须的，即使适用的是默认分支也必须加上 <code>@branch</code></p><p>如果你的 Action 在私有仓库中，那么需要注意：私有 Action 只能被<strong>同一用户/组织</strong>的<strong>私有仓库</strong>使用</p><p>也就是说，私有 Action 是不能直接在公有仓库中使用的，不同用户/组织间的私有 Action 也不能在私有仓库中使用，可能是为了安全规定的，但我觉得挺蠢就是了……（但给钱买企业版的话可以在组织内转为内部仓库来解决这个问题，但是要给钱）</p><p>不过有方法绕过，后面讲</p><p>并且私有 Action 需要经过设置才能被使用，具体进入仓库 Settings - Actions - General - Access，选择第二项</p><p><img src="/usr/uploads/2023/07/4014797867.png" alt="" /></p><p>如果你一定要在公有仓库中使用私有 Action，或者跨用户/组织在私有仓库中使用私有 Action，那么有个办法就是先 clone 过来再本地运行</p><p>没错，GitHub Workflow 支持执行本地的 Action，但你需要准备一个 access token 用来检出其他仓库，Workflow 自带的 token 只有本仓库的读写权限</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>steps:</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>- uses: actions/checkout@v3</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>with:</span></div></div><div><div><div>4</div></div><div><span><span>      </span></span><span>repository: user/repo</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>ref: branch</span></div></div><div><div><div>6</div></div><div><span><span>      </span></span><span>path: ./some/path</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>token: ${{ secrets.YOUR_GITHUB_TOKEN }}</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>- uses: ./some/path</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这里有一点需要注意，执行本地 Action 必须在工作区内，也就是说你没办法自行使用 git clone 某个 repo 到工作区外的某个文件夹然后 uses 一个绝对路径或 <code>..</code> 开头的相对路径</p></section></section>
<section><h2>组合操作 (Composite Action)<a href="#组合操作-composite-action"><span>#</span></a></h2><p>组合操作，顾名思义，可以将多个步骤组合成一个可复用的 Action，可以在一定程度上简化 Workflow</p><section><h3>1. 创建组合操作<a href="#1-创建组合操作"><span>#</span></a></h3><p>也是创建一个 <code>action.yml</code> 文件，元数据方面跟普通 Action 区别不大，只有 runs 配置有区别</p><p>组合操作的 <code>runs.using</code> 必须为 <code>composite</code>，并且需要提供 <code>runs.steps</code> 配置，跟 Workflow 的 steps 是基本一样的，具体可看官方文档 <a href="https://docs.github.com/zh/actions/creating-actions/creating-a-composite-action" target="_blank">创建组合操作</a></p><p>特别地，组合操作可以通过 <code>github.action_path</code> 上下文获得操作的根目录</p></section><section><h3>2. 使用组合操作<a href="#2-使用组合操作"><span>#</span></a></h3><p>你可以将组合操作的 action.yml 放在一个仓库里 clone 下来本地执行，也可以跟一般操作一样直接以 <code>uses: user/repo@branch</code> 的形式使用</p></section></section>
<section><h2>一些注意点<a href="#一些注意点"><span>#</span></a></h2><ol>
<li>uses 必须是确定的，不可是动态的</li>
<li>uses 本地操作不能位于工作区之外</li>
</ol></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/revolt/</id>
      <title type="text">Revolt 搭建指南</title>
      <published>2022-01-29T12:08:00.000Z</published>
      <updated>2022-02-09T06:45:22.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/revolt/"/>
      <summary type="text">最近开黑啦用户协议的事闹得挺厉害，但据说是从 YY 复制粘贴来的，意思是国内应用是不是都这个德行？我不好评价，所以转头去研究了下 Revolt 搭了个给群友们用。Revolt 是一个开源的类 Discord 社区应用，搭起来坑真是挺多的。年前刚好没什么事，在公司闲着也是闲着，故水文一篇。（时隔两年的新文章……）</summary>
      <content type="html"><![CDATA[<p>最近开黑啦用户协议的事闹得挺厉害，但据说是从 YY 复制粘贴来的，意思是国内应用是不是都这个德行？我不好评价，所以转头去研究了下 Revolt 搭了个给群友们用。Revolt 是一个开源的类 Discord 社区应用，搭起来坑真是挺多的。年前刚好没什么事，在公司闲着也是闲着，故水文一篇。（时隔两年的新文章……）</p>
<p>Head Pic: <a href="https://www.pixiv.net/artworks/95251417" target="_blank">#グランブルーファンタジー シンダラちゃん - ねじろ@FANBOX的插画 - pixiv</a></p>
<hr />
<p>Revolt 是一个开源的类 Discord 社区应用，但毕竟是民间发电，而且项目起步才半年，现阶段跟 Discord 这种商业产品是完全没法比的，未来可期</p>
<p>想搭建的可以试用一下官方 demo 再做决定，因为搭起来还是有点闹心的（特别是语音服务）</p>
<p><a href="https://app.revolt.chat/" target="_blank">https://app.revolt.chat/</a></p>
<section><h2>主体服务搭建<a href="#主体服务搭建"><span>#</span></a></h2><p>Revolt 前后端分离，后端包含非常多的小服务，好在官方提供了 docker 部署方式，不然直接就给劝退了</p><a href="https://github.com/revoltchat/self-hosted" target="_blank"><div><div><div><div></div><div>revoltchat</div></div><div>/</div><div>self-hosted</div></div><div></div></div><div>Deploy Stoat on your own infrastructure!</div><div><div>—</div><div>—</div><div>AGPL-3.0</div><span>JavaScript</span></div></a><p>下面说一下部署和配置细节</p><section><h3>0. 准备工作<a href="#0-准备工作"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/revoltchat/self-hosted</span><span> </span><span>revolt</span><span> </span><span>--depth=1</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>revolt</span></div></div><div><div><div>3</div></div><div><span>cp</span><span> </span><span>.env.example</span><span> </span><span>.env</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后我们需要按自己需要修改 <code>docker-compose.yml</code> 和 <code>.env</code></p></section><section><h3>1. docker compose 配置<a href="#1-docker-compose-配置"><span>#</span></a></h3><p><code>docker-compose.yml</code> 里面可能需要改的东西只有两个</p><p>第一个是端口映射，里面各种服务的 <code>ports</code>，冒号前面的就是映射到本机的端口，按你的需求自行修改</p><p>其中 minio 服务的端口没有在外面被直接使用，都是在 docker 间访问的，因此 minio 的端口是不需要暴露的，直接注释掉都可以</p><p>第二个是 mongodb 的版本，mongodb 5 开始要求 CPU 支持 AVX 指令集，如果你的 CPU 支持就不用管，我是在家里的辣鸡小服务器上搭建的，便宜老U不支持 AVX，因此需要改成使用 mongodb 4，把 image 改成 <code>mongo:4.4.12</code> 即可</p></section><section><h3>2. 环境变量配置<a href="#2-环境变量配置"><span>#</span></a></h3><p>要开始改 <code>.env</code> 了，重头戏，需要配合你最终的 nginx 配置来改，这里我先介绍一下需要改动的配置，nginx 部分我会在下一步说</p><p>开头糊脸的是一堆需要在外部可以访问到的服务 URL 配置（前端会用到这些 URL），默认的配置是直接按端口分的服务，生产环境下我们需要用子域或路径区分服务，通过 nginx 反代到本地端口</p><p>本文示例以子域来区分服务，你也可以用单域名通过路径来区分服务，但后面的 nginx 配置就靠你自己了</p><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># URL to where the Revolt app is publicly accessible (前端)</span></div></div><div><div><div>2</div></div><div><span>REVOLT_APP_URL</span><span>=</span><span>https://example.com</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># URL to where the API is publicly accessible (后端)</span></div></div><div><div><div>5</div></div><div><span>REVOLT_PUBLIC_URL</span><span>=</span><span>https://api.example.com</span></div></div><div><div><div>6</div></div><div><span>VITE_API_URL</span><span>=</span><span>https://api.example.com</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># URL to where the WebSocket server is publicly accessible (后端 WS)</span></div></div><div><div><div>9</div></div><div><span>REVOLT_EXTERNAL_WS_URL</span><span>=</span><span>wss://ws.example.com</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># URL to where Autumn is publicly available (静态资源服务)</span></div></div><div><div><div>12</div></div><div><span>AUTUMN_PUBLIC_URL</span><span>=</span><span>https://autumn.example.com</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span># URL to where January is publicly available (内嵌媒体预览服务)</span></div></div><div><div><div>15</div></div><div><span>JANUARY_PUBLIC_URL</span><span>=</span><span>https://january.example.com</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span># URL to where Vortex is publicly available (语音服务)</span></div></div><div><div><div>18</div></div><div><span>VOSO_PUBLIC_URL</span><span>=</span><span>https://vortex.example.com</span></div></div><div><div><div>19</div></div><div><span>VOSO_WS_HOST</span><span>=</span><span>wss://vortex.example.com</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>最后两条是语音服务相关的，需要额外搭建，后面会讲</p><p>后面重点需要改的有</p><ul>
<li><code>REVOLT_INVITE_ONLY</code>：设置成 <code>1</code> 就只有用邀请码才能注册，为了测试方便可以先维持 <code>0</code>，后面会讲怎么生成邀请码（有点麻烦）</li>
<li><code>REVOLT_VAPID_PRIVATE_KEY</code> &amp; <code>REVOLT_VAPID_PUBLIC_KEY</code>：看说明自行生成</li>
<li><code>VOSO_MANAGE_TOKEN</code>：语音服务用的，直接用脸进行一个键盘的滚即可，后面语音服务配置里的 token 要和这里一样</li>
</ul><p>其他的就是例行按你喜好了，Autumn 相关的不需要动</p></section><section><h3>3. nginx 配置<a href="#3-nginx-配置"><span>#</span></a></h3><p>用其它的 web 服务也行，这里用 nginx 示例，正常的部分该怎么配怎么配</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>map</span><span><span> $</span><span>http_host</span><span> $</span></span><span>revolt_upstream</span><span> {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>example.com http://127.0.0.1:5000;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>api.example.com http://127.0.0.1:8000;</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>ws.example.com http://127.0.0.1:9000;</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>autumn.example.com http://127.0.0.1:3000;</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>january.example.com http://127.0.0.1:7000;</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>vortex.example.com http://127.0.0.1:8080;</span></div></div><div><div><div>8</div></div><div><span>}</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>server</span><span> {</span></div></div><div><div><div>11</div></div><div><span> <span> </span></span><span>listen </span><span>80</span><span>;</span></div></div><div><div><div>12</div></div><div><span> <span> </span></span><span>listen </span><span>443</span><span> ssl http2;</span></div></div><div><div><div>13</div></div><div><span> <span> </span></span><span>server_name </span><span>example.com *.example.com;</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>  </span><span># SSL 自己配</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>  </span><span>if</span><span> ($</span><span>http_upgrade</span><span>) {</span></div></div><div><div><div>18</div></div><div><span>    </span><span># 这里的路径是用来反代 ws 的，脸滚键盘即可，防止和其他服务冲突</span></div></div><div><div><div>19</div></div><div><span>    </span><span>rewrite</span><span> </span><span>^(.*)$</span><span> /ws_78dd759593f041bc970fd7eef8b0c4af$</span><span>1</span><span>;</span></div></div><div><div><div>20</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>  </span><span>location</span><span> / {</span></div></div><div><div><div>23</div></div><div><span>   <span> </span></span><span>proxy_pass </span><span>$</span><span>revolt_upstream</span><span>;</span></div></div><div><div><div>24</div></div><div><span>   <span> </span></span><span>proxy_set_header </span><span>Host $</span><span>host</span><span>;</span></div></div><div><div><div>25</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span>  </span><span>location</span><span> /ws_78dd759593f041bc970fd7eef8b0c4af/ {</span></div></div><div><div><div>28</div></div><div><span>    </span><span># 注意这里的是带尾斜杠的</span></div></div><div><div><div>29</div></div><div><span>   <span> </span></span><span>proxy_pass </span><span>$</span><span>revolt_upstream</span><span>/;</span></div></div><div><div><div>30</div></div><div><span>   <span> </span></span><span>proxy_http_version </span><span>1.1</span><span>;</span></div></div><div><div><div>31</div></div><div><span>   <span> </span></span><span>proxy_set_header </span><span>Host $</span><span>host</span><span>;</span></div></div><div><div><div>32</div></div><div><span>   <span> </span></span><span>proxy_set_header </span><span>Connection $</span><span>http_connection</span><span>;</span></div></div><div><div><div>33</div></div><div><span>   <span> </span></span><span>proxy_set_header </span><span>Upgrade $</span><span>http_upgrade</span><span>;</span></div></div><div><div><div>34</div></div><div><span>    </span><span># 重要，防止 ws 长时间不发送数据导致超时断开</span></div></div><div><div><div>35</div></div><div><span>   <span> </span></span><span>proxy_read_timeout </span><span>24h</span><span>;</span></div></div><div><div><div>36</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>37</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>这里的端口都是 <code>docker-compose.yml</code> 里默认的端口，另外语音服务 vortex 的默认端口是 <code>8080</code>，可以改</p><p>如果模板配置自带对静态资源的正则 location 啥的记得去掉，不然会把匹配抢掉</p></section><section><h3>4. 启动<a href="#4-启动"><span>#</span></a></h3><p>ドキドキ时间到了，启动！</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>该程序没有后台以及超级管理员账户，因此进去后像普通用户一样注册帐号即可，自己对自己创建的频道拥有最高管理权限</p><p>注册是有坑点的，我目前发现的有：</p><ol>
<li>不能用QQ邮箱注册（果然在国外QQ邮箱都被列为垃圾邮箱了吗，不过我在他们的项目里没有找到黑名单之类的东西，估计是后端用了某个库带的规则）</li>
<li>用户名只能英文数字下划线，昵称可以中文，但是没有全局昵称，对每一个频道都得重新设置昵称</li>
</ol><p>停止容器执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>stop</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>销毁容器执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>down</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果要改环境变量的话销毁重建</p></section><section><h3>5. 邀请码生成<a href="#5-邀请码生成"><span>#</span></a></h3><p>解决方案来自 <a href="https://github.com/revoltchat/revolt/discussions/133" target="_blank">revoltchat/revolt#133</a></p><p>简单来说就是你需要手动往数据库里插入邀请码……</p><p>首先进入数据库所在容器</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker-compose</span><span> </span><span>exec</span><span> </span><span>database</span><span> </span><span>bash</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>运行 mongosh，没有的话看后面手动安装</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>mongosh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后往集合里插入邀请码</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>use</span><span> </span><span>revolt</span></span></div></div><div><div><div>2</div></div><div><span><span>db</span><span>.</span></span><span>invites</span><span>.</span><span>insertOne</span><span>({ </span><span>_id</span><span>:</span><span> </span><span>"邀请码"</span><span> })</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>我用的 mongodb 4 的镜像没有 <a href="https://www.mongodb.com/try/download/shell" target="_blank">mongosh</a>，因此我手动安装了</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>update</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>wget</span><span> </span><span>-y</span></div></div><div><div><div>3</div></div><div><span>cd</span><span> </span><span>~</span></div></div><div><div><div>4</div></div><div><span>wget</span><span> </span><span>https://downloads.mongodb.com/compass/mongodb-mongosh_1.1.9_amd64.deb</span></div></div><div><div><div>5</div></div><div><span>dpkg</span><span> </span><span>-i</span><span> </span><span>mongodb-mongosh_1.1.9_amd64.deb</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>语音服务搭建<a href="#语音服务搭建"><span>#</span></a></h2><a href="https://github.com/revoltchat/vortex" target="_blank"><div><div><div><div></div><div>revoltchat</div></div><div>/</div><div>vortex</div></div><div></div></div><div>(in development) Pluggable WebRTC Voice Server</div><div><div>—</div><div>—</div><div>AGPL-3.0</div><span>Rust</span></div></a><section><h3>1. 编译 vortex<a href="#1-编译-vortex"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/revoltchat/vortex</span><span> </span><span>--depth=1</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后修改 <code>Cargo.toml</code>，在最后加上一行 <code>mediasoup-sys = "0.3.2"</code>，不加的话会编译错误</p><p>之后去安装 rust，具体步骤就不写了跟着<a href="https://www.rust-lang.org/zh-CN/tools/install" target="_blank">官网</a>来就行</p><p>开始编译</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cargo</span><span> </span><span>build</span><span> </span><span>--release</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>编译完的可执行文件在 <code>target/release</code> 里面，拿出来即可</p><p>官方在项目里提供了 Dockerfile，但不建议用 docker 跑，因为需要开放非常多的端口供 WebRTC 使用，会有严重的性能问题</p></section><section><h3>2. 启动 vortex<a href="#2-启动-vortex"><span>#</span></a></h3><p>首先需要设置必要的环境变量，环境变量的作用看项目就知道了，下面强调几点</p><ol>
<li><code>WS_URL</code> 和之前的 <code>VOSO_WS_HOST</code> 一致</li>
<li><code>MANAGE_TOKEN</code> 和之前的 <code>VOSO_MANAGE_TOKEN</code> 一致</li>
<li>防火墙记得开放 <code>RTC_MIN_PORT</code> 到 <code>RTC_MAX_PORT</code> 之间的端口号</li>
<li><code>RTC_IPS</code> 的格式是 <code>监听IP,宣告IP</code>，必须是 IP，暂不支持主机名，例如你机器公网 IP 是 <code>1.2.3.4</code>，就填 <code>0.0.0.0,1.2.3.4</code></li>
</ol><p>好了，现在你拥有完全版 revolt 了</p></section></section>
<section><h2>后记<a href="#后记"><span>#</span></a></h2><p>坑挺多的，最坑的一点是 nginx 反代 WS</p><p>我一开始搭建好的时候，不知道为什么语音持续个一两分钟就会莫名断开，一开始我还以为是服务器问题，但换了好几台都有一样的问题，再后来我去试官方的 demo，却也是好的，我不禁开始怀疑是我的问题</p><p>事实证明确实是我的问题，在找朋友一起排查的时候无意中发现语音的 WS 会莫名断开</p><p>得知这一关键信息的我终于确定了方向，Google 得知原来还有 <code>proxy_read_timeout</code> 这一设定</p><p>nginx 的反代默认读超时是 60s，当 WS 空闲超过这个时间后 nginx 就把连接断开了</p><p>API 的 WS 有不停的发心跳包所以幸免于难，但语音的 WS 只有当有人进出或者开闭麦的时候才会传输信息，首当其寄</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/cloudcone/</id>
      <title type="text">[CloudCone] 洛杉矶/KVM/支持支付宝/$2换IP/1Gbps</title>
      <published>2020-06-08T15:31:00.000Z</published>
      <updated>2023-01-23T14:19:47.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/cloudcone/"/>
      <summary type="text">CloudCone 其实是 QuadCone 旗下的子品牌，KVM 虚拟，部署在洛杉矶 Multacom 机房，1Gbps 端口，3TB 流量，支持IPv6，小时计费，支持支付宝，余额可退款，工单服务超级好。</summary>
      <content type="html"><![CDATA[<p>CloudCone 其实是 QuadCone 旗下的子品牌，KVM 虚拟，部署在洛杉矶 Multacom 机房，1Gbps 端口，3TB 流量，支持IPv6，小时计费，支持支付宝，余额可退款，工单服务超级好。</p>
<hr />
<p><a href="https://app.cloudcone.com/?ref=74" target="_blank">官网注册链接</a></p>
<p><a href="http://la.lg.cloudc.one/" target="_blank">Looking Glass</a>（测速、ping、mtr、路由追踪）</p>
<section><h2>个人使用体感<a href="#个人使用体感"><span>#</span></a></h2><p>相当不错，难得一见的高性价比而且网络还不错的服务器，带免费的 DDOS 防护，工单客服态度很好。</p><div><div><div></div><div>Warning</div></div><div><p>IP被墙2刀换一次</p></div></div><p>带有免费的按需 DDoS 防护（还有付费的全天候 DDoS 防护），以及每两周一次的全服务器无差别快照备份，如果有恢复需求可以直接找客服。</p><p>另外，对于<strong>普通实例</strong>，CloudCone 对资源收费是很详细的，分为 CPU、内存、硬盘、IP 四个部分，前三者可以自由定制，额外的公网 IP 需要联系客服申请。</p><p>对于<strong>普通实例</strong>，如果你的服务器处于关机状态，将只收取硬盘以及 IP 的费用，也就是说如果服务器闲置了又不想删掉的话可以关机省钱。（<a href="https://help.cloudcone.com/en-us/article/how-am-i-billed-for-compute-instances-x8afmx/" target="_blank">官方说明</a>）</p></section>
<section><h2>优惠套餐<a href="#优惠套餐"><span>#</span></a></h2><p>注意，如果尚未注册并登录，打开购买链接会跳转至注册帐号页面，注册后即可看到套餐详情</p><section><h3>套餐说明<a href="#套餐说明"><span>#</span></a></h3><ul>
<li><strong>均为 KVM 虚拟化</strong></li>
<li><strong>自动两周一次全服务器备份</strong>
如果有恢复需求请发工单</li>
<li><strong>套餐计费说明</strong>
2020 年 5 月 2 日起，月付套餐和年付套餐扣款时是一次性按月付/年付价格扣费，<strong>前七天按小时计费，如果你在前七天删除机器，会按剩余时间比例退款至你的账户余额，相当于试用期</strong>，但七天后将变为实打实的月付或年付
购买前必须充值足够的余额才能购买</li>
</ul></section><section><h3>附加套件<a href="#附加套件"><span>#</span></a></h3><p>如果需要这些附加套件，发工单申请即可</p><ul>
<li><strong>cPanel 授权：</strong>
每月 $11</li>
<li><strong>高防 IP：</strong>
每月 $2</li>
<li><strong>普通 IP：</strong>
每月 $1</li>
</ul></section></section>
<section><h2>普通可自定义配置价格<a href="#普通可自定义配置价格"><span>#</span></a></h2><p>最低配 3.71刀/月（0.00498刀/小时）
<a href="https://app.cloudcone.com/?ref=74" target="_blank">注册帐号</a> 后即可创建这种自定义实例</p><p><img src="/usr/uploads/2019/01/3800593751.png" alt="" /></p><p>另外还有独立服务器可以购买，XEON X3450、8 GB ECC RAM、2 TB HDD、240 GB SSD、RAID 1，59刀/月起步</p></section>
<section><h2>DNS 服务<a href="#dns-服务"><span>#</span></a></h2><p>CloudCone 提供免费的 DNS 服务，普通用户最多可以托管三个域名进来。</p><p></p><figure><img src="/usr/uploads/2017/11/1796454579.png" alt="DNS" /><figcaption>DNS</figcaption></figure><p></p></section>
<section><h2>CDN 服务<a href="#cdn-服务"><span>#</span></a></h2><p>Cloudcone 也提供 CDN 服务，在 Beta 测试的时候我使用过一个多月，延迟挺低，速度只能说中规中矩，功能超级简单，虽然设置也十分简单就是了……</p><p>用来做普通的静态资源加速还是可以的</p><p>定价的话是<code>$0.045/GB</code></p></section>
<section><h2>网速/性能跑分<a href="#网速性能跑分"><span>#</span></a></h2><p>单核、512MB 内存、10GB 硬盘</p><section><h3>测试 IP<a href="#测试-ip"><span>#</span></a></h3><p>Server Location: Los Angeles, USA
Test IPv4: 173.82.2.222
Test files: <a href="http://la.lg.cloudc.one/100MB.test" target="_blank">http://la.lg.cloudc.one/100MB.test</a></p></section><section><h3>Speedtest<a href="#speedtest"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/11/901353443.png" alt="Speedtest" /><figcaption>Speedtest</figcaption></figure><p></p></section><section><h3>bench.sh<a href="#benchsh"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/11/928525446.png" alt="bench.sh" /><figcaption>bench.sh</figcaption></figure><p></p></section><section><h3>UnixBench<a href="#unixbench"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/11/550842967.png" alt="UnixBench" /><figcaption>UnixBench</figcaption></figure><p></p></section><section><h3>虚拟<a href="#虚拟"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/11/159295295.png" alt="虚拟" /><figcaption>虚拟</figcaption></figure><p></p></section></section>
<section><h2>创建服务器<a href="#创建服务器"><span>#</span></a></h2><p>进去之后右上角直接注册，来到后台右上角绿色的“+”即可创建服务器。</p><p></p><figure><img src="/usr/uploads/2017/11/2930540086.png" alt="创建服务器" /><figcaption>创建服务器</figcaption></figure><p></p><p>可以选择创建普通实例或者专用服务器，而且提供免费的 DNS 服务，这里简单介绍一下普通实例。</p><section><h3>系统选择<a href="#系统选择"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/11/2656747940.png" alt="选择系统" /><figcaption>选择系统</figcaption></figure><p></p><p>提供了多种系统的多个版本可供选择，都是64位，有 CentOS、Debian、Ubuntu、Fedora、Scientific Linux，其中 CentOS 提供带最新内核及 BBR 的版本。</p></section></section>
<section><h2>实例管理<a href="#实例管理"><span>#</span></a></h2><p>创建完之后，初始 root 密码会通过邮件发送给你。</p><p></p><figure><img src="/usr/uploads/2017/11/3723718141.png" alt="实例管理" /><figcaption>实例管理</figcaption></figure><p></p><p>Access 里可以直接重设 root 密码，以防忘记了密码。</p><p>Rebuild 里可以重装系统，没有限制次数什么的，想怎么折腾怎么折腾（。</p><section><h3>关于升级配置<a href="#关于升级配置"><span>#</span></a></h3><p>Resize 里可以变更你的服务器配置，仅限普通自定义配置实例，只能向上升级，变更之后会立即按照新的配置按小时计费。
<strong>不过需要注意的是，如果改变了硬盘大小，那么就需要手动扩容硬盘。</strong></p><p>硬盘扩容不会损失数据，老手如果有十足的把握，可以 fdisk 直接上，而萌新建议直接将你的 IP 和 root 密码发给客服，让他们帮你扩容硬盘，<strong>如果自己手动操作，稍有不慎就可能会丢失你的所有硬盘数据</strong></p><p></p><figure><img src="/usr/uploads/2017/11/1605027509.png" alt="扩容硬盘" /><figcaption>扩容硬盘</figcaption></figure><p></p></section></section>
<section><h2>付款<a href="#付款"><span>#</span></a></h2><p>信用卡支持 VISA、Master、美国运通卡。
你也可以使用 PayPal 付款。</p><div><div><div></div><div>Tip</div></div><div><p>目前已经支持支付宝</p></div></div><p></p><figure><img src="/usr/uploads/2017/11/3321796916.png" alt="信用卡" /><figcaption>信用卡</figcaption></figure><p></p><p></p><figure><img src="/usr/uploads/2017/11/1805178643.png" alt="PayPal" /><figcaption>PayPal</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/cfworker-telegraf-tgbot/</id>
      <title type="text">在 Cloudflare Workers 上部署基于 Telegraf 框架的 Telegram Bot</title>
      <published>2020-04-18T17:07:00.000Z</published>
      <updated>2022-04-29T05:04:54.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/cfworker-telegraf-tgbot/"/>
      <summary type="text">用 serverless 解放你的服务器</summary>
      <content type="html"><![CDATA[<p>用 serverless 解放你的服务器</p>
<p>Head Pic: <a href="https://www.pixiv.net/artworks/80761033" target="_blank">#アークナイツ timeout - Alcxome - pixiv</a></p>
<section><h2>Cloudflare Workers<a href="#cloudflare-workers"><span>#</span></a></h2><p>官网：<a href="https://workers.cloudflare.com/" target="_blank">https://workers.cloudflare.com/</a></p><p>我也不做过多介绍了，可以从官网上了解，简单来说它是个运行 javascript 的 serverless 平台，虽然还说支持 Rust 或者 C 等等，但实际上得将它们编译为 Wasm</p><p>有官方客户端 wrangler，但这客户端 bug 是真的多，请做好各种搜 issue 的准备（</p><p><strong>以下描述针对免费版计划</strong></p><p><strong>为什么值得用：</strong></p><ol>
<li><strong>每天</strong>免费调用<strong>十万</strong>次，超出只会终止而不扣费</li>
<li>最多创建 30 个 worker，管够</li>
<li>赠送一个专门用于调用 worker 的 workers.dev 子域，子域名自定义</li>
<li>可以自定义路由来使用你自己的域名</li>
<li>没有流量限制</li>
<li>可以使用 KV（cf 提供的键值数据库，2020年11月起对免费套餐开放使用了）</li>
</ol><p><strong>局限性：</strong></p><ol>
<li>Serverless 的特性所决定的局限性</li>
<li>每个请求限制 10ms CPU 时间（网络 IO 时间不计），无法完成某些太耗算力的任务，例如较复杂的图片处理或者使用 cheerio 这类效率不高的 HTML 解析库</li>
<li>（目前）不允许使用 websocket</li>
</ol><section><h3>关于 KV<a href="#关于-kv"><span>#</span></a></h3><p>由于免费版套餐也可以白嫖 KV 了，这意味着你可以编写有状态的 bot 逻辑了，但 KV 的写入生效可能存在延迟，并且存在每秒一次（目前）的频率限制，不能与内存相提并论，因此请根据实际情况合理使用</p></section></section>
<section><h2>Telegram Bot<a href="#telegram-bot"><span>#</span></a></h2><p>实现 Telegram Bot 的处理消息有两种方式，长轮询和 webhook，想依靠 serverless 处理则选用 webhook 方式</p><p>注意，webhook 每一次被 tg 服务器调用都只能返回一次，因此没办法做到“等待某条消息发送后再xxxx”，只能一次性发送完所有操作</p><p>我一般用 <a href="https://telegraf.js.org/" target="_blank">Telegraf</a> 框架开发，所以这里主要说下怎么将使用该框架开发的 bot 迁移至 cfworker</p><div><div><div></div><div>Warning</div></div><div><p>下面的内容是对于 Telegraf 3 的，目前已经支持 Telegraf 4，具体使用方法请以 github 项目为准</p></div></div><section><h3>迁移思路<a href="#迁移思路"><span>#</span></a></h3><p>如果只想知道最终该怎么做可以直接跳过这一节</p><p>首先 Telegraf 的文档有说明如何<a href="https://telegraf.js.org/#/?id=webhooks" target="_blank">处理 webhook</a></p><p>我一般使用 cf 官方的框架来开发 cfworker：</p><p><a href="https://www.npmjs.com/package/@cfworker/web" target="_blank">@cfworker/web</a></p><p>这是一个类 Koa 框架，并包含了 Router，但 cfworker 的<code>Request</code>和<code>Response</code>的 API 和 Koa 略有不同，具体可以见<a href="https://developers.cloudflare.com/workers/reference/apis" target="_blank">官方文档</a></p><p>综合考虑决定参考 Telegraf 文档中 Koa 的示例，使用<code>handleUpdate</code>方法来处理 webhook</p><p>这个函数接受两个参数，第一个是 webhook 请求的 payload，也就是<code>JSON.parse</code> body 所得到的内容，这个只要<code>await req.json()</code>就可以得到</p><p>而第二个参数是一个 <a href="https://nodejs.org/api/http.html#http_class_http_serverresponse" target="_blank">http.ServerResponse</a>，但 web-router 的<code>ResponseBuilder</code>由于 API 不同所以不能直接拿来用，需要改造一下</p><p>Telegraf 框架的<a href="https://github.com/telegraf/telegraf/blob/11c3105e69e2878c5979cf54215dd8f3c9960097/core/network/client.js#L183-L220" target="_blank">这段代码</a>作用就是产生 webhook 的应答，因此我从这里入手进行分析</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>isKoaResponse</span><span><span>(</span><span>response</span><span>) {</span></span></div></div><div><div><div>2</div></div><div><span>  </span><span>return</span><span> (</span></div></div><div><div><div>3</div></div><div><span>    </span><span>typeof</span><span><span> </span><span>response</span><span>.</span></span><span>set</span><span> </span><span>===</span><span> </span><span>"function"</span><span> </span><span>&amp;&amp;</span><span> </span><span>typeof</span><span><span> </span><span>response</span><span>.</span></span><span>header</span><span> </span><span>===</span><span> </span><span>"object"</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>);</span></div></div><div><div><div>5</div></div><div><span>}</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>function</span><span> </span><span>answerToWebhook</span><span><span>(</span><span>response</span><span>, </span><span>payload</span><span> </span></span><span>=</span><span><span> {}, </span><span>options</span><span>) {</span></span></div></div><div><div><div>8</div></div><div><span>  </span><span>if</span><span> (</span><span>!</span><span>includesMedia</span><span><span>(</span><span>payload</span><span>)) {</span></span></div></div><div><div><div>9</div></div><div><span>    </span><span>if</span><span> (</span><span>isKoaResponse</span><span><span>(</span><span>response</span><span>)) {</span></span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>response</span><span>.</span><span>body</span><span> </span><span>=</span><span><span> </span><span>payload</span><span>;</span></span></div></div><div><div><div>11</div></div><div><span>      </span><span>return</span><span> </span><span>Promise</span><span>.</span><span>resolve</span><span>(</span><span>WEBHOOK_REPLY_STUB</span><span>);</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>13</div></div><div><span>    </span><span>if</span><span> (</span><span>!</span><span><span>response</span><span>.</span></span><span>headersSent</span><span>) {</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>response</span><span>.</span><span>setHeader</span><span>(</span><span>"content-type"</span><span>, </span><span>"application/json"</span><span>);</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>16</div></div><div><span>    </span><span>return</span><span> </span><span>new</span><span> </span><span>Promise</span><span><span>((</span><span>resolve</span><span>) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>17</div></div><div><span>      </span><span>if</span><span><span> (</span><span>response</span><span>.</span></span><span>end</span><span>.</span><span>length</span><span> </span><span>===</span><span> </span><span>2</span><span>) {</span></div></div><div><div><div>18</div></div><div><span><span>        </span></span><span>response</span><span>.</span><span>end</span><span>(</span><span>JSON</span><span>.</span><span>stringify</span><span><span>(</span><span>payload</span><span>), </span></span><span>"utf-8"</span><span>);</span></div></div><div><div><div>19</div></div><div><span>        </span><span>return</span><span> </span><span>resolve</span><span>(</span><span>WEBHOOK_REPLY_STUB</span><span>);</span></div></div><div><div><div>20</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>21</div></div><div><span><span>      </span></span><span>response</span><span>.</span><span>end</span><span>(</span><span>JSON</span><span>.</span><span>stringify</span><span><span>(</span><span>payload</span><span>), </span></span><span>"utf-8"</span><span>, () </span><span>=&gt;</span></div></div><div><div><div>22</div></div><div><span>        </span><span>resolve</span><span>(</span><span>WEBHOOK_REPLY_STUB</span><span>),</span></div></div><div><div><div>23</div></div><div><span><span>      </span></span><span>);</span></div></div><div><div><div>24</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>25</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span>  </span><span>return</span><span> </span><span>buildFormDataConfig</span><span><span>(</span><span>payload</span><span>, </span><span>options</span><span>.</span></span><span>agent</span><span>).</span><span>then</span><span>(</span></div></div><div><div><div>28</div></div><div><span><span>    </span></span><span>({ </span><span>headers</span><span>, </span><span>body</span><span> }) </span><span>=&gt;</span><span> {</span></div></div><div><div><div>29</div></div><div><span>      </span><span>if</span><span> (</span><span>isKoaResponse</span><span><span>(</span><span>response</span><span>)) {</span></span></div></div><div><div><div>30</div></div><div><span><span>        </span></span><span>Object</span><span>.</span><span>keys</span><span><span>(</span><span>headers</span><span>).</span></span><span>forEach</span><span><span>((</span><span>key</span><span>) </span></span><span>=&gt;</span><span><span> </span><span>response</span><span>.</span></span><span>set</span><span><span>(</span><span>key</span><span>, </span><span>headers</span><span>[</span><span>key</span><span>]));</span></span></div></div><div><div><div>31</div></div><div><span><span>        </span></span><span>response</span><span>.</span><span>body</span><span> </span><span>=</span><span><span> </span><span>body</span><span>;</span></span></div></div><div><div><div>32</div></div><div><span>        </span><span>return</span><span> </span><span>Promise</span><span>.</span><span>resolve</span><span>(</span><span>WEBHOOK_REPLY_STUB</span><span>);</span></div></div><div><div><div>33</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>34</div></div><div><span>      </span><span>if</span><span> (</span><span>!</span><span><span>response</span><span>.</span></span><span>headersSent</span><span>) {</span></div></div><div><div><div>35</div></div><div><span><span>        </span></span><span>Object</span><span>.</span><span>keys</span><span><span>(</span><span>headers</span><span>).</span></span><span>forEach</span><span><span>((</span><span>key</span><span>) </span></span><span>=&gt;</span></div></div><div><div><div>36</div></div><div><span><span>          </span></span><span>response</span><span>.</span><span>setHeader</span><span><span>(</span><span>key</span><span>, </span><span>headers</span><span>[</span><span>key</span><span>]),</span></span></div></div><div><div><div>37</div></div><div><span><span>        </span></span><span>);</span></div></div><div><div><div>38</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>39</div></div><div><span>      </span><span>return</span><span> </span><span>new</span><span> </span><span>Promise</span><span><span>((</span><span>resolve</span><span>) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>40</div></div><div><span><span>        </span></span><span>response</span><span>.</span><span>on</span><span>(</span><span>"finish"</span><span>, () </span><span>=&gt;</span><span> </span><span>resolve</span><span>(</span><span>WEBHOOK_REPLY_STUB</span><span>));</span></div></div><div><div><div>41</div></div><div><span><span>        </span></span><span>body</span><span>.</span><span>pipe</span><span><span>(</span><span>response</span><span>);</span></span></div></div><div><div><div>42</div></div><div><span><span>      </span></span><span>});</span></div></div><div><div><div>43</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>44</div></div><div><span><span>  </span></span><span>);</span></div></div><div><div><div>45</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>根据 cfworker 中<code>Response</code>的 API，其<code>body</code>是支持被赋值<code>Stream</code>的，因此向 KoaResponse 靠拢会比较好处理，不需要考虑 pipe 的问题</p><p>那么就需要使<code>isKoaResponse(response)</code>为<code>true</code>，根据这段代码我们需要对 web-router 的<code>ResponseBuilder</code>做的适配有以下几点：</p><ol>
<li>实现<code>set()</code>函数，用于设置 header</li>
<li>有<code>header</code>属性且为<code>Object</code>，由于没有实际使用所以随便糊弄也可以</li>
<li><code>body</code>支持被赋值一个<code>Object</code>（但<code>Array</code>最好也考虑进去，与 Koa API 一致），相当于构造一个 JSON Response</li>
</ol><p>考虑到第三点，做一个 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy" target="_blank">Proxy</a> 就可以实现</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>getKoaLikeResponse</span><span><span>(</span><span>res</span><span>) {</span></span></div></div><div><div><div>2</div></div><div><span>  </span><span>return</span><span> </span><span>new</span><span> </span><span>Proxy</span><span>(</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>Object</span><span>.</span><span>assign</span><span><span>(</span><span>res</span><span>, {</span></span></div></div><div><div><div>4</div></div><div><span>      </span><span>set</span><span>:</span><span> (</span><span>...</span><span><span>args</span><span>) </span></span><span>=&gt;</span><span><span> </span><span>res</span><span>.</span></span><span>headers</span><span>.</span><span>set</span><span>(</span><span>...</span><span><span>args</span><span>),</span></span></div></div><div><div><div>5</div></div><div><span>      </span><span>header</span><span>:</span><span><span> </span><span>res</span><span>.</span></span><span>headers</span><span>,</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>}),</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>8</div></div><div><span>      </span><span>set</span><span><span>(</span><span>obj</span><span>, </span><span>prop</span><span>, </span><span>value</span><span>) {</span></span></div></div><div><div><div>9</div></div><div><span>        </span><span>if</span><span> (</span></div></div><div><div><div>10</div></div><div><span><span>          </span></span><span>prop</span><span> </span><span>===</span><span> </span><span>"body"</span><span> </span><span>&amp;&amp;</span></div></div><div><div><div>11</div></div><div><span><span>          </span></span><span>[</span><span>"Object"</span><span>, </span><span>"Array"</span><span>].</span><span>includes</span><span>(</span></div></div><div><div><div>12</div></div><div><span><span>            </span></span><span>Object</span><span>.</span><span>getPrototypeOf</span><span><span>(</span><span>value</span><span>).</span></span><span>constructor</span><span>.</span><span>name</span><span>,</span></div></div><div><div><div>13</div></div><div><span><span>          </span></span><span>)</span></div></div><div><div><div>14</div></div><div><span><span>        </span></span><span>) {</span></div></div><div><div><div>15</div></div><div><span><span>          </span></span><span>obj</span><span>.</span><span>body</span><span> </span><span>=</span><span> </span><span>JSON</span><span>.</span><span>stringify</span><span><span>(</span><span>value</span><span>);</span></span></div></div><div><div><div>16</div></div><div><span><span>          </span></span><span>obj</span><span>.</span><span>headers</span><span>.</span><span>set</span><span>(</span><span>"content-type"</span><span>, </span><span>"application/json"</span><span>);</span></div></div><div><div><div>17</div></div><div><span>          </span><span>return</span><span> </span><span>true</span><span>;</span></div></div><div><div><div>18</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>19</div></div><div><span>        </span><span>return</span><span><span> </span><span>Reflect</span><span>.</span></span><span>set</span><span>(</span><span>...</span><span>arguments</span><span>);</span></div></div><div><div><div>20</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>22</div></div><div><span><span>  </span></span><span>);</span></div></div><div><div><div>23</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>迁移流程<a href="#迁移流程"><span>#</span></a></h3><p>你可以选择直接使用我写好的模板 <a href="https://github.com/Tsuk1ko/cfworker-telegraf-template" target="_blank">Tsuk1ko/cfworker-telegraf-template</a> 来建仓库，或者是根据下面的步骤自己动手</p><section><h4>0. 安装依赖<a href="#0-安装依赖"><span>#</span></a></h4><p>我将以上解决方案写了个 npm 包，可以直接作为 cfworker 中间件使用</p><a href="https://github.com/Tsuk1ko/cfworker-middware-telegraf" target="_blank"><div><div><div><div></div><div>Tsuk1ko</div></div><div>/</div><div>cfworker-middware-telegraf</div></div><div></div></div><div>Make telegraf (a telegram bot framework) useable in Cloudflare Workers</div><div><div>—</div><div>—</div><div>MIT</div><span>JavaScript</span></div></a><p>在你的新项目中安装这些依赖：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>npm</span><span> </span><span>i</span><span> </span><span>@cfworker/web</span><span> </span><span>cfworker-middware-telegraf</span><span> </span><span>telegraf</span></div></div><div><div><div>2</div></div><div><span>npm</span><span> </span><span>i</span><span> </span><span>-D</span><span> </span><span>webpack</span><span> </span><span>webpack-cli</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>1. 写代码<a href="#1-写代码"><span>#</span></a></h4><p>主入口应该为这样的结构</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> { </span><span>Telegraf</span><span> } </span><span>=</span><span> </span><span>require</span><span>(</span><span>"telegraf"</span><span>);</span></div></div><div><div><div>2</div></div><div><span>const</span><span> { </span><span>Application</span><span>, </span><span>Router</span><span> } </span><span>=</span><span> </span><span>require</span><span>(</span><span>"@cfworker/web"</span><span>);</span></div></div><div><div><div>3</div></div><div><span>const</span><span> </span><span>createTelegrafMiddware</span><span> </span><span>=</span><span> </span><span>require</span><span>(</span><span>"cfworker-middware-telegraf"</span><span>);</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>const</span><span> </span><span>bot</span><span> </span><span>=</span><span> </span><span>new</span><span> </span><span>Telegraf</span><span>(</span><span>"BOT_TOKEN"</span><span>);</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>// 写 bot 逻辑，但不要 bot.launch()</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>const</span><span> </span><span>router</span><span> </span><span>=</span><span> </span><span>new</span><span> </span><span>Router</span><span>();</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>// `/SECRET_PATH` 指的是一个不容易猜到的路径，以防止他人访问你的 webhook</span></div></div><div><div><div>12</div></div><div><span>// 可以滚键盘或者用 UUID 之类的生成，例如 '/d4507ff0-08d1-4160-bad8-1addf587374a'</span></div></div><div><div><div>13</div></div><div><span><span>router</span><span>.</span></span><span>post</span><span>(</span><span>"/SECRET_PATH"</span><span>, </span><span>createTelegrafMiddware</span><span><span>(</span><span>bot</span><span>));</span></span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>new</span><span> </span><span>Application</span><span>().</span><span>use</span><span><span>(</span><span>router</span><span>.</span></span><span>middleware</span><span>).</span><span>listen</span><span>();</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>所以很简单，把这段代码抄走然后补上你的 bot 逻辑即可</p><p>顺带一提，cfworker 支持设置 secret，它们会成为代码中的全局变量，所以像<code>TG_BOT_TOKEN</code>和<code>SECRET_PATH</code>这类不宜写入代码的变量可以直接设置成 secret</p></section><section><h4>2. webpack<a href="#2-webpack"><span>#</span></a></h4><p>要在 cfworker 上运行需要 webpack 一下，把依赖全打进一个文件中，然后……粗暴的复制粘贴到 cfworker 编辑器中保存就行</p><p>当然你也可以用 wrangler，可通过配置实现自动 webpack 并部署</p><p>下面是一份示例配置</p><div><div><div><figure><figcaption><span>webpack.config.js</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>module</span><span>.</span><span>exports</span><span> </span><span>=</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>target</span><span>:</span><span> </span><span>"webworker"</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>entry</span><span>:</span><span> </span><span>"./index.js"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>  </span><span>mode</span><span>:</span><span> </span><span>"production"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>  </span><span>node</span><span>:</span><span> {</span></div></div><div><div><div>6</div></div><div><span>    </span><span>fs</span><span>:</span><span> </span><span>"empty"</span><span>,</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>8</div></div><div><span>  </span><span>module</span><span>:</span><span> {</span></div></div><div><div><div>9</div></div><div><span>    </span><span>rules</span><span>:</span><span> [</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>{</span></div></div><div><div><div>11</div></div><div><span>        </span><span>test</span><span>:</span><span><span> /</span><span>\.</span><span>mjs</span></span><span>$</span><span>/</span><span>,</span></div></div><div><div><div>12</div></div><div><span>        </span><span>include</span><span>:</span><span> /node_modules/</span><span>,</span></div></div><div><div><div>13</div></div><div><span>        </span><span>type</span><span>:</span><span> </span><span>"javascript/auto"</span><span>,</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>],</span></div></div><div><div><div>16</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>17</div></div><div><span>};</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>至于其中的 node 配置是干嘛的，你可以看 <a href="https://webpack.docschina.org/configuration/node/" target="_blank">webpack 文档</a></p><p>如果在打包时出现找不到模块错误，就说明你的依赖中用到了 webworker 不支持的 node 模块或全局变量，需要配置上面所说的 node</p><p>如果代码实际运行时不会用到这些模块或全局变量，则 empty 就可以解决；如果实际用到则需要尝试 webpack 提供的 polyfill 或 mock，如果仍无法正常执行那就只能放弃使用该依赖了</p></section><section><h4>3. 设置 webhook<a href="#3-设置-webhook"><span>#</span></a></h4><p>接着我们设置 bot 的 webhook，另起一个 js 在本地执行一下即可</p><p>只用执行一次即可，这段不需要放进 bot 代码中</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> </span><span>Telegraf</span><span> </span><span>=</span><span> </span><span>require</span><span>(</span><span>"telegraf"</span><span>);</span></div></div><div><div><div>2</div></div><div><span>const</span><span> </span><span>bot</span><span> </span><span>=</span><span> </span><span>new</span><span> </span><span>Telegraf</span><span>(</span><span>TG_BOT_TOKEN</span><span>);</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>// 设置 webhook，请改成你自己的回调地址</span></div></div><div><div><div>5</div></div><div><span><span>bot</span><span>.</span></span><span>telegram</span><span>.</span><span>setWebhook</span><span>(</span><span>"https://name.subdomain.workers.dev/SECRET_PATH"</span><span>);</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>// 删除 webhook</span></div></div><div><div><div>8</div></div><div><span>// bot.telegram.deleteWebhook();</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>// 查看当前 webhook</span></div></div><div><div><div>11</div></div><div><span>// bot.telegram.getWebhookInfo().then(console.log);</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/vue-build-from-specified-config/</id>
      <title type="text">让 Vue 使用指定配置文件进行构建</title>
      <published>2020-03-20T16:33:00.000Z</published>
      <updated>2020-05-03T11:33:53.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/vue-build-from-specified-config/"/>
      <summary type="text">坑</summary>
      <content type="html"><![CDATA[<p>坑</p>
<p>Head Pic: <a href="https://www.pixiv.net/artworks/80245772" target="_blank">#凯尔希 「梦想」 by キョウケン - pixiv</a></p>
<p>在 Vue 项目中，npm script 里通常用<code>vue-cli-service build</code>来构建成品，该命令默认会使用<code>vue.config.js</code>作为配置文件</p>
<p>但如果我们有在一个 Vue 项目中使用多个配置文件来构建不同成品的需求，该怎么办</p>
<p>可惜非常不人性化的是，<code>vue-cli-service</code>并没有设计支持使用类似<code>-c configFile</code>这样的参数来指定使用其它配置文件，那么还有其它办法么</p>
<section><h2><code>VUE_CLI_SERVICE_CONFIG_PATH</code>环境变量<a href="#vue_cli_service_config_path环境变量"><span>#</span></a></h2><p>还好，经过搜索，我发现<code>vue-cli-service</code>是支持使用<code>VUE_CLI_SERVICE_CONFIG_PATH</code>环境变量来自定义配置文件的，我们可以添加一个 npm script 像下面这样（Unix 下）</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>VUE_CLI_SERVICE_CONFIG_PATH</span><span>=</span><span>my.vue.config.js</span><span> </span><span>vue-cli-service</span><span> </span><span>build</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然而我实际执行确报错“找不到模块<code>my.vue.config.js</code>”</p><p>看了下<code>vue-cli-service</code>的<a href="https://github.com/vuejs/vue-cli/blob/eaa2b7341f174260f6ebc2345bd8e838f85a2ea3/packages/%40vue/cli-service/lib/Service.js#L301-L326" target="_blank">源码</a>，获取配置文件的部分是这样的</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// In loadUserOptions()</span></div></div><div><div><div>2</div></div><div><span>const</span><span> </span><span>configPath</span><span> </span><span>=</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>process</span><span>.</span><span>env</span><span>.</span><span>VUE_CLI_SERVICE_CONFIG_PATH</span><span> </span><span>||</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>path</span><span>.</span><span>resolve</span><span>(</span><span>this</span><span>.</span><span>context</span><span>, </span><span>"vue.config.js"</span><span>);</span></div></div><div><div><div>5</div></div><div><span>if</span><span><span> (</span><span>fs</span><span>.</span></span><span>existsSync</span><span><span>(</span><span>configPath</span><span>)) {</span></span></div></div><div><div><div>6</div></div><div><span>  </span><span>try</span><span> {</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>fileConfig</span><span> </span><span>=</span><span> </span><span>require</span><span><span>(</span><span>configPath</span><span>);</span></span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>    </span><span>if</span><span> (</span><span>typeof</span><span><span> </span><span>fileConfig</span><span> </span></span><span>===</span><span> </span><span>"function"</span><span>) {</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>fileConfig</span><span> </span><span>=</span><span> </span><span>fileConfig</span><span>();</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>    </span><span>if</span><span> (</span><span>!</span><span><span>fileConfig</span><span> </span></span><span>||</span><span> </span><span>typeof</span><span><span> </span><span>fileConfig</span><span> </span></span><span>!==</span><span> </span><span>"object"</span><span>) {</span></div></div><div><div><div>14</div></div><div><span>      </span><span>error</span><span>(</span></div></div><div><div><div>15</div></div><div><span>        </span><span>`Error loading </span><span>${</span><span>chalk</span><span>.</span><span>bold</span><span>(</span></div></div><div><div><div>16</div></div><div><span>          </span><span>"</span><span>vue.config.js</span><span>"</span><span>,</span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>)</span><span>}</span><span>: should export an object or a function that returns object.`</span><span>,</span></div></div><div><div><div>18</div></div><div><span><span>      </span></span><span>);</span></div></div><div><div><div>19</div></div><div><span><span>      </span></span><span>fileConfig</span><span> </span><span>=</span><span> </span><span>null</span><span>;</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>21</div></div><div><span><span>  </span></span><span>} </span><span>catch</span><span><span> (</span><span>e</span><span>) {</span></span></div></div><div><div><div>22</div></div><div><span>    </span><span>error</span><span>(</span><span>`Error loading </span><span>${</span><span>chalk</span><span>.</span><span>bold</span><span>(</span><span>"</span><span>vue.config.js</span><span>"</span><span>)</span><span>}</span><span>:`</span><span>);</span></div></div><div><div><div>23</div></div><div><span>    </span><span>throw</span><span><span> </span><span>e</span><span>;</span></span></div></div><div><div><div>24</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>25</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>可以看到，<code>configPath</code>会直接取环境变量作为 id 来<code>require</code>，而不会像默认的<code>vue.config.js</code>一样根据上下文来计算绝对路径</p><p>虽然看似非常反人类，但仔细想想也能理解这是出于安全考虑</p><p>那么解决方法就显而易见了，传个绝对路径进去，例如在 Unix 下可以利用<code>$PWD</code>环境变量</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>VUE_CLI_SERVICE_CONFIG_PATH</span><span>=</span><span>$PWD</span><span>/my.vue.config.js</span><span> </span><span>vue-cli-service</span><span> </span><span>build</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>但这衍生出另一个问题，最直接的说，Windows 下没有<code>$PWD</code>，而是<code>%cd%</code>，虽然我们能利用<code>cross-env</code>解决不同操作系统下环境变量设置方式不同的问题，却无法解决 Windows 与 Unix 系统环境变量获取方式不同的问题</p></section>
<section><h2>既然是 node，就用 node 解决<a href="#既然是-node就用-node-解决"><span>#</span></a></h2><p>一拍大腿之后，曲线救国的方案就出来了，我们可以直接用 node 获取配置的绝对路径，然后作为环境变量来执行<code>npm run build</code></p><p>在 node 中执行命令就要请<code>child_process</code>出场了，梳理一下我们的需求：</p><ol>
<li>执行<code>npm run build</code></li>
<li>传入<code>VUE_CLI_SERVICE_CONFIG_PATH</code>环境变量</li>
<li>维持原本的输出形式</li>
</ol><p>阅读其文档，最终我选用 <a href="https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options" target="_blank">spawnSync</a> 方法，相关参数如下</p><p><code>child_process.spawnSync(command[, args][, options])</code></p><ul>
<li><code>command &lt;string&gt;</code> The command to run.</li>
<li><code>args &lt;string[]&gt;</code> List of string arguments.</li>
<li><code>options &lt;Object&gt;</code>
<ul>
<li><code>shell &lt;boolean&gt; | &lt;string&gt;</code> If <code>true</code>, runs <code>command</code> inside of a shell. Uses <code>'/bin/sh'</code> on Unix, and <code>process.env.ComSpec</code> on Windows. A different shell can be specified as a string. See <a href="https://nodejs.org/api/child_process.html#child_process_shell_requirements" target="_blank">Shell Requirements</a> and <a href="https://nodejs.org/api/child_process.html#child_process_default_windows_shell" target="_blank">Default Windows Shell</a>. <strong>Default:</strong> <code>false</code> (no shell).</li>
<li><code>stdio &lt;string&gt; | &lt;Array&gt;</code> Child’s stdio configuration.</li>
<li><code>env &lt;Object&gt;</code> Environment key-value pairs. Default: process.env.</li>
</ul>
</li>
</ul><p>值得说明的是 <a href="https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options" target="_blank">options.stdio</a> 这一参数，其中有一条说明</p><blockquote><p><code>'inherit'</code>: Pass through the corresponding stdio stream to/from the parent process. In the first three positions, this is equivalent to <code>process.stdin</code>, <code>process.stdout</code>, and <code>process.stderr</code>, respectively. In any other position, equivalent to <code>'ignore'</code>.</p></blockquote><p>这正是我们想要的，将子进程的输入输出原封不动的传回给父进程，这样一来体验就与直接执行命令无异（指各种命令行动画和文字颜色这种）</p><p>所以最终我们可以像下面这样写个，比如说<code>myBuild.js</code></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> { </span><span>spawnSync</span><span> } </span><span>=</span><span> </span><span>require</span><span>(</span><span>"child_process"</span><span>);</span></div></div><div><div><div>2</div></div><div><span>const</span><span> { </span><span>resolve</span><span> } </span><span>=</span><span> </span><span>require</span><span>(</span><span>"path"</span><span>);</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>spawnSync</span><span>(</span><span>"npm"</span><span>, [</span><span>"run"</span><span>, </span><span>"build"</span><span>], {</span></div></div><div><div><div>5</div></div><div><span>  </span><span>shell</span><span>:</span><span> </span><span>true</span><span>,</span></div></div><div><div><div>6</div></div><div><span>  </span><span>env</span><span>:</span><span> {</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>...</span><span><span>process</span><span>.</span></span><span>env</span><span>, </span><span>// 要记得导入原本的环境变量</span></div></div><div><div><div>8</div></div><div><span>    </span><span>VUE_CLI_SERVICE_CONFIG_PATH</span><span>:</span><span> </span><span>resolve</span><span><span>(</span><span>__dirname</span><span>, </span></span><span>"my.vue.config.js"</span><span>),</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>10</div></div><div><span>  </span><span>stdio</span><span>:</span><span> </span><span>"inherit"</span><span>,</span></div></div><div><div><div>11</div></div><div><span>});</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后我们就可以添加一个 npm script 了，<code>"build:my": "node myBuild.js"</code></p></section>
<section><h2>拓展<a href="#拓展"><span>#</span></a></h2><p>我们可以做的更通用化一点，接受一个参数来指定配置文件，做到可以写成<code>"build:my": "node build.js my.vue.config.js"</code>这样的效果，这里就不详细说了</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/redis-access-control/</id>
      <title type="text">借助 redis 实现访问控制</title>
      <published>2020-03-16T09:41:00.000Z</published>
      <updated>2020-05-03T16:56:57.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/redis-access-control/"/>
      <summary type="text">轻松做到基于 IP 或用户 ID 等的单位时间内访问频率的限制</summary>
      <content type="html"><![CDATA[<p>轻松做到基于 IP 或用户 ID 等的单位时间内访问频率的限制</p>
<p>Head Pic: <a href="https://www.pixiv.net/artworks/80122598" target="_blank">#明日方舟 双狼 by 卧龙先生的爸爸 - pixiv</a></p>
<p>做开放 API，访问控制防止滥用是相当重要的一部分</p>
<p>我相信世上好人还是多，但不可避免地总会出现那么几个憨憨，普通 WAF 提供的基于 URL 的访问频率限制已经不顶用了，自己拓展又很麻烦</p>
<p>想了想，不如直接用开发 API 的语言写好了，方便、契合度还高</p>
<section><h2>关于 redis<a href="#关于-redis"><span>#</span></a></h2><section><h3>为什么用 redis<a href="#为什么用-redis"><span>#</span></a></h3><p>其实也没有什么特别的理由，只是碰巧想了解学习一下 redis，结果无意间发现 redis 很适合用来做访问记录，主要因为以下两点</p><ol>
<li>支持有序集合 (sorted sets)</li>
<li>可为某个键设置 TTL (time to live)</li>
</ol><p>这两点，无疑为做<strong>单位时间内</strong>的访问频率限制提供了巨大便利</p><p>另外明确一下，此处单位时间指的是<strong>持续时间</strong>而不是自然时间：
例如每天允许访问 1000 次，即从 1 天前的时间点到当前时间点的这段时间内最多允许访问 1000 次，而不是每个自然天中最多允许访问 1000 次，过了 0 点就刷新的那种</p><p>（如果是自然时间那好办了，直接开干就可以，根本用不着 redis）</p></section><section><h3>redis 中的有序集合<a href="#redis-中的有序集合"><span>#</span></a></h3><p>Redis 中的有序集合是 string 类型元素的集合，与一般集合不同的是每个元素都与一个 double 值相关联用于排序，称作 score</p><p>有序集合中的元素不可重复，但 score 可以重复</p></section></section>
<section><h2>思路及实现<a href="#思路及实现"><span>#</span></a></h2><p>以下例子均为 PHP 下的实现，用到 <a href="https://github.com/phpredis/phpredis" target="_blank">phpredis</a> 扩展</p><section><h3>基本思路<a href="#基本思路"><span>#</span></a></h3><p>使用 redis 储存访问记录，当访问者访问时通过判断单位时间内该访问者的访问次数是否超出预订值来决定是否 block</p><section><h4>确定如何储存<a href="#确定如何储存"><span>#</span></a></h4><p>根据对 redis 中有序集合的基础了解，使用它储存访问记录之前我们需要确定三个参数</p><ul>
<li><code>key</code> - 键名</li>
<li><code>score</code> - 用于排序</li>
<li><code>value</code> - 唯一值</li>
</ul><p>想一下，我们是要基于 <strong>IP</strong> 或 <strong>用户 ID</strong>，记录<strong>单位时间</strong>内的<strong>访问行为</strong>，因此可以这么设计</p><ul>
<li><code>key</code> - IP 或用户 ID</li>
<li><code>score</code> - 时间戳</li>
<li><code>value</code> - 一个唯一值，可以理解为请求 ID，也可以包含任何你想记录的信息</li>
</ul><p>由于 score 可以重复，因此我们不需要在意时间戳的单位，秒还是毫秒还是微秒都无所谓，只需要保证 value 不重复即可</p><p>正好，PHP 中有一个函数 <a href="https://www.php.net/manual/zh/function.uniqid.php" target="_blank">uniqid</a>，作用是生成一个基于当前时间微秒数的<em>几乎</em>唯一的 ID</p><p>* 通过随机前缀和<code>more_entropy</code>参数可以增加唯一性的概率，足够了，已经可以不用再努力了</p></section><section><h4>确定如何释放<a href="#确定如何释放"><span>#</span></a></h4><p>释放过时的记录是必要的，不然一直存下去内存迟早药丸，虽然也可能等不到这一天就是了（</p><p>此处就轮到 TTL 派上用场了，前面提到过 redis 支持为键设置 TTL，这样就可以在特定时间后自动释放，我们每次要向有序集合内添加新元素时都更新一次 TTL，将其复原至预设值，这样就可以保证活动状态下的数据不会被释放</p><p>但如果一个有序集合一直有数据添加进来怎么办，这样也会越存越多</p><p>好办，只要每次向这个集合添加元素前先删掉所有过期元素就好了</p><p>这样所有过期记录都只有两种下场：在新元素添加进来之前被删除，或因为其所属集合的 TTL 到期而被删除</p></section></section><section><h3>简单实现<a href="#简单实现"><span>#</span></a></h3><p>连接 redis 的步骤均省略</p><section><h4>公共变量<a href="#公共变量"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>$time</span><span><span> </span><span>=</span><span> </span></span><span>time</span><span>();      </span><span>// 当前时间戳（秒）</span></div></div><div><div><div>2</div></div><div><span>$ttl</span><span><span> </span><span>=</span><span> </span></span><span>24</span><span><span> </span><span>*</span><span> </span></span><span>60</span><span><span> </span><span>*</span><span> </span></span><span>60</span><span>;  </span><span>// 一天内</span></div></div><div><div><div>3</div></div><div><span>$key</span><span><span> </span><span>=</span><span> </span></span><span>'IP or User ID'</span><span>;  </span><span>// 这个访问者</span></div></div><div><div><div>4</div></div><div><span>$limit</span><span><span> </span><span>=</span><span> </span></span><span>1000</span><span>;      </span><span>// 最多允许访问 1000 次</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>$line</span><span><span> </span><span>=</span><span> </span></span><span>$time</span><span><span> </span><span>-</span><span> </span></span><span>$ttl</span><span>;  </span><span>// TTL 时间线</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>获取剩余额度信息<a href="#获取剩余额度信息"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// 时间线后的记录数</span></div></div><div><div><div>2</div></div><div><span>$count</span><span><span> </span><span>=</span><span> </span></span><span>$redis</span><span>-&gt;</span><span>zCount</span><span>(</span><span>$key</span><span>, </span><span>$line</span><span>, </span><span>'+inf'</span><span>);</span></div></div><div><div><div>3</div></div><div><span>// 拿到最接近时间线的 score 对应的 value，返回值是数组，没有就是空数组</span></div></div><div><div><div>4</div></div><div><span>$top_value</span><span><span> </span><span>=</span><span> </span></span><span>$redis</span><span>-&gt;</span><span>zRangeByScore</span><span>(</span><span>$key</span><span>, </span><span>$line</span><span>, </span><span>'+inf'</span><span>, [</span><span>'limit'</span><span> =&gt; [</span><span>0</span><span>, </span><span>1</span><span>]]);</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>// 最终要得到的：剩余额度</span></div></div><div><div><div>7</div></div><div><span>$quota</span><span><span> </span><span>=</span><span> </span></span><span>$limit</span><span><span> </span><span>-</span><span> </span></span><span>$count</span><span>;</span></div></div><div><div><div>8</div></div><div><span>// 最终要得到的：额度恢复 1 所需等待的时间，如果没用过就 0</span></div></div><div><div><div>9</div></div><div><span>$quota_ttl</span><span><span> </span><span>=</span><span> </span></span><span>count</span><span>(</span><span>$top_value</span><span><span>) </span><span>&gt;</span><span> </span></span><span>0</span><span><span> </span><span>?</span><span> </span></span><span>$redis</span><span>-&gt;</span><span>zScore</span><span>(</span><span>$key</span><span>, </span><span>$top_value</span><span>[</span><span>0</span><span><span>]) </span><span>+</span><span> </span></span><span>$ttl</span><span><span> </span><span>-</span><span> </span></span><span>$time</span><span><span> </span><span>:</span><span> </span></span><span>0</span><span>;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>记录使用行为<a href="#记录使用行为"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// 清除旧记录</span></div></div><div><div><div>2</div></div><div><span>$redis</span><span>-&gt;</span><span>zRemRangeByScore</span><span>(</span><span>$key</span><span>, </span><span>'-inf'</span><span>, </span><span>$line</span><span>);</span></div></div><div><div><div>3</div></div><div><span>// 记录</span></div></div><div><div><div>4</div></div><div><span>$redis</span><span>-&gt;</span><span>zAdd</span><span>(</span><span>$key</span><span>, </span><span>$time</span><span>, </span><span>uniqid</span><span>(</span><span>''</span><span><span>,</span><span> </span></span><span>true</span><span>));</span></div></div><div><div><div>5</div></div><div><span>// 更新集合的 TTL</span></div></div><div><div><div>6</div></div><div><span>$redis</span><span>-&gt;</span><span>expire</span><span>(</span><span>$key</span><span>, </span><span>$ttl</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h2>后记<a href="#后记"><span>#</span></a></h2><p>拿什么做<code>key</code>是一个需要三思的问题，对于一个固定的访问者用固定的方式访问，它必须也是固定的</p><p>比如，如果你设计了自己的 APIKEY 体系，切忌将 APIKEY 作为<code>key</code>，因为 APIKEY 可能是可变的（取决于你自己的设计），而比较妥善的方法是将 APIKEY 所属的用户的 ID 之类的作为<code>key</code></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/opaque-responses/</id>
      <title type="text">一个由不透明响应引发的灾难</title>
      <published>2019-12-12T10:14:00.000Z</published>
      <updated>2020-02-11T17:19:07.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/opaque-responses/"/>
      <summary type="text">不是应该只有 5MB 的缓存吗，怎么就“DOMException: Quota exceeded.”了？</summary>
      <content type="html"><![CDATA[<p>不是应该只有 5MB 的缓存吗，怎么就“DOMException: Quota exceeded.”了？</p>
<p>Head Pic: <a href="https://www.pixiv.net/artworks/78259001" target="_blank">#アズールレーン 湊 あくあ - 小小男爵不要坑的插画 - pixiv</a></p>
<hr />
<p>不透明响应被 Service Worker 缓存简直就是个灾难</p>
<section><h2>DOMException: Quota exceeded.<a href="#domexception-quota-exceeded"><span>#</span></a></h2><p>我的方舟工具箱一直没有给图片使用 CDN，原因是我在<a href="http://wiki.joyme.com/arknights/" target="_blank">着迷 wiki</a> 中看到的 360 图片 CDN 的域名<code>p&lt;x&gt;.qhimg.com</code>(0&lt;=x&lt;=25)都是不支持 SSL 的，无法被 SW 缓存，所以一直使用项目中独立保存的图片，缓存和加载图片都十分缓慢，这一直是一个令我头疼的地方</p><p>后记：其实可以白嫖 jsDelivr 的……</p><p>而昨天下午我突发奇想搜索了下发现其实是有支持 SSL 的，域名为<code>p&lt;x&gt;.ssl.qhimg.com</code>(0&lt;=x&lt;=6)，这一下我就开心炸了，赶忙写了个 CDN 支持，并使用 <a href="https://developers.google.com/web/tools/workbox" target="_blank">Workbox</a> 做运行时缓存</p><p>发布，测试，然后 BOOM，一气呵成</p><p><img src="/usr/uploads/2019/12/3775254390.png" alt="" /></p><p><img src="/usr/uploads/2020/02/247604030.gif" alt="" /></p><p>很怪，所有静态资源加起来也就 5MB 左右，怎么告诉我直接超额了？</p><p><img src="/usr/uploads/2019/12/4136534877.png" alt="" /></p></section>
<section><h2>全是不透明响应惹的祸<a href="#全是不透明响应惹的祸"><span>#</span></a></h2><p>先打开缓存列表看看情况，但<code>Content-Length</code>是正常的完全没有问题</p><p><img src="/usr/uploads/2019/12/3655484049.png" alt="" /></p><p>经过一番思考（其实是走投无路没得选），我将目光放在了可疑的<code>Response-Type: opaque</code>上</p><p>稍微搜索了下，在一则 Stack Overflow 问题 <a href="https://stackoverflow.com/questions/39109789/what-limitations-apply-to-opaque-responses" target="_blank">What limitations apply to opaque responses?</a> 中找到了这段话</p><blockquote><p><strong>Opaque Responses &amp; the navigator.storage API</strong></p><p>In order to avoid leakage of cross-domain information, there’s significant padding added to the size of an opaque response used for calculating storage quota limits (i.e. whether a <code>QuotaExceeded</code> exception is thrown) and reported by the <a href="https://developers.google.com/web/updates/2017/08/estimating-available-storage-space" target="_blank"><code>navigator.storage</code> API</a>.</p><p>The details of this padding vary from browser to browser, but for Google Chrome, this means that the minimum size that any single cached opaque response contributes to the overall storage usage is <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=796060#c17" target="_blank">approximately 7 megabytes</a>. You should keep this in mind when determining how many opaque responses you want to cache, since you could easily exceeded storage quota limitations much sooner than you’d otherwise expect based on the actual size of the opaque resources.</p></blockquote><p>意思是，为了避免跨域信息泄漏，在计算储存空间时，不透明响应的大小会被添加大量填充，填充的大小因浏览器而异，对于 Chrome 来说，<strong>缓存单个不透明响应将至少占用约 7MB 空间</strong></p><p>破案了，那这 100MB 空间确实不够存的</p></section>
<section><h2>跟跨域请求讲道理<a href="#跟跨域请求讲道理"><span>#</span></a></h2><p>那么解决问题的关键就是如何让“不透明”响应变为“透明”响应了</p><p>再次观察之前的缓存列表，发现由 CSS 请求的字体文件为<code>Response-Type: cors</code>，也就是说字体文件是正确发出了跨域请求的</p><p>对比字体文件的请求和其它请求，发现一个很关键的点，字体文件请求头带了<code>origin</code>，而其它有问题的请求没有！</p>

<table><thead><tr><th><img src="/usr/uploads/2019/12/4004080005.png" alt="" /></th><th><img src="/usr/uploads/2019/12/2129633247.png" alt="" /></th></tr></thead><tbody><tr><td>cors</td><td>opaque</td></tr></tbody></table><p>如果没有携带<code>origin</code>头，CORS 就不会运作，所以我们得到了不透明响应</p><p>基于这一设想，我在 MDN 的一个文档 <a href="https://developer.mozilla.org/zh-CN/docs/Web/HTML/CORS_settings_attributes" target="_blank">CORS settings attributes</a> 中找到了这些描述</p><blockquote><p>在HTML5中，一些 HTML 元素提供了对 CORS 的支持， 例如 <code>&lt;audio&gt;</code>、<code>&lt;img&gt;</code>、<code>&lt;link&gt;</code>、<code>&lt;script&gt;</code> 和 <code>&lt;video&gt;</code> 均有一个跨域属性 (crossOrigin property)，它允许你配置元素获取数据的 CORS 请求。</p><p>…</p><p>**默认情况下（即未指定 crossOrigin 属性时），CORS 根本不会使用。**如 <a href="http://www.w3.org/TR/cors/#user-credentials" target="_blank">Terminology section of the CORS specification</a> 中的描述，在非同源情况下，设置 “anonymous” 关键字将不会通过 cookies，客户端 SSL 证书或 HTTP 认证交换用户凭据。</p></blockquote><p>也就是说，请求没有携带<code>origin</code>头的原因是没有给标签配置<code>crossorigin</code>属性，由于我需要跨域加载的都是静态资源，不需要携带凭据，所以只要给各种标签都配置<code>crossorigin="anonymous"</code>就可以了</p><p>于是我开始疯狂的搜索项目中的各种<code>&lt;img&gt;</code>、<code>&lt;link&gt;</code>、<code>&lt;script&gt;</code>标签然后加跨域属性，发布，测试，很好，请求都带上<code>origin</code>头了，并且成功成为了<code>Response-Type: cors</code>的“透明”响应被 Workbox 缓存，储存空间的占用也恢复了正常水平</p><p><img src="/usr/uploads/2019/12/4109501567.png" alt="" /></p><p><img src="/usr/uploads/2019/12/2680533143.png" alt="" /></p><p><img src="/usr/uploads/2019/12/3394322755.png" alt="" /></p></section>
<section><h2>别高兴的太早<a href="#别高兴的太早"><span>#</span></a></h2><p>对于多媒体标签的跨域问题是解决了，其它情况下的请求又如何呢</p><p>经过测试与排查，我发现以下几种情况依然会得到不透明响应</p><ol>
<li>在 CSS 中引用的背景图片(<code>background-image</code>)等</li>
<li>通过 JS 控制的但没有设置跨域属性的多媒体加载：常见于各类第三方组件，拿图片懒加载组件举例，一般的懒加载都是先通过 JS 请求图片，加载完成后再给<code>&lt;img&gt;</code>的<code>src</code>赋值，如果这次由 JS 发出的请求没有携带<code>origin</code>头，那么即使你给懒加载的<code>&lt;img&gt;</code>设置跨域属性，你依然会得到不透明响应</li>
</ol><p>解决办法：</p><ol>
<li>改用<code>&lt;img&gt;</code>做背景图，你可以通过<code>position: absolute</code>之类的 CSS 手段让<code>&lt;img&gt;</code>不占据空间，达到和<code>background-image</code>一样的效果</li>
<li>这个解决方法因实际情况而异了，例如我使用的是 <a href="https://www.npmjs.com/package/vue-lazyload" target="_blank">Vue-Lazyload</a> 组件，好在它提供懒加载组件的功能，因此我将原本的懒加载图片改为懒加载一个包含<code>&lt;img crossorigin="anonymous"&gt;</code>的组件，这样就不存在用 JS 预加载图片的过程，曲线救国</li>
</ol><p>另外，为了确保不会缓存到不透明响应，强烈建议配置 Workbox 时不要允许缓存<a href="https://fetch.spec.whatwg.org/#concept-filtered-response-opaque" target="_blank">返回码为<code>0</code>的请求</a></p><p>例如我使用 Vue 的 PWA 插件，原本的配置（局部）是这样的：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>module</span><span>.</span><span>exports</span><span> </span><span>=</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>pwa</span><span>:</span><span> {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>workboxOptions</span><span>:</span><span> {</span></div></div><div><div><div>4</div></div><div><span>      </span><span>runtimeCaching</span><span>:</span><span> [</span></div></div><div><div><div>5</div></div><div><span><span>        </span></span><span>{</span></div></div><div><div><div>6</div></div><div><span>          </span><span>urlPattern</span><span>:</span><span> /</span><span>...</span><span>/</span><span>,</span></div></div><div><div><div>7</div></div><div><span>          </span><span>handler</span><span>:</span><span> </span><span>"CacheFirst"</span><span>,</span></div></div><div><div><div>8</div></div><div><span>          </span><span>options</span><span>:</span><span> {</span></div></div><div><div><div>9</div></div><div><span>            </span><span>cacheableResponse</span><span>:</span><span> {</span></div></div><div><div><div>10</div></div><div><span>              </span><span>statuses</span><span>:</span><span> [</span><span>0</span><span>, </span><span>200</span><span>],</span></div></div><div><div><div>11</div></div><div><span><span>            </span></span><span>},</span></div></div><div><div><div>12</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>13</div></div><div><span><span>        </span></span><span>},</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>],</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>16</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>17</div></div><div><span>};</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>因为最初写的时候照抄了官方示例因此带上了<code>0</code>，发生这次事件以后，我将<code>statuses: [0, 200]</code>改为了<code>statuses: [200]</code> :)</p></section>
<section><h2>清除旧缓存<a href="#清除旧缓存"><span>#</span></a></h2><p>做完了以上步骤仍没有结束，因为用户如果在之前使用过旧版本的 PWA 应用，遗留的不透明请求缓存可能会产生副作用</p><p>如果你的缓存机制为<code>CacheFirst</code>，仍会得到由 Service Worker 返回的不透明请求，由于<code>crossorigin="anonymous"</code>的应用，这些请求将会被浏览器拒绝，导致资源无法加载</p><p>我个人的解决方法是在更新后判断是否是从之前的旧版本升级的，如果是的话调用 CacheStorage 的 API 清除运行时缓存并重载页面</p><p>例如在页面比较前的位置加入下方的 script</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>(</span><span>function</span><span> () {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>var</span><span><span> </span><span>versionFlag</span><span> </span></span><span>=</span><span><span> </span><span>localStorage</span><span>.</span></span><span>getItem</span><span>(</span><span>"versionFlag"</span><span>);</span></div></div><div><div><div>3</div></div><div><span>  </span><span>var</span><span><span> </span><span>currentFlag</span><span> </span></span><span>=</span><span> </span><span>"20191211"</span><span>; </span><span>// 随便使用一个字符串</span></div></div><div><div><div>4</div></div><div><span>  </span><span>// caches 是 CacheStorage 的一个实例</span></div></div><div><div><div>5</div></div><div><span>  </span><span>if</span><span> (</span><span>!</span><span><span>(</span><span>versionFlag</span><span> </span></span><span>&amp;&amp;</span><span><span> </span><span>versionFlag</span><span> </span></span><span>===</span><span><span> </span><span>currentFlag</span><span>) </span></span><span>&amp;&amp;</span><span><span> </span><span>caches</span><span>) {</span></span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>caches</span><span>.</span><span>keys</span><span>().</span><span>then</span><span>(</span><span>function</span><span><span> (</span><span>names</span><span>) {</span></span></div></div><div><div><div>7</div></div><div><span>      </span><span>Promise</span><span>.</span><span>all</span><span>(</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span>names</span></div></div><div><div><div>9</div></div><div><span><span>          </span></span><span>.</span><span>filter</span><span>(</span><span>function</span><span><span> (</span><span>name</span><span>) {</span></span></div></div><div><div><div>10</div></div><div><span>            </span><span>return</span><span> /runtime/</span><span>.</span><span>test</span><span><span>(</span><span>name</span><span>);</span></span></div></div><div><div><div>11</div></div><div><span><span>          </span></span><span>})</span></div></div><div><div><div>12</div></div><div><span><span>          </span></span><span>.</span><span>map</span><span>(</span><span>function</span><span><span> (</span><span>name</span><span>) {</span></span></div></div><div><div><div>13</div></div><div><span>            </span><span>return</span><span><span> </span><span>caches</span><span>.</span></span><span>delete</span><span><span>(</span><span>name</span><span>);</span></span></div></div><div><div><div>14</div></div><div><span><span>          </span></span><span>}),</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>).</span><span>then</span><span>(</span><span>function</span><span> () {</span></div></div><div><div><div>16</div></div><div><span><span>        </span></span><span>localStorage</span><span>.</span><span>setItem</span><span>(</span><span>"versionFlag"</span><span><span>, </span><span>currentFlag</span><span>);</span></span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>window</span><span>.</span><span>location</span><span>.</span><span>reload</span><span>();</span></div></div><div><div><div>18</div></div><div><span><span>      </span></span><span>});</span></div></div><div><div><div>19</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>20</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>21</div></div><div><span>})();</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/vscode-monospaced/</id>
      <title type="text">VSCode 等宽字体之坑</title>
      <published>2019-11-20T09:49:00.000Z</published>
      <updated>2019-11-20T14:15:35.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/vscode-monospaced/"/>
      <summary type="text">想等个宽，我太难了</summary>
      <content type="html"><![CDATA[<p>想等个宽，我太难了</p>
<p>Head Pic: <a href="https://www.pixiv.net/artworks/77875196" target="_blank">#明日方舟 Mostima - Alcxome的插画 - pixiv</a>
<small>我抽到啦（小声）</small></p>
<hr />
<p>由于习惯原因我一直是使用 VSCode 写 Markdown 的，并且一直在用 <a href="https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one" target="_blank">Markdown All in One</a> 插件，有一说一它确实非常好用，特别是这个表格格式化功能让我爱不释手</p>
<p><img src="/usr/uploads/2019/11/4275063757.gif" alt="" /></p>
<p>但我很快发现了一个问题，含有中文的时候这个表格，它对不齐</p>
<p><img src="/usr/uploads/2019/11/755261504.png" alt="" /></p>
<p>当时因为我过于年轻，这个问题被不了了之了，直到最近才突然重新出现在我脑袋中，经过一番思索我马上意识到这是字体不等宽导致的问题</p>
<p>那怎么解决？找个等宽字体就好啦？</p>
<p>然而事情并没有那么简单</p>
<section><h2>寻找合适的等宽字体<a href="#寻找合适的等宽字体"><span>#</span></a></h2><p>经过一番搜索，我找到了四款我觉得不错的包含中文的等宽字体，但实际上只有前两款可以在 VSCode 中正常等宽，非常奇怪（终端中只允许使用等宽字体，能用就说明等宽）</p>

<table><thead><tr><th>Name</th><th>Used Font Family</th><th>In VSCode</th><th>In Terminal</th></tr></thead><tbody><tr><td><a href="https://github.com/be5invis/Sarasa-Gothic" target="_blank">更纱黑体</a></td><td><code>'Sarasa Mono SC'</code></td><td><img src="/usr/uploads/2019/11/3100915754.png" alt="" /></td><td><img src="/usr/uploads/2019/11/4196080814.png" alt="" /></td></tr><tr><td><a href="https://github.com/rayshan/mplus-fonts" target="_blank">M+ FONTS</a></td><td><code>'M+ 1m'</code></td><td><img src="/usr/uploads/2019/11/3246963724.png" alt="" /></td><td><img src="/usr/uploads/2019/11/169042396.png" alt="" /></td></tr><tr><td><a href="https://www.onlinewebfonts.com/download/9798f64007ae3426b2336e57dae4149c" target="_blank">雅黑等宽</a></td><td><code>'Microsoft YaHei Mono'</code></td><td><img src="/usr/uploads/2019/11/1621915418.png" alt="" /></td><td><img src="/usr/uploads/2019/11/2310660965.png" alt="" /></td></tr><tr><td><a href="https://gitee.com/leehow1988/font-yasolas" target="_blank">Yasolas</a></td><td><code>Yasolas</code></td><td><img src="/usr/uploads/2019/11/2139980882.png" alt="" /></td><td><img src="/usr/uploads/2019/11/3636772843.png" alt="" /></td></tr></tbody></table><p>后来我在 issue <a href="https://github.com/Microsoft/vscode/issues/14589" target="_blank">Monospacing broken by Chinese character #14589</a> 中找到了答复，由于 VSCode 是基于 Electron 的，前端由 Chromium 渲染，这种字体渲染问题很可能是 Chromium 导致的，VSCode 侧无能为力</p><blockquote><p>This is an upstream issue (possibly within Chromium), and there are no known workarounds that we could implement on our side. This means there is no possible code change for us to do in VS Code sources to improve things.</p></blockquote></section>
<section><h2>但我不想用中英等宽字体写代码<a href="#但我不想用中英等宽字体写代码"><span>#</span></a></h2><p>你可以从截图中看出，这些等宽字体会使一个全角字符的宽度严格等于两个半角字符的宽度</p><p>他们的宽高比最大只有0.5，这导致半角字符看起来特别“瘦”，拿来写代码……反正我是会瞎的</p><p>由于只是在 Markdown 之类的格式下需要使用这类字体，因此我们完全可以独立配置</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"[markdown]"</span><span>: {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"editor.fontFamily"</span><span>: </span><span>"'Sarasa Mono SC'"</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这样就不会影响全局的设置了</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/github-actions-experience/</id>
      <title type="text">GitHub Actions 初体验及踩坑记录</title>
      <published>2019-11-14T10:14:00.000Z</published>
      <updated>2019-11-14T10:16:59.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/github-actions-experience/"/>
      <summary type="text">上周摸鱼摸到 GitHub Actions，听说今年 11 月就要正式向大众开放了，试了下蛮好玩的，但局限性和坑点也非常多</summary>
      <content type="html"><![CDATA[<p>上周摸鱼摸到 GitHub Actions，听说今年 11 月就要正式向大众开放了，试了下蛮好玩的，但局限性和坑点也非常多</p>
<p>Head Pic: <a href="https://www.pixiv.net/artworks/77789607" target="_blank">#アークナイツ frost - am1m的插画 - pixiv</a></p>
<hr />
<p>官方介绍说，<a href="https://github.com/features/actions" target="_blank">GitHub Actions</a> 可以自动化和定制化项目的 Workflow，相当于官方钦定的 CI，目前仍处于 beta 阶段，想使用必须去手动点个按钮申请，听说 11 月会正式开放给全员</p>
<p>实际折腾了几天，给我的感受是，得益于 GitHub 这个平台，再加上你的创(xiao)造(nao)力(gua)，Actions 能做到的事情确实很多，但有很多问题十分影响使用体验，后面会一一列出</p>
<p>使用前可以搜索一下已有的介绍文章、阅读<a href="https://help.github.com/en/actions/automating-your-workflow-with-github-actions" target="_blank">官方文档</a>来大致了解，真正使用的话我们主要阅读 <a href="https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions" target="_blank">Workflow syntax</a> 和 <a href="https://help.github.com/en/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions" target="_blank">Contexts and expression syntax</a> 文档就行了</p>
<p>你可以在 <a href="https://github.com/marketplace?type=actions" target="_blank">GitHub Marketplace</a> 浏览寻找其他人开发的 actions，同时我推荐看看 <a href="https://github.com/sdras/awesome-actions" target="_blank">sdras/awesome-actions</a> 这个仓库，它收录了许多 GitHub Actions 相关的内容，并且对官方和他人开发的 actions 的功能做了分类与简略说明，方便你快速找到自己需要的 actions</p>
<section><h2>用例与简单说明<a href="#用例与简单说明"><span>#</span></a></h2><p>与 Travis CI 相似，GitHub Actions 也使用 YAML 作为配置文件的格式，放在<code>.github/workflows</code>文件夹下</p><p><a href="https://github.com/Tsuk1ko/arknights-toolbox/blob/master/.github/workflows/pages-deploy.yml" target="_blank">这是一个简单的示例</a>，作用是当我更新 vue 项目文件时自动构建 dist 并发布到 GitHub Pages，然后推送到我的 Coding Pages 所在的远程仓库</p><p>下面我简单描述一下 GitHub Actions 中常用的语法，使你可以大概了解它能做什么</p><ul>
<li><code>on</code>规定什么时候触发 workflow
<ul>
<li>可以由<code>push</code>,<code>pull_request</code>,<code>release</code>等<a href="https://help.github.com/en/articles/events-that-trigger-workflows" target="_blank">事件</a>触发
<ul>
<li>例如<code>release</code>这种事件可以定义具体<a href="https://help.github.com/en/articles/events-that-trigger-workflows#webhook-events" target="_blank">类型</a></li>
<li><code>push</code>,<code>pull_request</code>可以规定涉及具体分支<code>branches</code>、标签<code>tags</code>、路径<code>path</code>时触发
<ul>
<li>路径可以用包含（<code>path</code>）或忽略（<code>paths-ignore</code>）两种模式，支持通配符，包含模式下可以用<code>!</code>声明例外目录</li>
</ul>
</li>
</ul>
</li>
<li>可以由<code>schedule</code>定时触发，使用 cron 表达式</li>
</ul>
</li>
<li><code>jobs</code>是 workflow 的组成部分，每个 job 是在不同的容器内并行运行的，之间无法直接相互干涉
<ul>
<li><code>needs</code>可以声明一个工作依赖另一个或多个 job，当这些 job 被完成后才会开始执行</li>
<li><code>runs-on</code>系统环境，目前支持以下几个（以后估计会慢慢加）
<ol>
<li>Windows Server 2019: <code>windows-latest</code></li>
<li>Ubuntu 18.04: <code>ubuntu-latest</code> or <code>ubuntu-18.04</code></li>
<li>Ubuntu 16.04: <code>ubuntu-16.04</code></li>
<li>macOS X Catalina 10.15: <code>macos-latest</code></li>
</ol>
</li>
<li><code>env</code>定义环境变量，作用域为整个 job</li>
<li><code>if</code>规定当满足某些条件时才执行这个 job</li>
<li><code>steps</code>是 job 的组成部分，step 是顺序执行的
<ol>
<li><code>env</code>定义环境变量，作用域为当前 step，且你对环境变量的任何更改都不会带到其它 step 或者 job 中</li>
<li><code>if</code>规定当满足某些条件时才执行这个 step，并且可以使用<a href="https://help.github.com/en/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#job-status-check-functions" target="_blank">状态检查函数</a>，根据上一个 step 的状态决定是否运行</li>
<li><code>uses</code>声明使用其它 action 作为你的 step，也就是使用其他人写好的 action</li>
<li><code>with</code>为 uses 的 action 传入参数，具体看你使用的 action 的说明</li>
<li><code>run</code>运行命令，支持多行，具体看文档</li>
<li><code>shell</code>定义 run 所使用的 shell，具体看文档</li>
<li><code>continue-on-error</code>即使有错误也继续往下运行 step</li>
<li><code>timeout-minutes</code>规定该 step 的超时时间</li>
</ol>
</li>
<li><code>timeout-minutes</code>规定该 job 的超时时间</li>
<li><code>strategy</code>定义一些矩阵供 job 使用，详细看文档</li>
<li><code>container</code>容器具体信息，不规定时所有 step 将直接在<code>runs-on</code>规定的环境上运行，详细看文档</li>
<li><code>services</code>声明使用哪些服务，例如<code>nginx</code>或<code>redis</code>等</li>
</ul>
</li>
</ul></section>
<section><h2>Tips<a href="#tips"><span>#</span></a></h2><ol>
<li>涉密内容应使用 secrets（如何使用请阅读 <a href="https://help.github.com/en/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#contexts" target="_blank">Contexts and expression syntax</a>），在项目 settings 中可以设置，此时 workflow 的日志中所有与 secrets 一致的内容都会用<code>***</code>替换；基于这一特性，若你想隐藏日志中会出现的某些词句，即使它们不需要被当做涉密变量在 workflow 中使用，你也可以将它们设置成 secrets</li>
<li>可以使用 <a href="https://github.com/marketplace/actions/cache" target="_blank">actions/cache</a> 来缓存一些可以重复利用的文件，例如 node_modules，可以节省时间减少网络开销等</li>
<li>当你觉得他人开发的 action 与你的需求相当贴合但就是差了那么一丢丢时，你可以 fork 并自行修改，然后直接用自己改过的 action</li>
</ol></section>
<section><h2>坑<a href="#坑"><span>#</span></a></h2><ol>
<li>只有<code>push</code>,<code>pull_request</code>事件触发的 workflow 可以使用 <a href="https://github.com/marketplace/actions/cache" target="_blank">actions/cache</a>，详见 <a href="https://github.com/actions/cache/issues/64" target="_blank">issue#64</a></li>
<li>在<code>if</code>内无法访问 secrets 上下文</li>
<li>在<code>if</code>内无法访问同级<code>env</code>
<ul>
<li>例如<code>job.&lt;job_id&gt;.step.if</code>只能访问<code>job.&lt;job_id&gt;.env</code>中定义的环境变量，而不能访问<code>job.&lt;job_id&gt;.step.env</code>中定义的环境变量</li>
</ul>
</li>
<li>综合 2 和 3，2 的变通解决方式是在上级<code>env</code>中声明一个环境变量来使用 secrets 的值，并且由于 3 的限制，你只能在 step 上这么操作</li>
<li>由于<code>env</code>的本质是字符串，因此在<code>if</code>中使用<code>env</code>时请注意数据类型
<ul>
<li>例如在 job 中声明环境变量<code>test: ${{ true }}</code>，在 step 的 if 中使用时，条件应当用<code>env.test == 'true'</code>，而不是<code>env.test == true</code></li>
</ul>
</li>
<li>workflow 中产生的事件无法直接触发另一个 workflow 的运行，详见 <a href="https://help.github.com/en/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows#about-workflow-events" target="_blank">About workflow events</a>
<ul>
<li>例如 A 是定时运行，会往项目 push 代码，B 会在 push 事件发生时触发，则 A 的运行无法触发 B</li>
</ul>
</li>
</ol></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/greasemonkey-experience/</id>
      <title type="text">油猴脚本入坑指南</title>
      <published>2019-11-06T09:29:00.000Z</published>
      <updated>2020-12-29T07:54:10.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/greasemonkey-experience/"/>
      <summary type="text">希望可以让开始尝试自己写脚本的同学们少走一些弯路吧</summary>
      <content type="html"><![CDATA[<p>希望可以让开始尝试自己写脚本的同学们少走一些弯路吧</p>
<p>Head Pic: <a href="https://www.pixiv.net/artworks/77678526" target="_blank">#アズールレーン 恶毒 - 小小男爵不要坑的插画 - pixiv</a></p>
<section><h1>基础<a href="#基础"><span>#</span></a></h1><p>这部分主要是开始写油猴脚本前应当有所了解的知识</p><section><h2>常见的用户脚本管理器<a href="#常见的用户脚本管理器"><span>#</span></a></h2><ul>
<li><a href="https://www.tampermonkey.net/" target="_blank">Tampermonkey</a>
应该是各位见得最多的也是最知名的，好用又稳定，多浏览器支持，我很喜欢</li>
<li><a href="https://addons.mozilla.org/zh-CN/firefox/addon/greasemonkey/" target="_blank">Greasemonkey</a>
用户脚本始祖，我们现在一直习惯说的油猴脚本的“油猴”实际上就是 Greasemonkey，只支持 Firefox
由于与 Tampermonkey 等其它脚本管理器在 API 的使用上会有些区别，导致某些情况下你很难保持你的脚本同时对 Greasemonkey 兼容，我一般直接放弃兼容</li>
<li><a href="https://violentmonkey.github.io/" target="_blank">Violentmonkey</a>
由国人开发的一款脚本管理器，界面好看，我很喜欢</li>
</ul></section><section><h2>元数据<a href="#元数据"><span>#</span></a></h2><p>即每个油猴脚本都有的，脚本开头很多行注释的内容，这是油猴脚本关键的基础部分，刚开始接触可能会一头雾水，但你绝不能忽视这部分内容</p><p>建议：</p><ol>
<li>多参考别人的脚本，能对各个字段的意义了解个大概</li>
<li>阅读<a href="https://wiki.greasespot.net/Metadata_Block" target="_blank">官方 wiki</a>，有每个字段详细的介绍
如果你觉得读鸟语实在是很头疼，你也可以阅读由他人维护的<a href="https://jixunmoe.github.io/gmDevBook/" target="_blank">中文 GreaseMonkey 用户脚本开发手册</a></li>
<li>不同的用户脚本管理器可能会加入自己独有的 meta，开发时建议以你的脚本打算主要支持的脚本管理器为主，例如这是 <a href="https://www.tampermonkey.net/documentation.php" target="_blank">Tampermonkey 的文档</a></li>
</ol></section><section><h2>GM API<a href="#gm-api"><span>#</span></a></h2><p>油猴提供了很多强大的 API，它们可以使很操作变得相当简单</p><p>注意每个 API 在使用前需要在元数据中用 <a href="https://wiki.greasespot.net/@grant" target="_blank">@grant</a> 进行声明，若你不打算使用这些 API，应当声明 <code>@grant none</code></p><p>以下是一个简单的表格，帮助你了解油猴的 API 大概能做哪些事情</p>

<table><thead><tr><th><a href="https://jixunmoe.github.io/gmDevBook/#/doc/api/GM_info" target="_blank">旧 API</a></th><th><a href="https://wiki.greasespot.net/Greasemonkey_Manual:API" target="_blank">新 API</a></th><th>说明</th></tr></thead><tbody><tr><td>GM_info</td><td>GM.info</td><td>返回当前脚本的元数据</td></tr><tr><td>GM_addStyle</td><td></td><td>为网页添加 CSS</td></tr><tr><td>GM_setValue</td><td>GM.setValue</td><td>在本地储存值（只能是字符串），你可以将这个储存看作是 localStorage 一样的东西</td></tr><tr><td>GM_getValue</td><td>GM.getValue</td><td>获取使用储存的值</td></tr><tr><td>GM_deleteValue</td><td>GM.deleteValue</td><td>删除储存的值</td></tr><tr><td>GM_listValues</td><td>GM.listValues</td><td>返回一个由所有储存值的键名组成的数组</td></tr><tr><td>GM_getResourceText</td><td></td><td>获取元数据中定义的 @resource 的资源内容</td></tr><tr><td>GM_getResourceU<strong>RL</strong></td><td>GM.getResourceU<strong>rl</strong></td><td>获取元数据中定义的 @resource 资源的 URL（base64 编码后的<code>data:</code>协议地址）</td></tr><tr><td>GM_openInTab</td><td>GM.openInTab</td><td>新标签页打开指定地址（用来绕过 Chrome 会阻止所有非用户触发的<code>window.open</code>的限制）</td></tr><tr><td>GM_registerMenuCommand</td><td></td><td>向油猴插件菜单中添加脚本指令（通常用于打开自己写的设置界面或者执行代码之类的）</td></tr><tr><td>GM_setClipboard</td><td>GM.setClipboard</td><td>复制指定内容到剪贴板</td></tr><tr><td>GM_xml<strong>h</strong>ttpRequest</td><td>GM.xml<strong>H</strong>ttpRequest</td><td>发送网络请求，且允许跨域</td></tr><tr><td></td><td>GM.notification</td><td>浏览器通知</td></tr></tbody></table><section><h3>新旧 API 的区别<a href="#新旧-api-的区别"><span>#</span></a></h3><p>Greasemonkey 从版本 4 开始向性能更高的异步模型发展，旧的 API <code>GM_*</code> 通常是同步的，而新的 API <code>GM.*</code> 是异步的（采用 Promise），在使用时请参考官方 wiki 并多加留意</p><p>并且，有些 API 的名称拼写也发生了变化，在上面的表格中已经用粗体标识</p><p>想了解更多信息可以阅读官方说明文章 <a href="https://www.greasespot.net/2017/09/greasemonkey-4-for-script-authors.html" target="_blank">Greasemonkey 4 For Script Authors</a></p></section><section><h3>unsafeWindow<a href="#unsafewindow"><span>#</span></a></h3><p>如果你在写脚本的时候有尝试直接通过 window 添加或访问网页全局变量，你会发现这是没有效果的</p><p>这是因为油猴的沙箱机制，任何人都无法从 window 直接访问到油猴的 API 或脚本内的变量，保证了安全</p><p>如果你确实需要访问 window，可以使用 unsafeWindow，但在正式发布的脚本中<strong>你不应该将任何油猴 API 或者脚本中的变量通过它暴露到 window 中</strong></p><p>unsafeWindow 在不同脚本管理器中的表现可能会有所不同，特别是 Violentmonkey，如需考虑兼容性还需要多加测试</p></section><section><h3>跨域请求<a href="#跨域请求"><span>#</span></a></h3><p>在油猴脚本中你可以引用网络脚本来使用 axios 之类的网络请求模块，这很方便，但同样也产生了局限性，例如由于浏览器机制的限制，你无法直接在网页上进行没有被事先允许的跨域请求</p><p>这时建议使用 <a href="https://wiki.greasespot.net/GM.xmlHttpRequest" target="_blank">GM.xmlHttpRequest</a>，同时你应当在元数据用<code>// @connect &lt;value&gt;</code>声明允许被 GM.xmlHttpRequest 访问的域名</p><p><code>&lt;value&gt;</code>可以是：</p><ul>
<li>域名，例如<code>example.com</code>，这也将允许所有子域</li>
<li>子域，例如<code>abc.example.com</code></li>
<li><code>self</code>，即脚本运行的网址</li>
<li><code>localhost</code></li>
<li>IP 地址</li>
<li><code>*</code></li>
</ul><p>如果你习惯用 axios 之类的用 Promise 封装的请求模块，你同样可以将 GM.xmlHttpRequest 封装成 Promise 形式</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> </span><span>xhr</span><span> </span><span>=</span><span><span> (</span><span>option</span><span>) </span></span><span>=&gt;</span></div></div><div><div><div>2</div></div><div><span>  </span><span>new</span><span> </span><span>Promise</span><span><span>((</span><span>resolve</span><span>, </span><span>reject</span><span>) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>GM</span><span>.</span><span>xmlHttpRequest</span><span>({</span></div></div><div><div><div>4</div></div><div><span><span>      </span></span><span>...</span><span><span>option</span><span>,</span></span></div></div><div><div><div>5</div></div><div><span>      </span><span>onerror</span><span>:</span><span><span> </span><span>reject</span><span>,</span></span></div></div><div><div><div>6</div></div><div><span>      </span><span>onload</span><span>:</span><span><span> </span><span>resolve</span><span>,</span></span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>});</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h2>使用自己的 IDE 编写油猴脚本<a href="#使用自己的-ide-编写油猴脚本"><span>#</span></a></h2><p>一般脚本管理器自带的编辑器功能十分单一，全程在里面写代码肯定十分不爽，那么如何使用自己的 IDE 编写脚本并随时保存随时生效呢</p><p>答案是利用元数据的 <a href="https://wiki.greasespot.net/Metadata_Block#.40require" target="_blank">@require</a>，它不仅能引用网络脚本，还可以引用本地脚本，所以我们只要 require 用 IDE 编辑的本地脚本就行了</p><p>在这之前我们需要允许油猴插件访问本地文件，以 Chrome 为例，在扩展程序列表<code>chrome://extensions/</code>进入插件的详细信息，开启“允许访问文件网址”即可，接着就可以<code>// @require file://&lt;本地路径&gt;</code>的文件网址方式引用本地脚本了</p></section><section><h2>引用 CSS<a href="#引用-css"><span>#</span></a></h2><p>引用 JS 可以采用<code>@require</code>，但 CSS 不行</p><p>可行的方法有两种</p><ol>
<li>老办法：用 JS 往<code>&lt;head&gt;</code>插入 CSS 的<code>&lt;link&gt;</code></li>
<li>API 方法：在元数据中声明<code>// @resource mycss &lt;地址&gt;</code>，然后<code>GM_addStyle(GM_getResourceText('mycss'));</code>
别忘了用到的这两个 API 也要<code>@grant</code>声明</li>
</ol></section></section>
<section><h1>进阶<a href="#进阶"><span>#</span></a></h1><p>这部分主要是写脚本的过程中有可能遇到的一些难点的较优解决方法</p><section><h2>避免将 setInterval 用作动态监听的解决方案<a href="#避免将-setinterval-用作动态监听的解决方案"><span>#</span></a></h2><p>初学 JS 的新手在遇到监听动态元素的问题的时候，由于缺乏经验，通常只能想到用 setInterval 去“每隔一段时间就检测一下”，当然这也包括我自己，但不管从性能上还是从实现复杂度来说，这都不是一个好选择，不够优雅</p><p>大部分类似的问题都可以在事件监听层面运用点技巧来解决</p><p>此处会列举几个常见的场景来说明一下解决思路</p><section><h3>1. 监听动态生成的页面元素的事件<a href="#1-监听动态生成的页面元素的事件"><span>#</span></a></h3><p>在有些时候我们可能要去监听动态生成的页面元素的事件，例如自动翻页加载的评论这类</p><ul>
<li><strong>不好的思路</strong>
setInterval 每隔一段时间检测一下有没有新生成的页面元素，然后对这些页面元素添加事件监听</li>
<li><strong>好的思路</strong>
由于事件冒泡机制，我们可以监听其父级元素的点击事件，然后通过事件信息来确定被点击的元素<code>currentTarget</code>或其父级元素<code>currentTarget.parentNode</code></li>
</ul><p>不仅是动态的场景下可以这么做，当你需要针对一个很多元素的静态列表监听每个元素的事件时也可以这么做，这种方法最大的优点是你只需要添加一个事件监听，如果你对列表中的每个元素都添加事件监听，会增大内存开销，影响页面性能</p><p>有种比较特殊的情况：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>ul</span><span> </span><span>class</span><span>=</span><span>"list"</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>li</span><span> </span><span>class</span><span>=</span><span>"item"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>&lt;</span><span>img</span><span> </span><span>class</span><span>=</span><span>"image"</span><span> /&gt;</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>&lt;/</span><span>li</span><span>&gt;</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>&lt;</span><span>li</span><span>&gt;...&lt;/</span><span>li</span><span>&gt;</span></div></div><div><div><div>8</div></div><div><span>&lt;/</span><span>ul</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>假设在该场景下，点击 .image 时它自身会被移除，而你需要得到被点击的 .image 所在的 .item，由于该 .image 已经被移出页面的 DOM 树，因此你无法通过点击事件的<code>currentTarget.parentNode</code>来得到 .item</p><p>最简单的解决方案是在事件发生时获取鼠标所在的 .item，例如使用 jQuery：<code>$('.item:hover')</code></p></section><section><h3>2. 对动态生成的页面元素进行修改<a href="#2-对动态生成的页面元素进行修改"><span>#</span></a></h3><p>假设一个场景，此处借用一下 vue 的语法来说明页面元素逻辑：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;!-- Init: showA = true; showB = false; --&gt;</span></div></div><div><div><div>2</div></div><div><span>&lt;</span><span>ul</span><span> </span><span>class</span><span>=</span><span>"list"</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>&lt;</span><span>li</span><span> </span><span>class</span><span>=</span><span>"item"</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>&lt;</span><span>div</span></div></div><div><div><div>5</div></div><div><span>      </span><span>v-if</span><span>=</span><span>"showA"</span></div></div><div><div><div>6</div></div><div><span>      </span><span>class</span><span>=</span><span>"item-a"</span></div></div><div><div><div>7</div></div><div><span>      </span><span>@click</span><span>=</span><span>"showA = false; doSth().then(() =&gt; { showB = true });"</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>&gt;</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>...</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>&lt;</span><span>div</span><span> </span><span>v-if</span><span>=</span><span>"showB"</span><span> </span><span>class</span><span>=</span><span>"item-b"</span><span>&gt;...&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>...</span></div></div><div><div><div>13</div></div><div><span><span>  </span></span><span>&lt;/</span><span>li</span><span>&gt;</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span><span>  </span></span><span>&lt;</span><span>li</span><span>&gt;...&lt;/</span><span>li</span><span>&gt;</span></div></div><div><div><div>16</div></div><div><span>&lt;/</span><span>ul</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>大致就是，当你点击 .item-a 的时候，.item-a 会被移除，并在一个异步函数<code>doSth()</code>完成后显示 .item-b</p><p>你当前的目标是要在 .item-b 出现的时候修改其内容</p><ul>
<li><strong>不好的思路</strong>
监听 .item-a 的点击事件，setInterval 每隔一段时间检测一下当前 .item 内有没有 .item-b，有的话就进行修改然后终止该 interval</li>
<li><strong>好的思路</strong>
监听 .item-a 的点击事件，当其被点击后监视 .item 的 DOM 变化，若新增了 .item-b 就对其进行修改</li>
</ul><p>是时候祭出 <a href="https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver" target="_blank">MutationObserver</a> 了，利用它我们可以监视 DOM 树的改动，同时它也是过去的 <a href="https://developer.mozilla.org/zh-CN/docs/Web/Guide/Events/Mutation_events" target="_blank">Mutation Events</a> 的替代品</p><p>上面所说的场景可以按这个思路来解决</p><ol>
<li>监听 .list 的点击</li>
<li>当触发点击事件时，找到  状态的 .item，对其添加 MutationObserver</li>
<li>当 MutationObserver 监视到 .item-b 被添加时，修改 .item-b，并<code>disconnect()</code>该 MutationObserver</li>
</ol><p>写成代码大概像这样：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> </span><span>findItemB</span><span> </span><span>=</span><span><span> (</span><span>$item</span><span>) </span></span><span>=&gt;</span></div></div><div><div><div>2</div></div><div><span>  </span><span>new</span><span> </span><span>Promise</span><span><span>((</span><span>resolve</span><span>, </span><span>reject</span><span>) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>if</span><span><span> (</span><span>$item</span><span>.</span></span><span>length</span><span> </span><span>===</span><span> </span><span>0</span><span>) </span><span>reject</span><span>();</span></div></div><div><div><div>4</div></div><div><span>    </span><span>// 有可能此时 .item-b 已经出现，所以先检查下</span></div></div><div><div><div>5</div></div><div><span>    </span><span>const</span><span> </span><span>$itemB</span><span> </span><span>=</span><span><span> </span><span>$item</span><span>.</span></span><span>find</span><span>(</span><span>".item-b"</span><span>);</span></div></div><div><div><div>6</div></div><div><span>    </span><span>if</span><span><span> (</span><span>$itemB</span><span>.</span></span><span>length</span><span> </span><span>&gt;</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>7</div></div><div><span>      </span><span>resolve</span><span><span>(</span><span>$itemB</span><span>);</span></span></div></div><div><div><div>8</div></div><div><span>      </span><span>return</span><span>;</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>10</div></div><div><span>    </span><span>// 监视 .item 的 DOM 树 childList 变化</span></div></div><div><div><div>11</div></div><div><span>    </span><span>new</span><span> </span><span>MutationObserver</span><span><span>((</span><span>mutations</span><span>, </span><span>self</span><span>) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>mutations</span><span>.</span><span>forEach</span><span><span>(({ </span><span>addedNodes</span><span> }) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>13</div></div><div><span><span>        </span></span><span>addedNodes</span><span>.</span><span>forEach</span><span><span>((</span><span>node</span><span>) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>14</div></div><div><span>          </span><span>if</span><span><span> (</span><span>node</span><span>.</span></span><span>className</span><span> </span><span>!==</span><span> </span><span>".item-b"</span><span>) </span><span>return</span><span>;</span></div></div><div><div><div>15</div></div><div><span><span>          </span></span><span>self</span><span>.</span><span>disconnect</span><span>();</span></div></div><div><div><div>16</div></div><div><span>          </span><span>resolve</span><span>(</span><span>$</span><span><span>(</span><span>node</span><span>));</span></span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>});</span></div></div><div><div><div>18</div></div><div><span><span>      </span></span><span>});</span></div></div><div><div><div>19</div></div><div><span><span>    </span></span><span>}).</span><span>observe</span><span><span>(</span><span>$item</span><span>[</span></span><span>0</span><span>], { </span><span>childList</span><span>:</span><span> </span><span>true</span><span> });</span></div></div><div><div><div>20</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>$</span><span>(</span><span>".list"</span><span>).</span><span>click</span><span>(</span><span>async</span><span><span> ({ </span><span>target</span><span> }) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>23</div></div><div><span>  </span><span>if</span><span><span> (</span><span>target</span><span>.</span></span><span>className</span><span> </span><span>!==</span><span> </span><span>"item-a"</span><span>) </span><span>return</span><span>;</span></div></div><div><div><div>24</div></div><div><span>  </span><span>const</span><span> </span><span>$itemB</span><span> </span><span>=</span><span> </span><span>await</span><span> </span><span>findItemB</span><span>(</span><span>$</span><span>(</span><span>".item:hover"</span><span>));</span></div></div><div><div><div>25</div></div><div><span>  </span><span>// do something with $itemB</span></div></div><div><div><div>26</div></div><div><span>});</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section></section>
<section><h1>补充<a href="#补充"><span>#</span></a></h1><section><h2>推荐的一些可能会常用的模块<a href="#推荐的一些可能会常用的模块"><span>#</span></a></h2>

<table><thead><tr><th>Github</th><th>BootCDN</th><th>用途</th></tr></thead><tbody><tr><td><a href="https://github.com/defunkt/jquery-pjax" target="_blank">jquery-pjax</a></td><td><a href="https://www.bootcdn.cn/jquery.pjax/" target="_blank">Link</a></td><td>为页面添加 pjax 支持</td></tr><tr><td><a href="https://github.com/jquery/jquery-mousewheel" target="_blank">jquery-mousewheel</a></td><td><a href="https://www.bootcdn.cn/jquery-mousewheel/" target="_blank">Link</a></td><td>为 jQuery 添加鼠标滚轮事件的支持</td></tr><tr><td><a href="https://github.com/eligrey/FileSaver.js/" target="_blank">FileSaver.js</a></td><td><a href="https://www.bootcdn.cn/FileSaver.js/" target="_blank">Link</a></td><td>另存为任意 blob 为文件</td></tr><tr><td><a href="https://github.com/Stuk/jszip" target="_blank">jszip</a></td><td><a href="https://www.bootcdn.cn/jszip/" target="_blank">Link</a></td><td>读写创建压缩文件</td></tr><tr><td><a href="https://github.com/jnordberg/gif.js" target="_blank">gif.js</a></td><td><a href="https://www.bootcdn.cn/gif.js/" target="_blank">Link</a></td><td>制作 gif，支持 worker 方式</td></tr><tr><td><a href="https://github.com/zenorocha/clipboard.js" target="_blank">clipboard.js</a></td><td><a href="https://www.bootcdn.cn/clipboard.js/" target="_blank">Link</a></td><td>虽然油猴提供剪贴板 API，但该模块可以提供一些扩展功能，例如 tooltips 反馈等</td></tr><tr><td><a href="https://github.com/bevacqua/dragula" target="_blank">dragula</a></td><td><a href="https://www.bootcdn.cn/dragula/" target="_blank">Link</a></td><td>提供页面元素的拖拽调序功能</td></tr><tr><td><a href="https://github.com/CodeSeven/toastr" target="_blank">toastr</a></td><td><a href="https://www.bootcdn.cn/toastr.js/" target="_blank">Link</a></td><td>方便的显示页内通知</td></tr></tbody></table></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/ps4-live/</id>
      <title type="text">如何科学地直播 PS4</title>
      <published>2019-09-13T08:24:00.000Z</published>
      <updated>2021-04-07T09:16:30.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/ps4-live/"/>
      <summary type="text">劫持 twitch 推流，无需采集卡就能直播 PS4 画面，于是又省下了买采集卡的钱（。</summary>
      <content type="html"><![CDATA[<p>劫持 twitch 推流，无需采集卡就能直播 PS4 画面，于是又省下了买采集卡的钱（。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=76625943" target="_blank">#arknights 白面鸮 - UM3c的插画 - pixiv</a></p>
<hr />
<p>不用采集卡直播还有一种最简单的方法是使用 PS4 遥控操作（PS4 Remote Play），直接直播在电脑上串流的 PS4 画面，但这有几点缺点</p>
<ol>
<li>手柄需要一直连到电脑上，且声音只能通过电脑或手柄播放</li>
<li>Slim 机型（比如我这种穷人甚至买的二手 Slim）只支持 720p 串流，虽然用来直播是可以的，但是自己玩的话体验极差</li>
</ol>
<p>那么问题就在于如何找到一种独立的“投屏”方法，在不影响游戏体验的情况下得到 PS4 画面</p>
<p>好在 PS4 其实是自带直播推流功能的，支持 twitch 和 youtube，那么我们只要劫持推流就可以拿来推到自己想要的直播平台上了</p>
<p>当然了，这种方法肯定是没有采集卡效果好的，而且 Slim 的推流最高也只支持 720p 60fps</p>
<section><h2>0. 前置准备<a href="#0-前置准备"><span>#</span></a></h2><p>想要完成上述操作，我们需要</p><ol>
<li>一台 openwrt 路由器或自建的软路由</li>
<li>一个位于内网的 linux，可以是 WSL 或者虚拟机，如果你是软路由的话也可以尝试直接利用
我个人最推荐 WSL，它最为方便，WSL 大法好</li>
<li>nginx + nginx-rtmp-module</li>
</ol><p>后续示例均为使用 WSL 与 openwrt 路由器</p></section>
<section><h2>1. 编译带 nginx-rtmp-module 的 nginx<a href="#1-编译带-nginx-rtmp-module-的-nginx"><span>#</span></a></h2>

<table><thead><tr><th>Require</th><th>Website</th></tr></thead><tbody><tr><td>nginx</td><td><a href="https://nginx.org/en/download.html" target="_blank">https://nginx.org/en/download.html</a></td></tr><tr><td>nginx-rtmp-module</td><td><a href="https://github.com/arut/nginx-rtmp-module" target="_blank">https://github.com/arut/nginx-rtmp-module</a></td></tr></tbody></table><p>此处假设我们将 nginx 装到<code>/opt</code>下，我编译的是写这篇文章的时候最新的 stable version nginx-1.16.1</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 安装依赖</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>build-essential</span><span> </span><span>libpcre3</span><span> </span><span>libpcre3-dev</span><span> </span><span>libssl-dev</span><span> </span><span>zlib1g-dev</span><span> </span><span>git</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 获取 nginx 源码</span></div></div><div><div><div>5</div></div><div><span>cd</span><span> </span><span>/opt</span></div></div><div><div><div>6</div></div><div><span>wget</span><span> </span><span>https://nginx.org/download/nginx-1.16.1.tar.gz</span></div></div><div><div><div>7</div></div><div><span>tar</span><span> </span><span>zxvf</span><span> </span><span>nginx-1.16.1.tar.gz</span></div></div><div><div><div>8</div></div><div><span>cd</span><span> </span><span>nginx-1.16.1</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 获取 nginx-rtmp-module</span></div></div><div><div><div>11</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/arut/nginx-rtmp-module.git</span><span> </span><span>--depth=1</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># configure</span></div></div><div><div><div>14</div></div><div><span>./configure</span><span> </span><span>--prefix=/opt/nginx</span><span>  </span><span>--add-module=./nginx-rtmp-module/</span><span> </span><span>--with-http_ssl_module</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后稍等一下，不急着<code>make</code></p><p>使用<code>gcc -dumpversion</code>命令查看一下自己的 gcc 版本，特别是如果你用的是 WSL，预装的 gcc 应该是 8，版本是 7 及以上的必须改 makefile 来忽略 nginx 源码中 switch-case 没加 break 造成的 implicit fallthrough error</p><p>编辑<code>objs/Makefile</code>，在下面所示的这行上加个<code>-Wno-implicit-fallthrough</code></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 把</span></div></div><div><div><div>2</div></div><div><span>CFLAGS</span><span> </span><span>=</span><span>  </span><span>-pipe</span><span>  </span><span>-O</span><span> </span><span>-W</span><span> </span><span>-Wall</span><span> </span><span>-Wpointer-arith</span><span> </span><span>-Wno-unused-parameter</span><span> </span><span>-Werror</span><span> </span><span>-g</span></div></div><div><div><div>3</div></div><div><span># 改为</span></div></div><div><div><div>4</div></div><div><span>CFLAGS</span><span> </span><span>=</span><span>  </span><span>-pipe</span><span>  </span><span>-O</span><span> </span><span>-W</span><span> </span><span>-Wall</span><span> </span><span>-Wpointer-arith</span><span> </span><span>-Wno-unused-parameter</span><span> </span><span>-Werror</span><span> </span><span>-g</span><span> </span><span>-Wno-implicit-fallthrough</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>好，接下来就可以继续了</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>make</span><span> &amp;&amp; </span><span>make</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>2. 配置 nginx<a href="#2-配置-nginx"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 当前目录 /opt/nginx-1.16.1</span></div></div><div><div><div>2</div></div><div><span>cp</span><span> </span><span>nginx-rtmp-module/stat.xsl</span><span> </span><span>/opt/nginx/html</span></div></div><div><div><div>3</div></div><div><span>chown</span><span> </span><span>-R</span><span> </span><span>www:www</span><span> </span><span>/opt/nginx/html</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>接着修改<code>/opt/nginx/conf/nginx.conf</code>，首先将最前面<code>#user nobody;</code>修改为<code>user www;</code></p><p>在 http 配置块前加上 rtmp 配置</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>rtmp</span><span> {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>server</span><span> {</span></div></div><div><div><div>3</div></div><div><span>       <span> </span></span><span>listen </span><span>1935</span><span>;</span></div></div><div><div><div>4</div></div><div><span>        </span><span>application</span><span> app {</span></div></div><div><div><div>5</div></div><div><span>            </span><span>live</span><span> </span><span>on</span><span>;</span></div></div><div><div><div>6</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>8</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在 http 的 server 配置块中加入 rtmp 状态页面配置，<code>location /</code>直接修改原有即可</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>location</span><span> / {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>rtmp_stat</span><span> </span><span>all</span><span>;</span></div></div><div><div><div>3</div></div><div><span>    </span><span>rtmp_stat_stylesheet</span><span> stat.xsl;</span></div></div><div><div><div>4</div></div><div><span>}</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>location</span><span> /stat.xsl {</span></div></div><div><div><div>7</div></div><div><span>   <span> </span></span><span>root </span><span>/opt/nginx/html;</span></div></div><div><div><div>8</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>最好将 http 的 server 中的 listen 也改一下，因为我们编译的这个 nginx 只是拿来做推流劫持的，不会用来做别的事，所以不需要占用 80 端口，改成其他的可以避免以后做什么事需要用 80 端口导致冲突</p><p>在此处我改为<code>10080</code>，见下方完整配置</p><p>于是最终你的配置文件应该像这样（我删掉了自带注释）</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>user </span><span> www;</span></div></div><div><div><div>2</div></div><div><span>worker_processes </span><span> </span><span>1</span><span>;</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>events</span><span> {</span></div></div><div><div><div>5</div></div><div><span>   <span> </span></span><span>worker_connections </span><span> </span><span>1024</span><span>;</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>rtmp</span><span> {</span></div></div><div><div><div>9</div></div><div><span>    </span><span>server</span><span> {</span></div></div><div><div><div>10</div></div><div><span>       <span> </span></span><span>listen </span><span>1935</span><span>;</span></div></div><div><div><div>11</div></div><div><span>        </span><span>application</span><span> app {</span></div></div><div><div><div>12</div></div><div><span>            </span><span>live</span><span> </span><span>on</span><span>;</span></div></div><div><div><div>13</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>15</div></div><div><span>}</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>http</span><span> {</span></div></div><div><div><div>18</div></div><div><span>   <span> </span></span><span>include </span><span>      mime.types;</span></div></div><div><div><div>19</div></div><div><span>   <span> </span></span><span>default_type </span><span> application/octet-stream;</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span>   <span> </span></span><span>sendfile </span><span>          </span><span>on</span><span>;</span></div></div><div><div><div>22</div></div><div><span>   <span> </span></span><span>keepalive_timeout </span><span> </span><span>65</span><span>;</span></div></div><div><div><div>23</div></div><div>
</div></div><div><div><div>24</div></div><div><span>    </span><span>server</span><span> {</span></div></div><div><div><div>25</div></div><div><span>        </span><span># 改一下监听端口</span></div></div><div><div><div>26</div></div><div><span>       <span> </span></span><span>listen </span><span>      </span><span>10080</span><span>;</span></div></div><div><div><div>27</div></div><div><span>       <span> </span></span><span>server_name </span><span> localhost;</span></div></div><div><div><div>28</div></div><div>
</div></div><div><div><div>29</div></div><div><span>        </span><span>location</span><span> / {</span></div></div><div><div><div>30</div></div><div><span>            </span><span>rtmp_stat</span><span> </span><span>all</span><span>;</span></div></div><div><div><div>31</div></div><div><span>            </span><span>rtmp_stat_stylesheet</span><span> stat.xsl;</span></div></div><div><div><div>32</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div><span>        </span><span>location</span><span> /stat.xsl {</span></div></div><div><div><div>35</div></div><div><span>           <span> </span></span><span>root </span><span>/opt/nginx/html;</span></div></div><div><div><div>36</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>37</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>38</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>接着测试一下配置文件，没错误就可以启动 nginx 了</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 测试配置</span></div></div><div><div><div>2</div></div><div><span>/opt/nginx/sbin/nginx</span><span> </span><span>-t</span></div></div><div><div><div>3</div></div><div><span># 启动</span></div></div><div><div><div>4</div></div><div><span>/opt/nginx/sbin/nginx</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>3. 劫持 twitch 推流<a href="#3-劫持-twitch-推流"><span>#</span></a></h2><p>接下来只要劫持 live.twitch.tv 到 nginx 就行</p><p>需要注意的是，不能使用 hosts 方式，这对新版本的 PS4 系统无效，我试了下确实如此，所以我们使用 iptables 做 DNAT</p><p>首先用<code>dig</code>或者<code>nslookup</code>查看一下我们当前网络的 live.twitch.tv 被解析到哪里</p><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 以 dig 为例，没有的话需要安装</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>dnsutils</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>dig</span><span> </span><span>live.twitch.tv</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span># ; &lt;&lt;&gt;&gt; DiG 9.11.5-P4-5.1-Debian &lt;&lt;&gt;&gt; live.twitch.tv</span></div></div><div><div><div>7</div></div><div><span># ;; global options: +cmd</span></div></div><div><div><div>8</div></div><div><span># ;; Got answer:</span></div></div><div><div><div>9</div></div><div><span># ;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 36451</span></div></div><div><div><div>10</div></div><div><span># ;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1</span></div></div><div><div><div>11</div></div><div><span>#</span></div></div><div><div><div>12</div></div><div><span># ;; QUESTION SECTION:</span></div></div><div><div><div>13</div></div><div><span># ;live.twitch.tv.                        IN      A</span></div></div><div><div><div>14</div></div><div><span>#</span></div></div><div><div><div>15</div></div><div><span># ;; ANSWER SECTION:</span></div></div><div><div><div>16</div></div><div><span># live.twitch.tv.         600     IN      CNAME   live.video.twitch.tv.</span></div></div><div><div><div>17</div></div><div><span># live.video.twitch.tv.   600     IN      CNAME   live-beta.video.twitch.tv.</span></div></div><div><div><div>18</div></div><div><span># live-beta.video.twitch.tv. 600  IN      CNAME   live-hkg.twitch.tv.</span></div></div><div><div><div>19</div></div><div><span># live-hkg.twitch.tv.     600     IN      A       45.113.128.181</span></div></div><div><div><div>20</div></div><div><span># live-hkg.twitch.tv.     600     IN      A       45.113.128.147</span></div></div><div><div><div>21</div></div><div><span># live-hkg.twitch.tv.     600     IN      A       45.113.128.110</span></div></div><div><div><div>22</div></div><div><span>#</span></div></div><div><div><div>23</div></div><div><span># ;; Query time: 312 msec</span></div></div><div><div><div>24</div></div><div><span># ;; SERVER: 192.168.123.1#53(192.168.123.1)</span></div></div><div><div><div>25</div></div><div><span># ;; WHEN: Fri Sep 13 15:14:30 CST 2019</span></div></div><div><div><div>26</div></div><div><span># ;; MSG SIZE  rcvd: 321</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>我们可以看到记录有 3 个 IP，都在<code>45.113.128.0/24</code>中，所以我们就 DNAT 这个网段的 1935 端口到 nginx 所在设备的 1935 端口就行</p><p>在 openwrt 路由器或软路由上执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>iptables</span><span> </span><span>-t</span><span> </span><span>nat</span><span> </span><span>-I</span><span> </span><span>PREROUTING</span><span> </span><span>-d</span><span> </span><span>45.113.128.0/24</span><span> </span><span>-p</span><span> </span><span>tcp</span><span> </span><span>--dport</span><span> </span><span>1935</span><span> </span><span>-j</span><span> </span><span>DNAT</span><span> </span><span>--to-destination</span><span> </span><span>192.168.123.2:1935</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>我在 WSL 上运行 nginx，所以需要转发到我 PC 上，<code>192.168.123.2</code>是我 PC 的内网 IP，建议在路由器上配置给相应设备分配静态 IP</p><p>注意：如果你使用 WSL 或虚拟机，请关闭 Winddows 防火墙，或创建规则放行 1935 端口；若使用内网中的 linux 机器也应当检查防火墙确保端口开放</p></section>
<section><h2>4. 开启 PS4 直播推流<a href="#4-开启-ps4-直播推流"><span>#</span></a></h2><p>按下 share 键打开菜单，有个“播放游玩过程”，选 twitch 然后按说明绑定账号，设置推流分辨率之类的</p><p>开始推流之后访问 rtmp stat 页面，例如我自己这种部署方式就是 <a href="http://127.0.0.1:10080" target="_blank">http://127.0.0.1:10080</a> ，然后应该就能看到 live streams 下方出现了一条记录</p><p><img src="/usr/uploads/2019/09/1769422176.png" alt="" /></p><p>如果 app 写的是<code>[EMPTY]</code>的话那么 rtmp 地址就是<code>rtmp://127.0.0.1:1935/app/</code>
否则应该是<code>rtmp://127.0.0.1:1935/app/xxx</code></p><p>然后我们拿一个支持 rtmp 的播放器测试一下，顺利的话就应该能看到 PS4 的画面了（好耶</p><p><img src="/usr/uploads/2019/09/855334774.jpg" alt="" /></p></section>
<section><h2>5. 推流到直播平台<a href="#5-推流到直播平台"><span>#</span></a></h2><p>有两种方式，看自己需求选择</p><section><h3>(1) 直接推流<a href="#1-直接推流"><span>#</span></a></h3><p>这种方式相当于原封不动地推流到其他直播平台，好处是不用再开推流软件，但我自己试的时候不知为何推流画质十分惨烈</p><p>修改 nginx 配置，在 rtmp 配置块中的<code>live on;</code>下面添加一行<code>push rtmp://[直播推流带key的完整地址];</code>即可</p><p>例如这是推流到B站的示例</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>push rtmp://js.live-send.acg.tv/live-js/?streamname=[name]&amp;key=[key];</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>修改完配置只要<code>/opt/nginx/sbin/nginx -s reload</code>即可重载配置</p></section><section><h3>(2) 使用 obs 再推流<a href="#2-使用-obs-再推流"><span>#</span></a></h3><p>大部分情况下你可能想用 obs 做些处理再推流，这很简单，只要添加“媒体源”，去掉“本地文件”勾选，在“输入”中贴上 rtmp 地址即可</p></section></section>
<section><h2>6. 自启动<a href="#6-自启动"><span>#</span></a></h2><section><h3>nginx 方面<a href="#nginx-方面"><span>#</span></a></h3><p>普通 linux 上自启动 nginx 应该不用我多说，改<code>/etc/rc.local</code></p><p>若使用 WSL，你可以在 PC 上创建一个 vbs 脚本，例如<code>nginx-rtmp.vbs</code>，内容如下</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Set</span><span> </span><span>ws</span><span> </span><span>=</span><span> </span><span>CreateObject</span><span>(</span><span>"Wscript.Shell"</span><span>)</span></div></div><div><div><div>2</div></div><div><span>ws.run</span><span> </span><span>"wsl /opt/nginx/sbin/nginx",</span><span> </span><span>vbhide</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后把这个脚本扔到 Windows 的启动目录<code>C:\Users\[用户名]\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup</code>即可</p><p>使用 vbs 的原因是 vbhide 可以让命令执行的时候不会有一个 cmd 窗一瞬出现影响观感</p></section><section><h3>iptables 方面<a href="#iptables-方面"><span>#</span></a></h3><p>这一方面情况比较复杂，只是路由器启动时加 iptables 规则的话，可以简单的写在路由器启动脚本里就行</p><p>但有些时候，例如启动 ss，可能会清空你的 nat 表，这时候需要重新添加，总之就看你自己实际情况将命令也放在 ss 启动脚本里什么的</p><p>一劳永逸的简便的方法是写个守护脚本，我就不贴脚本了，因为我自己都还懒得去写（</p></section></section>
<section><h2>后记<a href="#后记"><span>#</span></a></h2><p>这个方法最大的缺点是，无法与加速器同时使用</p><p>目前市面上的加速器基本都是在 PC 上起一个 TAP Adapter 然后让 PS4 连，这样所有的流量都会走加速器出去，iptables 无法劫持</p><p>不过有些加速器也有提供路由器插件，我没有实际用过因为没有“支持”插件的路由器，说不定这种情况下有方法可以实现同时使用</p><p>另外，如果路由器上用的是 DNSMasq，配合 ipset 应该可以实现自动将 live.twitch.tv 的 IP 加到 ipset 中，然后 iptables 规则就可以直接使用 ipset，而不用自己手写网段了</p></section>
<section><h2>参考<a href="#参考"><span>#</span></a></h2><ul>
<li><a href="https://homulilly.com/post/play-ps4-live-stream-at-local.html" target="_blank">搭建 PS4 本地直播服务器</a></li>
<li><a href="http://colinzhang.com/2015/10/how-to-push-play-station-4-live-stream-with-lower-cost/" target="_blank">如何用最低的成本转播PlayStation 4到国内的直播平台</a></li>
<li><a href="https://blog.csdn.net/jaybill/article/details/80164370" target="_blank">linux下编译nginx1.0.15报错：Implicit fallthrough error</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/vue-pwa/</id>
      <title type="text">为 Vue 项目添加 PWA 支持</title>
      <published>2019-06-26T08:18:00.000Z</published>
      <updated>2022-03-22T04:34:13.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/vue-pwa/"/>
      <summary type="text">前段时间摸鱼终于摸到了 Service Worker 这块，顺理成章的接触了 PWA，于是用这篇文章记录下如何为一个 vue 应用添加 PWA 支持，包括中途遇到的一些坑点和一些技巧</summary>
      <content type="html"><![CDATA[<p>前段时间摸鱼终于摸到了 Service Worker 这块，顺理成章的接触了 PWA，于是用这篇文章记录下如何为一个 vue 应用添加 PWA 支持，包括中途遇到的一些坑点和一些技巧</p>
<p>Head Pic:<a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=75393724" target="_blank">【オリジナル】「Recital」/「RH」的插画 [pixiv]</a></p>
<hr />
<p>如果您的目的不是为现有的 vue 项目添加 PWA 支持，那么更推荐尝试 <a href="https://lavas.baidu.com/" target="_blank">Lavas</a></p>
<p>注：PWA 应用要求必须全程 https，且在已安装的 PWA 应用中无法发送 http 请求</p>
<section><h2>为已有项目添加 PWA 支持<a href="#为已有项目添加-pwa-支持"><span>#</span></a></h2><section><h3>1. 安装 PWA 插件<a href="#1-安装-pwa-插件"><span>#</span></a></h3><p>如果你已经在使用<code>@vue/cli</code>，那么可以直接在可视化界面中安装 PWA 插件</p><p><img src="/usr/uploads/2019/06/981132562.png" alt="" /></p><p>否则，可以通过<code>vue add @vue/pwa</code>命令来安装</p><p>该插件会使用谷歌的 PWA 框架 <a href="https://developers.google.com/web/tools/workbox/" target="_blank">Workbox</a></p></section><section><h3>2. 配置 PWA 插件<a href="#2-配置-pwa-插件"><span>#</span></a></h3><p>需要创建或修改项目中的<code>vue.config.js</code>，配置项以及示例在<a href="https://www.npmjs.com/package/@vue/cli-plugin-pwa#configuration" target="_blank">此处</a></p><p>我想多提几句的配置项有三个：</p><section><h4>workboxPluginMode<a href="#workboxpluginmode"><span>#</span></a></h4><p>可选配置项，默认为<code>GenerateSW</code></p><p><code>GenerateSW</code>与<code>InjectManifest</code>如何选择：</p><ul>
<li>如果你只是想简单地将项目 PWA 化，选择<code>GenerateSW</code>，插件会自动帮你生成包含 precache manifest 的<code>service-worker.js</code></li>
<li>如果你有较高的定制需求，需要在已有 Service Worker 的基础上将项目 PWA 化，则选择<code>InjectManifest</code>，插件会在你指定的<code>service-worker.js</code>的基础上加入 precache manifest</li>
</ul></section><section><h4>workboxOptions<a href="#workboxoptions"><span>#</span></a></h4><p>配置项，请对应<code>workboxPluginMode</code>来参考</p><ul>
<li><a href="https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin#full_generatesw_config" target="_blank">GenerateSW</a></li>
<li><a href="https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin#full_generatesw_config" target="_blank">InjectManifest</a>（必须指定<code>swSrc</code>）</li>
</ul><p>通过配置可以做到的一些常用操作：</p><ol>
<li>将指定（或指定文件夹中的）文件添加到 precache manifest 中，或从中排除，支持使用正则表达式</li>
<li>自动跳过 Service Worker 的等待阶段</li>
<li>添加离线 Google Analytics 支持</li>
<li>运行时缓存<code>runtimeCaching</code>，Workbox 的强大所在，阅读这些内容会使你更好地了解如何配置以及具体能做什么：</li>
</ol><ul>
<li><a href="https://developers.google.com/web/tools/workbox/modules/workbox-routing" target="_blank">Workbox Routing</a></li>
<li><a href="https://developers.google.com/web/tools/workbox/modules/workbox-strategies" target="_blank">Workbox Strategies</a></li>
<li><a href="https://developers.google.com/web/tools/workbox/modules/workbox-cache-expiration" target="_blank">Workbox Cache Expiration</a></li>
</ul></section><section><h4>iconPaths<a href="#iconpaths"><span>#</span></a></h4><p>该设置项可以自定义在页面<code>&lt;head&gt;</code>中添加的一些图标的<code>&lt;link&gt;</code>或<code>&lt;meta&gt;</code>中指定的文件路径</p><p><code>public/icons</code>中有安装插件时生成的默认图标</p><p>其有一个坑点，就是你无法设置<strong>不去添加</strong>某些<code>&lt;link&gt;</code>或<code>&lt;meta&gt;</code>，也就是强制性的</p><p>这主要会影响到<code>maskIcon</code>，是 Macbook 的 Touch Bar 上的图标，由于要求必须是 svg，个人开发的小应用一般懒得去制作这个图标，但又无法不去添加这个<code>&lt;link&gt;</code></p><p>几个可能对你有帮助的 icon 制作工具：</p><ul>
<li><a href="https://lolicon.dev/#/image/png2ico" target="_blank">https://lolicon.dev/#/image/png2ico</a></li>
<li><a href="https://www.websiteplanet.com/webtools/favicon-generator/" target="_blank">https://www.websiteplanet.com/webtools/favicon-generator/</a></li>
<li><a href="https://realfavicongenerator.net" target="_blank">https://realfavicongenerator.net</a></li>
</ul></section></section><section><h3>3. 配置<code>manifest.json</code><a href="#3-配置manifestjson"><span>#</span></a></h3><p>位于<code>public/manifest.json</code>，安装插件时自动生成，参考 <a href="https://developer.mozilla.org/zh-CN/docs/Web/Manifest" target="_blank">Web App Manifest</a> 进行配置</p></section></section>
<section><h2>引导用户添加 PWA 应用<a href="#引导用户添加-pwa-应用"><span>#</span></a></h2><p>在应用中可以自行通过提示等方式引导用户手动添加 PWA 应用，以下列举目前我所知道的添加方式</p><section><h3>Chrome 专有方式<a href="#chrome-专有方式"><span>#</span></a></h3><p>对于 PC 或 Android 的 Chrome 浏览器都可以实现点击一个按钮来添加 PWA 应用，其原理是拦截了<code>beforeinstallprompt</code>这一事件，并在自己需要的时候触发</p><p>例如我们可以在项目的根 vue 实例中（以下示例省略了挂载及渲染等操作）</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>new</span><span> </span><span>Vue</span><span>({</span></div></div><div><div><div>2</div></div><div><span>  </span><span>data</span><span>:</span><span> {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>deferredPrompt</span><span>:</span><span> </span><span>false</span><span>,</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>5</div></div><div><span>  </span><span>created</span><span>() {</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>window</span><span>.</span><span>addEventListener</span><span>(</span><span>"beforeinstallprompt"</span><span><span>, (</span><span>e</span><span>) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>e</span><span>.</span><span>preventDefault</span><span>();</span></div></div><div><div><div>8</div></div><div><span>      </span><span>this</span><span>.</span><span>deferredPrompt</span><span> </span><span>=</span><span><span> </span><span>e</span><span>;</span></span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>11</div></div><div><span>  </span><span>methods</span><span>:</span><span> {</span></div></div><div><div><div>12</div></div><div><span>    </span><span>installPWA</span><span>() {</span></div></div><div><div><div>13</div></div><div><span>      </span><span>if</span><span> (</span><span>this</span><span>.</span><span>deferredPrompt</span><span>) {</span></div></div><div><div><div>14</div></div><div><span>        </span><span>this</span><span>.</span><span>deferredPrompt</span><span>.</span><span>prompt</span><span>();</span></div></div><div><div><div>15</div></div><div><span>        </span><span>this</span><span>.</span><span>deferredPrompt</span><span> </span><span>=</span><span> </span><span>false</span><span>;</span></div></div><div><div><div>16</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>17</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>18</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>19</div></div><div><span>});</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>然后就可以像这样自由地在任何 template 中使用了</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>button</span><span> </span><span>@click</span><span>=</span><span>"$root.installPWA"</span><span> </span><span>:disabled</span><span>=</span><span>"$root.deferredPrompt===false"</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>添加到主屏幕</span></div></div><div><div><div>3</div></div><div><span>&lt;/</span><span>button</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>手动添加方式<a href="#手动添加方式"><span>#</span></a></h3><p>iOS ≥ 11.3 可以在 Safari 中打开，点击浏览器底部的分享按钮，选择“添加到主屏幕”</p><p>PC 与 Android 的 Chrome 可通过右上角菜单添加（此处以 <a href="https://m.weibo.cn" target="_blank">m.weibo.cn</a> 为例）</p>

<table><thead><tr><th>PC</th><th>Android</th></tr></thead><tbody><tr><td><img src="/usr/uploads/2019/06/1138841713.png" alt="" /></td><td><img src="/usr/uploads/2019/06/4059793851.png" alt="" /></td></tr></tbody></table></section></section>
<section><h2>Service Worker 的更新<a href="#service-worker-的更新"><span>#</span></a></h2><p>这是开发 PWA 应用时需要考虑的一个重要问题</p><p>由于 Service Worker 的更新机制（扩展阅读：<a href="https://segmentfault.com/a/1190000007487049" target="_blank">【Service Worker】生命周期那些事儿</a>），直接单纯的刷新页面并没有结束当前 session，因此依然是旧的 SW 在接管页面，新的 SW 仍旧是 waiting 状态</p><p>想要实现在不结束 session 的情况下更新 SW，必须使用 skipWaiting，目前有两种常见的处理方法</p><p>注：以下方法中提到的<code>registerServiceWorker.js</code>是由 PWA 插件在<code>src</code>目录中自动生成的，其作用是注册 SW 以及提供其生命周期钩子，具体可以看该 npm 包 <a href="https://www.npmjs.com/package/register-service-worker" target="_blank">register-service-worker</a></p><section><h3>方法一：直接 skipWaiting，并引导用户刷新<a href="#方法一直接-skipwaiting并引导用户刷新"><span>#</span></a></h3><p>这种方法非常暴力且简单，你只需要在步骤2提到的<code>workboxOptions</code>中将<code>skipWaiting</code>设置为<code>true</code>就行了，然后在<code>registerServiceWorker.js</code>中的<code>updated()</code>函数里做一些操作，例如弹出一个对话框来提示用户点击某个按钮以刷新页面</p><p>该方法对仅 precache 应用是没有任何影响的</p><p>但由于 skipWaiting 后新 SW 会立即接管页面，因此如果你更新了 SW 在处理 runtimeCaching 之类的运行时操作的行为而用户又没有刷新页面，就有可能会出现问题</p><p>即除非你能保证同一个页面在两个版本的 SW 相继处理的情况下依然能够正常工作，否则不要使用这个方法</p></section><section><h3>方法二：等待用户同意再 skipWaiting 并刷新<a href="#方法二等待用户同意再-skipwaiting-并刷新"><span>#</span></a></h3><p>该方法可以解决方法一的局限性，我们可以先弹出一个对话框询问用户是否要更新，用户同意后再 skipWaiting 并刷新</p><p>关于这种方法，我只描述大致的思路和做法，因为我没有实际完整地实践过，因为比较复杂麻烦（好的下面我就开始云了）</p><p>我们需要在<code>workboxOptions</code>中将<code>skipWaiting</code>设置为<code>false</code>，或者不设置，因为默认值为<code>false</code></p><p>此处，官方文档中提到，当<code>skipWaiting</code>为<code>false</code>的时候，生成的 SW 会加入以下代码</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>self</span><span>.</span></span><span>addEventListener</span><span>(</span><span>"message"</span><span><span>, (</span><span>event</span><span>) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>if</span><span><span> (</span><span>event</span><span>.</span></span><span>data</span><span> </span><span>&amp;&amp;</span><span><span> </span><span>event</span><span>.</span></span><span>data</span><span>.</span><span>type</span><span> </span><span>===</span><span> </span><span>"SKIP_WAITING"</span><span>) {</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>self</span><span>.</span><span>skipWaiting</span><span>();</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>5</div></div><div><span>});</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>其作用是当 SW 接收到<code>{type:'SKIP_WAITING'}</code>的消息后，SW 就会 skipWaiting</p><p>但实际情况是，最终生成的 SW 中并没有这一段代码（也并没有放置在其他 js 中），我猜测这可能是因为加入代码的这一特性是 Workbox 4 才加入的，而插件生成的 SW 引用的是 Workbox 3 的缘故……</p><p>对于这个问题有两种可能的解决方法：</p><ol>
<li>将<code>workboxPluginMode</code>设置为<code>InjectManifest</code>，然后自己指定一个 SW 里面加上该代码内容</li>
<li>从谷歌那里下载最新的 Workbox 放置在项目内，并配置<code>workboxOptions</code>中的<code>importWorkboxFrom</code>为<code>disable</code>，然后在<code>importScripts</code>中指定本地<code>workbox-sw.js</code>的路径</li>
</ol><p>接着在<code>registerServiceWorker.js</code>中我们可以如下所示在<code>updated()</code>函数中加入一些内容，询问用户是否愿意重载页面以更新应用，若用户同意则向 waiting 状态的 SW 发送<code>{type:'SKIP_WAITING'}</code>消息，并在新 SW 控制页面后立即刷新</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>updated</span><span><span>(</span><span>reg</span><span>) {</span></span></div></div><div><div><div>2</div></div><div><span>  </span><span>// 当控制页面的 SW 改变时刷新</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>navigator</span><span>.</span><span>serviceWorker</span><span>.</span><span>addEventListener</span><span>(</span><span>'controllerchange'</span><span>, () </span><span>=&gt;</span><span> {</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>window</span><span>.</span><span>location</span><span>.</span><span>reload</span><span>();</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>6</div></div><div><span>  </span><span>// 接下来询问用户是否更新并重载应用</span></div></div><div><div><div>7</div></div><div><span>  </span><span>// 用户同意则执行以下语句</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>reg</span><span>.</span><span>waiting</span><span>.</span><span>postMessage</span><span>({ </span><span>type</span><span>:</span><span> </span><span>'SKIP_WAITING'</span><span> });</span></div></div><div><div><div>9</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/lodash-akhr/</id>
      <title type="text">[Lodash] 明日方舟公开招募计算器的简单实现</title>
      <published>2019-05-22T15:20:00.000Z</published>
      <updated>2019-12-05T04:46:06.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/lodash-akhr/"/>
      <summary type="text">水文章（x</summary>
      <content type="html"><![CDATA[<p>水文章（x</p>
<p>Head Pic：<a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=74627781" target="_blank">【明日方舟】「series」/「Alcxome」的插画 [pixiv]</a></p>
<hr />
<p>差不多一周前还是经不住劝诱被基友拉入了坑，对刚入坑还不熟悉角色池的人来说，公开招募计算器是非常有用且必要的工具</p>
<p>之前我一直用的是 <a href="https://graueneko.github.io/akhr.html" target="_blank">graueneko.github.io</a>，做的非常好，而后面我懒癌发作，因此想能不能将这个功能也整合进<a href="/posts/qq-robot-picfinder/">我自己写的QQ机器人</a>里，利用现成的 OCR 做到：直接识别截图获取词条-&gt;计算可能的词条组合及其包含的干员-&gt;输出</p>
<p>但一开始的词条排列组合问题就让我感到头疼，如果要自己用动态规划来降低计算量和复杂度又感觉很麻烦，因为当时脑子瓦特了想不到什么简便的储存词条组合中间结果的方法（后来才想起可以排序后用 hash 或者直接拼接作为 key 啊真蠢）</p>
<p>在神的指引下我想起了还有 <a href="https://www.lodashjs.com" target="_blank">Lodash</a>，并且发现其很适合写这类需要对数组进行大量操作的算法，于是决定写一个来练习一下</p>
<section><h2>1. 数据预处理<a href="#1-数据预处理"><span>#</span></a></h2><p>还是要感谢 graueneko 等人的工作，已经将<a href="https://graueneko.github.io/akhr.json" target="_blank">干员数据</a>整理成了 json 格式，可以方便的直接拿来使用</p><p>那么首先需要明确，要做的是一个公开招募计算器，得到最终结果的算法大致如下</p><ol>
<li>计算指定词条的所有排列组合方案</li>
<li>对每种方案，找到满足这些词条的干员，并对方案进行评分</li>
<li>按评分对所有有效方案进行排序</li>
</ol><p>实现的重点是第2步，而干员数据的结构是<strong>干员-&gt;词条</strong>，每当我们想寻找满足某些词条的干员，我们都必须把列表遍历一遍，这是非常麻烦的</p><p>因此我们可以换一种储存方式，使结构变为<strong>词条-&gt;干员</strong>，这样比如我们想寻找同时拥有<strong>词条A</strong>和<strong>词条B</strong>的干员，只需要<strong>求A和B的交集</strong>就行了</p><p>以下是示例：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> { </span><span>get</span><span> } </span><span>from</span><span> </span><span>"axios"</span><span>;</span></div></div><div><div><div>2</div></div><div><span>import</span><span> </span><span>_</span><span> </span><span>from</span><span> </span><span>"lodash"</span><span>;</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>const</span><span> </span><span>akhr</span><span> </span><span>=</span><span> </span><span>"https://graueneko.github.io/akhr.json"</span><span>;</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>async</span><span> </span><span>function</span><span> </span><span>pullData</span><span>() {</span></div></div><div><div><div>7</div></div><div><span>  </span><span>let</span><span><span> </span><span>json</span><span> </span></span><span>=</span><span> </span><span>await</span><span> </span><span>get</span><span><span>(</span><span>akhr</span><span>).</span></span><span>then</span><span><span>((</span><span>r</span><span>) </span></span><span>=&gt;</span><span><span> </span><span>r</span><span>.</span></span><span>data</span><span>);</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>  </span><span>//将干员按照稀有度从高到低排序，后续输出的时候就不用再排序了</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>json</span><span>.</span><span>sort</span><span><span>((</span><span>a</span><span>, </span><span>b</span><span>) </span></span><span>=&gt;</span><span><span> </span><span>b</span><span>.</span></span><span>level</span><span> </span><span>-</span><span><span> </span><span>a</span><span>.</span></span><span>level</span><span>);</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>  </span><span>let</span><span><span> </span><span>characters</span><span> </span></span><span>=</span><span> []; </span><span>//角色列表</span></div></div><div><div><div>13</div></div><div><span>  </span><span>let</span><span><span> </span><span>data</span><span> </span></span><span>=</span><span> {}; </span><span>//词条数据</span></div></div><div><div><div>14</div></div><div><span>  </span><span>let</span><span><span> </span><span>charTagSum</span><span> </span></span><span>=</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span>  </span><span>for</span><span> (</span><span>let</span><span><span> </span><span>character</span><span> </span></span><span>of</span><span><span> </span><span>json</span><span>) {</span></span></div></div><div><div><div>17</div></div><div><span>    </span><span>if</span><span><span> (</span><span>character</span><span>.</span></span><span>hidden</span><span>) </span><span>continue</span><span>;</span></div></div><div><div><div>18</div></div><div><span>    </span><span>let</span><span><span> { </span><span>level</span><span>, </span><span>name</span><span>, </span><span>sex</span><span>, </span><span>tags</span><span>, </span><span>type</span><span> } </span></span><span>=</span><span><span> </span><span>character</span><span>;</span></span></div></div><div><div><div>19</div></div><div><span>    </span><span>//将性别和干员种类也加入词条中</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>tags</span><span>.</span><span>push</span><span>(</span><span>`</span><span>${</span><span>sex</span><span>}</span><span>性干员`</span><span>);</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>tags</span><span>.</span><span>push</span><span>(</span><span>`</span><span>${</span><span>type</span><span>}</span><span>干员`</span><span>);</span></div></div><div><div><div>22</div></div><div><span>    </span><span>//将干员放入 characters 数组，后续直接用其在数组中的 index 指代</span></div></div><div><div><div>23</div></div><div><span>    </span><span>let</span><span><span> </span><span>p</span><span> </span></span><span>=</span></div></div><div><div><div>24</div></div><div><span><span>      </span></span><span>characters</span><span>.</span><span>push</span><span>({</span></div></div><div><div><div>25</div></div><div><span>        </span><span>n</span><span>:</span><span><span> </span><span>name</span><span>, </span></span><span>//名字</span></div></div><div><div><div>26</div></div><div><span>        </span><span>r</span><span>:</span><span><span> </span><span>level</span><span>, </span></span><span>//稀有度</span></div></div><div><div><div>27</div></div><div><span><span>      </span></span><span>}) </span><span>-</span><span> </span><span>1</span><span>;</span></div></div><div><div><div>28</div></div><div><span>    </span><span>//储存：词条-&gt;干员</span></div></div><div><div><div>29</div></div><div><span>    </span><span>for</span><span> (</span><span>let</span><span><span> </span><span>tag</span><span> </span></span><span>of</span><span><span> </span><span>tags</span><span>) {</span></span></div></div><div><div><div>30</div></div><div><span>      </span><span>if</span><span> (</span><span>!</span><span><span>data</span><span>[</span><span>tag</span><span>]) </span><span>data</span><span>[</span><span>tag</span><span>] </span></span><span>=</span><span> [];</span></div></div><div><div><div>31</div></div><div><span><span>      </span></span><span>data</span><span>[</span><span>tag</span><span>].</span><span>push</span><span><span>(</span><span>p</span><span>);</span></span></div></div><div><div><div>32</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>33</div></div><div><span><span>    </span></span><span>charTagSum</span><span> </span><span>+=</span><span><span> </span><span>tags</span><span>.</span></span><span>length</span><span>;</span></div></div><div><div><div>34</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>35</div></div><div>
</div></div><div><div><div>36</div></div><div><span>  </span><span>let</span><span><span> </span><span>tagCount</span><span> </span></span><span>=</span><span><span> </span><span>_</span><span>.</span></span><span>size</span><span><span>(</span><span>data</span><span>);</span></span></div></div><div><div><div>37</div></div><div><span>  </span><span>return</span><span> {</span></div></div><div><div><div>38</div></div><div><span><span>    </span></span><span>characters</span><span>,</span></div></div><div><div><div>39</div></div><div><span><span>    </span></span><span>data</span><span>,</span></div></div><div><div><div>40</div></div><div><span>    </span><span>//这是后续计算评分用的数据（来自 graueneko）</span></div></div><div><div><div>41</div></div><div><span>    </span><span>avgCharTag</span><span>:</span><span><span> </span><span>charTagSum</span><span> </span></span><span>/</span><span><span> </span><span>tagCount</span><span>,</span></span></div></div><div><div><div>42</div></div><div><span><span>  </span></span><span>};</span></div></div><div><div><div>43</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>然后就能得到这样子的数据结构</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"characters"</span><span>: [</span></div></div><div><div><div>3</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"推进之王"</span><span>, </span><span>"r"</span><span>: </span><span>6</span><span> },</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"闪灵"</span><span>, </span><span>"r"</span><span>: </span><span>6</span><span> },</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"夜莺"</span><span>, </span><span>"r"</span><span>: </span><span>6</span><span> },</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"伊芙利特"</span><span>, </span><span>"r"</span><span>: </span><span>6</span><span> },</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"能天使"</span><span>, </span><span>"r"</span><span>: </span><span>6</span><span> },</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"银灰"</span><span>, </span><span>"r"</span><span>: </span><span>6</span><span> },</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"星熊"</span><span>, </span><span>"r"</span><span>: </span><span>6</span><span> },</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"塞雷娅"</span><span>, </span><span>"r"</span><span>: </span><span>6</span><span> },</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"德克萨斯"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"凛冬"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"白面鸮"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"赫默"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"华法琳"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"红"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>17</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"狮蝎"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>18</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"崖心"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>19</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"食铁兽"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"普罗旺斯"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"蓝毒"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>22</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"守林人"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"陨星"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>24</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"白金"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>25</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"初雪"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>26</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"真理"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>27</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"梅尔"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>28</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"幽灵鲨"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>29</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"因陀罗"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>30</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"临光"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>31</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"雷蛇"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>32</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"火神"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>33</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"可颂"</span><span>, </span><span>"r"</span><span>: </span><span>5</span><span> },</span></div></div><div><div><div>34</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"清道夫"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>35</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"红豆"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>36</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"末药"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>37</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"调香师"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>38</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"夜烟"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>39</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"远山"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>40</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"砾"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>41</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"暗索"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>42</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"阿消"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>43</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"白雪"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>44</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"流星"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>45</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"杰西卡"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>46</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"地灵"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>47</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"杜宾"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>48</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"艾丝黛尔"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>49</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"慕斯"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>50</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"霜叶"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>51</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"缠丸"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>52</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"蛇屠箱"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>53</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"古米"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>54</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"角峰"</span><span>, </span><span>"r"</span><span>: </span><span>4</span><span> },</span></div></div><div><div><div>55</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"芬"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>56</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"香草"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>57</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"翎羽"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>58</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"芙蓉"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>59</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"安赛尔"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>60</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"炎熔"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>61</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"史都华德"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>62</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"克洛丝"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>63</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"安德切尔"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>64</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"梓兰"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>65</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"玫兰莎"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>66</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"米格鲁"</span><span>, </span><span>"r"</span><span>: </span><span>3</span><span> },</span></div></div><div><div><div>67</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"夜刀"</span><span>, </span><span>"r"</span><span>: </span><span>2</span><span> },</span></div></div><div><div><div>68</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"杜林"</span><span>, </span><span>"r"</span><span>: </span><span>2</span><span> },</span></div></div><div><div><div>69</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"12F"</span><span>, </span><span>"r"</span><span>: </span><span>2</span><span> },</span></div></div><div><div><div>70</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"巡林者"</span><span>, </span><span>"r"</span><span>: </span><span>2</span><span> },</span></div></div><div><div><div>71</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"黑角"</span><span>, </span><span>"r"</span><span>: </span><span>2</span><span> },</span></div></div><div><div><div>72</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"Lancet-2"</span><span>, </span><span>"r"</span><span>: </span><span>1</span><span> },</span></div></div><div><div><div>73</div></div><div><span><span>    </span></span><span>{ </span><span>"n"</span><span>: </span><span>"Castle-3"</span><span>, </span><span>"r"</span><span>: </span><span>1</span><span> }</span></div></div><div><div><div>74</div></div><div><span><span>  </span></span><span>],</span></div></div><div><div><div>75</div></div><div><span>  </span><span>"data"</span><span>: {</span></div></div><div><div><div>76</div></div><div><span>    </span><span>"近战位"</span><span>: [</span></div></div><div><div><div>77</div></div><div><span>      </span><span>0</span><span>, </span><span>5</span><span>, </span><span>6</span><span>, </span><span>7</span><span>, </span><span>8</span><span>, </span><span>9</span><span>, </span><span>13</span><span>, </span><span>14</span><span>, </span><span>15</span><span>, </span><span>16</span><span>, </span><span>25</span><span>, </span><span>26</span><span>, </span><span>27</span><span>, </span><span>28</span><span>, </span><span>29</span><span>, </span><span>30</span><span>, </span><span>31</span><span>, </span><span>32</span><span>, </span><span>37</span><span>, </span><span>38</span><span>,</span></div></div><div><div><div>78</div></div><div><span>      </span><span>39</span><span>, </span><span>44</span><span>, </span><span>45</span><span>, </span><span>46</span><span>, </span><span>47</span><span>, </span><span>48</span><span>, </span><span>49</span><span>, </span><span>50</span><span>, </span><span>51</span><span>, </span><span>52</span><span>, </span><span>53</span><span>, </span><span>54</span><span>, </span><span>62</span><span>, </span><span>63</span><span>, </span><span>64</span><span>, </span><span>68</span><span>, </span><span>70</span></div></div><div><div><div>79</div></div><div><span><span>    </span></span><span>],</span></div></div><div><div><div>80</div></div><div><span>    </span><span>"费用回复"</span><span>: [</span><span>0</span><span>, </span><span>8</span><span>, </span><span>9</span><span>, </span><span>31</span><span>, </span><span>32</span><span>, </span><span>52</span><span>, </span><span>53</span><span>, </span><span>54</span><span>],</span></div></div><div><div><div>81</div></div><div><span>    </span><span>"输出"</span><span>: [</span></div></div><div><div><div>82</div></div><div><span>      </span><span>0</span><span>, </span><span>4</span><span>, </span><span>5</span><span>, </span><span>6</span><span>, </span><span>14</span><span>, </span><span>15</span><span>, </span><span>17</span><span>, </span><span>18</span><span>, </span><span>19</span><span>, </span><span>21</span><span>, </span><span>23</span><span>, </span><span>26</span><span>, </span><span>28</span><span>, </span><span>29</span><span>, </span><span>31</span><span>, </span><span>32</span><span>, </span><span>35</span><span>, </span><span>41</span><span>, </span><span>42</span><span>,</span></div></div><div><div><div>83</div></div><div><span>      </span><span>44</span><span>, </span><span>46</span><span>, </span><span>47</span><span>, </span><span>48</span><span>, </span><span>54</span><span>, </span><span>58</span><span>, </span><span>59</span><span>, </span><span>60</span><span>, </span><span>62</span></div></div><div><div><div>84</div></div><div><span><span>    </span></span><span>],</span></div></div><div><div><div>85</div></div><div><span>    </span><span>"高级资深干员"</span><span>: [</span><span>0</span><span>, </span><span>1</span><span>, </span><span>2</span><span>, </span><span>3</span><span>, </span><span>4</span><span>, </span><span>5</span><span>, </span><span>6</span><span>, </span><span>7</span><span>],</span></div></div><div><div><div>86</div></div><div><span>    </span><span>"女性干员"</span><span>: [</span></div></div><div><div><div>87</div></div><div><span>      </span><span>0</span><span>, </span><span>1</span><span>, </span><span>2</span><span>, </span><span>3</span><span>, </span><span>4</span><span>, </span><span>6</span><span>, </span><span>7</span><span>, </span><span>8</span><span>, </span><span>9</span><span>, </span><span>10</span><span>, </span><span>11</span><span>, </span><span>12</span><span>, </span><span>13</span><span>, </span><span>14</span><span>, </span><span>15</span><span>, </span><span>16</span><span>, </span><span>17</span><span>, </span><span>18</span><span>, </span><span>19</span><span>, </span><span>20</span><span>, </span><span>21</span><span>,</span></div></div><div><div><div>88</div></div><div><span>      </span><span>22</span><span>, </span><span>23</span><span>, </span><span>24</span><span>, </span><span>25</span><span>, </span><span>26</span><span>, </span><span>27</span><span>, </span><span>28</span><span>, </span><span>29</span><span>, </span><span>30</span><span>, </span><span>31</span><span>, </span><span>32</span><span>, </span><span>33</span><span>, </span><span>34</span><span>, </span><span>35</span><span>, </span><span>36</span><span>, </span><span>37</span><span>, </span><span>38</span><span>, </span><span>39</span><span>,</span></div></div><div><div><div>89</div></div><div><span>      </span><span>40</span><span>, </span><span>41</span><span>, </span><span>42</span><span>, </span><span>43</span><span>, </span><span>44</span><span>, </span><span>45</span><span>, </span><span>46</span><span>, </span><span>47</span><span>, </span><span>48</span><span>, </span><span>49</span><span>, </span><span>50</span><span>, </span><span>52</span><span>, </span><span>53</span><span>, </span><span>54</span><span>, </span><span>55</span><span>, </span><span>57</span><span>, </span><span>59</span><span>, </span><span>61</span><span>,</span></div></div><div><div><div>90</div></div><div><span>      </span><span>62</span><span>, </span><span>63</span><span>, </span><span>64</span><span>, </span><span>65</span><span>, </span><span>69</span></div></div><div><div><div>91</div></div><div><span><span>    </span></span><span>],</span></div></div><div><div><div>92</div></div><div><span>    </span><span>"先锋干员"</span><span>: [</span><span>0</span><span>, </span><span>8</span><span>, </span><span>9</span><span>, </span><span>31</span><span>, </span><span>32</span><span>, </span><span>52</span><span>, </span><span>53</span><span>, </span><span>54</span><span>, </span><span>64</span><span>],</span></div></div><div><div><div>93</div></div><div><span>    </span><span>"远程位"</span><span>: [</span></div></div><div><div><div>94</div></div><div><span>      </span><span>1</span><span>, </span><span>2</span><span>, </span><span>3</span><span>, </span><span>4</span><span>, </span><span>10</span><span>, </span><span>11</span><span>, </span><span>12</span><span>, </span><span>17</span><span>, </span><span>18</span><span>, </span><span>19</span><span>, </span><span>20</span><span>, </span><span>21</span><span>, </span><span>22</span><span>, </span><span>23</span><span>, </span><span>24</span><span>, </span><span>33</span><span>, </span><span>34</span><span>, </span><span>35</span><span>, </span><span>36</span><span>,</span></div></div><div><div><div>95</div></div><div><span>      </span><span>40</span><span>, </span><span>41</span><span>, </span><span>42</span><span>, </span><span>43</span><span>, </span><span>55</span><span>, </span><span>56</span><span>, </span><span>57</span><span>, </span><span>58</span><span>, </span><span>59</span><span>, </span><span>60</span><span>, </span><span>61</span><span>, </span><span>65</span><span>, </span><span>66</span><span>, </span><span>67</span><span>, </span><span>69</span></div></div><div><div><div>96</div></div><div><span><span>    </span></span><span>],</span></div></div><div><div><div>97</div></div><div><span>    </span><span>"支援"</span><span>: [</span><span>1</span><span>, </span><span>2</span><span>, </span><span>5</span><span>, </span><span>7</span><span>, </span><span>9</span><span>, </span><span>10</span><span>, </span><span>12</span><span>, </span><span>44</span><span>, </span><span>70</span><span>],</span></div></div><div><div><div>98</div></div><div><span>    </span><span>"治疗"</span><span>: [</span><span>1</span><span>, </span><span>2</span><span>, </span><span>7</span><span>, </span><span>10</span><span>, </span><span>11</span><span>, </span><span>12</span><span>, </span><span>27</span><span>, </span><span>33</span><span>, </span><span>34</span><span>, </span><span>50</span><span>, </span><span>55</span><span>, </span><span>56</span><span>, </span><span>69</span><span>],</span></div></div><div><div><div>99</div></div><div><span>    </span><span>"医疗干员"</span><span>: [</span><span>1</span><span>, </span><span>2</span><span>, </span><span>10</span><span>, </span><span>11</span><span>, </span><span>12</span><span>, </span><span>33</span><span>, </span><span>34</span><span>, </span><span>55</span><span>, </span><span>56</span><span>, </span><span>69</span><span>],</span></div></div><div><div><div>100</div></div><div><span>    </span><span>"群攻"</span><span>: [</span><span>3</span><span>, </span><span>20</span><span>, </span><span>25</span><span>, </span><span>36</span><span>, </span><span>40</span><span>, </span><span>45</span><span>, </span><span>57</span><span>],</span></div></div><div><div><div>101</div></div><div><span>    </span><span>"削弱"</span><span>: [</span><span>3</span><span>, </span><span>20</span><span>, </span><span>22</span><span>, </span><span>35</span><span>, </span><span>41</span><span>],</span></div></div><div><div><div>102</div></div><div><span>    </span><span>"术师干员"</span><span>: [</span><span>3</span><span>, </span><span>35</span><span>, </span><span>36</span><span>, </span><span>57</span><span>, </span><span>58</span><span>, </span><span>65</span><span>, </span><span>66</span><span>],</span></div></div><div><div><div>103</div></div><div><span>    </span><span>"狙击干员"</span><span>: [</span><span>4</span><span>, </span><span>17</span><span>, </span><span>18</span><span>, </span><span>19</span><span>, </span><span>20</span><span>, </span><span>21</span><span>, </span><span>40</span><span>, </span><span>41</span><span>, </span><span>42</span><span>, </span><span>59</span><span>, </span><span>60</span><span>, </span><span>67</span><span>],</span></div></div><div><div><div>104</div></div><div><span>    </span><span>"男性干员"</span><span>: [</span><span>5</span><span>, </span><span>51</span><span>, </span><span>56</span><span>, </span><span>58</span><span>, </span><span>60</span><span>, </span><span>66</span><span>, </span><span>67</span><span>, </span><span>68</span><span>, </span><span>70</span><span>],</span></div></div><div><div><div>105</div></div><div><span>    </span><span>"近卫干员"</span><span>: [</span><span>5</span><span>, </span><span>25</span><span>, </span><span>26</span><span>, </span><span>44</span><span>, </span><span>45</span><span>, </span><span>46</span><span>, </span><span>47</span><span>, </span><span>48</span><span>, </span><span>62</span><span>, </span><span>70</span><span>],</span></div></div><div><div><div>106</div></div><div><span>    </span><span>"防护"</span><span>: [</span><span>6</span><span>, </span><span>7</span><span>, </span><span>27</span><span>, </span><span>28</span><span>, </span><span>29</span><span>, </span><span>30</span><span>, </span><span>37</span><span>, </span><span>49</span><span>, </span><span>50</span><span>, </span><span>51</span><span>, </span><span>63</span><span>],</span></div></div><div><div><div>107</div></div><div><span>    </span><span>"重装干员"</span><span>: [</span><span>6</span><span>, </span><span>7</span><span>, </span><span>27</span><span>, </span><span>28</span><span>, </span><span>29</span><span>, </span><span>30</span><span>, </span><span>49</span><span>, </span><span>50</span><span>, </span><span>51</span><span>, </span><span>63</span><span>, </span><span>68</span><span>],</span></div></div><div><div><div>108</div></div><div><span>    </span><span>"控场"</span><span>: [</span><span>8</span><span>, </span><span>13</span><span>, </span><span>24</span><span>],</span></div></div><div><div><div>109</div></div><div><span>    </span><span>"资深干员"</span><span>: [</span></div></div><div><div><div>110</div></div><div><span>      </span><span>8</span><span>, </span><span>9</span><span>, </span><span>10</span><span>, </span><span>11</span><span>, </span><span>12</span><span>, </span><span>13</span><span>, </span><span>14</span><span>, </span><span>15</span><span>, </span><span>16</span><span>, </span><span>17</span><span>, </span><span>18</span><span>, </span><span>19</span><span>, </span><span>20</span><span>, </span><span>21</span><span>, </span><span>22</span><span>, </span><span>23</span><span>, </span><span>24</span><span>, </span><span>25</span><span>, </span><span>26</span><span>,</span></div></div><div><div><div>111</div></div><div><span>      </span><span>27</span><span>, </span><span>28</span><span>, </span><span>29</span><span>, </span><span>30</span></div></div><div><div><div>112</div></div><div><span><span>    </span></span><span>],</span></div></div><div><div><div>113</div></div><div><span>    </span><span>"快速复活"</span><span>: [</span><span>13</span><span>, </span><span>37</span><span>],</span></div></div><div><div><div>114</div></div><div><span>    </span><span>"特种干员"</span><span>: [</span><span>13</span><span>, </span><span>14</span><span>, </span><span>15</span><span>, </span><span>16</span><span>, </span><span>37</span><span>, </span><span>38</span><span>, </span><span>39</span><span>],</span></div></div><div><div><div>115</div></div><div><span>    </span><span>"生存"</span><span>: [</span><span>14</span><span>, </span><span>25</span><span>, </span><span>26</span><span>, </span><span>29</span><span>, </span><span>42</span><span>, </span><span>45</span><span>, </span><span>48</span><span>, </span><span>62</span><span>],</span></div></div><div><div><div>116</div></div><div><span>    </span><span>"位移"</span><span>: [</span><span>15</span><span>, </span><span>16</span><span>, </span><span>30</span><span>, </span><span>38</span><span>, </span><span>39</span><span>],</span></div></div><div><div><div>117</div></div><div><span>    </span><span>"减速"</span><span>: [</span><span>16</span><span>, </span><span>23</span><span>, </span><span>40</span><span>, </span><span>43</span><span>, </span><span>47</span><span>, </span><span>61</span><span>],</span></div></div><div><div><div>118</div></div><div><span>    </span><span>"爆发"</span><span>: [</span><span>19</span><span>],</span></div></div><div><div><div>119</div></div><div><span>    </span><span>"辅助干员"</span><span>: [</span><span>22</span><span>, </span><span>23</span><span>, </span><span>24</span><span>, </span><span>43</span><span>, </span><span>61</span><span>],</span></div></div><div><div><div>120</div></div><div><span>    </span><span>"召唤"</span><span>: [</span><span>24</span><span>],</span></div></div><div><div><div>121</div></div><div><span>    </span><span>"新手"</span><span>: [</span><span>64</span><span>, </span><span>65</span><span>, </span><span>66</span><span>, </span><span>67</span><span>, </span><span>68</span><span>]</span></div></div><div><div><div>122</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>123</div></div><div><span>  </span><span>"avgCharTag"</span><span>: </span><span>12.275862068965518</span></div></div><div><div><div>124</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>一下子就变得很直观了呢</p></section>
<section><h2>2. 计算<a href="#2-计算"><span>#</span></a></h2><p>需要用到 <a href="https://www.npmjs.com/package/lodash.combinations" target="_blank">lodash.combinations</a></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> </span><span>"lodash.combinations"</span><span>;</span></div></div><div><div><div>2</div></div><div><span>import</span><span> </span><span>_</span><span> </span><span>from</span><span> </span><span>"lodash"</span><span>;</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>let</span><span> </span><span>AKDATA</span><span>; </span><span>//假设这是上面得到的处理过后的数据</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>function</span><span> </span><span>getChar</span><span><span>(</span><span>i</span><span>) {</span></span></div></div><div><div><div>7</div></div><div><span>  </span><span>return</span><span> </span><span>AKDATA</span><span>.</span><span>characters</span><span><span>[</span><span>i</span><span>];</span></span></div></div><div><div><div>8</div></div><div><span>}</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>//tags 是词条数组，例如 ['治疗','新手','削弱']</span></div></div><div><div><div>11</div></div><div><span>function</span><span> </span><span>getCombinations</span><span><span>(</span><span>tags</span><span>) {</span></span></div></div><div><div><div>12</div></div><div><span>  </span><span>//_.combinations 得到所有排列组合方案</span></div></div><div><div><div>13</div></div><div><span>  </span><span>let</span><span><span> </span><span>combs</span><span> </span></span><span>=</span><span><span> </span><span>_</span><span>.</span></span><span>flatMap</span><span>([</span><span>1</span><span>, </span><span>2</span><span>, </span><span>3</span><span><span>], (</span><span>v</span><span>) </span></span><span>=&gt;</span><span><span> </span><span>_</span><span>.</span></span><span>combinations</span><span><span>(</span><span>tags</span><span>, </span><span>v</span><span>));</span></span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>  </span><span>let</span><span><span> </span><span>result</span><span> </span></span><span>=</span><span> [];</span></div></div><div><div><div>16</div></div><div><span>  </span><span>for</span><span> (</span><span>let</span><span><span> </span><span>comb</span><span> </span></span><span>of</span><span><span> </span><span>combs</span><span>) {</span></span></div></div><div><div><div>17</div></div><div><span>    </span><span>//获取需要取交集的词条</span></div></div><div><div><div>18</div></div><div><span>    </span><span>let</span><span><span> </span><span>need</span><span> </span></span><span>=</span><span> [];</span></div></div><div><div><div>19</div></div><div><span>    </span><span>for</span><span> (</span><span>let</span><span><span> </span><span>tag</span><span> </span></span><span>of</span><span><span> </span><span>comb</span><span>) </span><span>need</span><span>.</span></span><span>push</span><span>(</span><span>AKDATA</span><span>.</span><span>data</span><span><span>[</span><span>tag</span><span>]);</span></span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span>    </span><span>//_.intersection 取交集</span></div></div><div><div><div>22</div></div><div><span>    </span><span>let</span><span><span> </span><span>chars</span><span> </span></span><span>=</span><span><span> </span><span>_</span><span>.</span></span><span>intersection</span><span>(</span><span>...</span><span><span>need</span><span>);</span></span></div></div><div><div><div>23</div></div><div>
</div></div><div><div><div>24</div></div><div><span>    </span><span>//如果词条中没有“高级资深干员”则无法招募6星干员，用 _.remove 按指定条件移除</span></div></div><div><div><div>25</div></div><div><span>    </span><span>if</span><span> (</span><span>!</span><span><span>comb</span><span>.</span></span><span>includes</span><span>(</span><span>"高级资深干员"</span><span>))</span></div></div><div><div><div>26</div></div><div><span><span>      </span></span><span>_</span><span>.</span><span>remove</span><span><span>(</span><span>chars</span><span>, (</span><span>i</span><span>) </span></span><span>=&gt;</span><span> </span><span>AKDATA</span><span>.</span><span>characters</span><span><span>[</span><span>i</span><span>].</span></span><span>r</span><span> </span><span>==</span><span> </span><span>6</span><span>);</span></div></div><div><div><div>27</div></div><div><span>    </span><span>if</span><span><span> (</span><span>chars</span><span>.</span></span><span>length</span><span> </span><span>==</span><span> </span><span>0</span><span>) </span><span>continue</span><span>;</span></div></div><div><div><div>28</div></div><div>
</div></div><div><div><div>29</div></div><div><span>    </span><span>//计算方案评分，在 graueneko 的基础上有所改进</span></div></div><div><div><div>30</div></div><div><span>    </span><span>//因为多数情况下我们只招募3星及以上干员，因此在评分时可以忽略1星2星</span></div></div><div><div><div>31</div></div><div><span>    </span><span>//_.sumBy 按指定方法求和，_.filter 按指定条件过滤</span></div></div><div><div><div>32</div></div><div><span>    </span><span>let</span><span><span> </span><span>scoreChars</span><span> </span></span><span>=</span><span><span> </span><span>_</span><span>.</span></span><span>filter</span><span><span>(</span><span>chars</span><span>, (</span><span>i</span><span>) </span></span><span>=&gt;</span><span> </span><span>getChar</span><span><span>(</span><span>i</span><span>).</span></span><span>r</span><span> </span><span>&gt;=</span><span> </span><span>3</span><span>);</span></div></div><div><div><div>33</div></div><div><span>    </span><span>if</span><span><span> (</span><span>scoreChars</span><span>.</span></span><span>length</span><span> </span><span>==</span><span> </span><span>0</span><span><span>) </span><span>scoreChars</span><span> </span></span><span>=</span><span><span> </span><span>chars</span><span>;</span></span></div></div><div><div><div>34</div></div><div><span>    </span><span>let</span><span><span> </span><span>score</span><span> </span></span><span>=</span></div></div><div><div><div>35</div></div><div><span><span>      </span></span><span>_</span><span>.</span><span>sumBy</span><span><span>(</span><span>scoreChars</span><span>, (</span><span>i</span><span>) </span></span><span>=&gt;</span><span> </span><span>getChar</span><span><span>(</span><span>i</span><span>).</span></span><span>r</span><span>) </span><span>/</span><span><span> </span><span>scoreChars</span><span>.</span></span><span>length</span><span> </span><span>-</span></div></div><div><div><div>36</div></div><div><span><span>      </span></span><span>comb</span><span>.</span><span>length</span><span> </span><span>/</span><span> </span><span>10</span><span> </span><span>-</span></div></div><div><div><div>37</div></div><div><span><span>      </span></span><span>scoreChars</span><span>.</span><span>length</span><span> </span><span>/</span><span> </span><span>AKDATA</span><span>.</span><span>avgCharTag</span><span>;</span></div></div><div><div><div>38</div></div><div>
</div></div><div><div><div>39</div></div><div><span>    </span><span>//得到保底稀有度用于排序</span></div></div><div><div><div>40</div></div><div><span>    </span><span>let</span><span><span> </span><span>minI</span><span> </span></span><span>=</span><span><span> </span><span>_</span><span>.</span></span><span>minBy</span><span><span>(</span><span>scoreChars</span><span>, (</span><span>i</span><span>) </span></span><span>=&gt;</span><span> </span><span>getChar</span><span><span>(</span><span>i</span><span>).</span></span><span>r</span><span>);</span></div></div><div><div><div>41</div></div><div>
</div></div><div><div><div>42</div></div><div><span><span>    </span></span><span>result</span><span>.</span><span>push</span><span>({</span></div></div><div><div><div>43</div></div><div><span><span>      </span></span><span>comb</span><span>,</span></div></div><div><div><div>44</div></div><div><span><span>      </span></span><span>chars</span><span>,</span></div></div><div><div><div>45</div></div><div><span>      </span><span>min</span><span>:</span><span> </span><span>AKDATA</span><span>.</span><span>characters</span><span><span>[</span><span>minI</span><span>].</span></span><span>r</span><span>,</span></div></div><div><div><div>46</div></div><div><span><span>      </span></span><span>score</span><span>,</span></div></div><div><div><div>47</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>48</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>49</div></div><div>
</div></div><div><div><div>50</div></div><div><span>  </span><span>//按保底稀有度和评分进行排序</span></div></div><div><div><div>51</div></div><div><span><span>  </span></span><span>result</span><span>.</span><span>sort</span><span><span>((</span><span>a</span><span>, </span><span>b</span><span>) </span></span><span>=&gt;</span><span><span> (</span><span>a</span><span>.</span></span><span>min</span><span> </span><span>==</span><span><span> </span><span>b</span><span>.</span></span><span>min</span><span> </span><span>?</span><span><span> </span><span>b</span><span>.</span></span><span>score</span><span> </span><span>-</span><span><span> </span><span>a</span><span>.</span></span><span>score</span><span> </span><span>:</span><span><span> </span><span>b</span><span>.</span></span><span>min</span><span> </span><span>-</span><span><span> </span><span>a</span><span>.</span></span><span>min</span><span>));</span></div></div><div><div><div>52</div></div><div><span>  </span><span>return</span><span><span> </span><span>result</span><span>;</span></span></div></div><div><div><div>53</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2>3. OCR 以及结果生成<a href="#3-ocr-以及结果生成"><span>#</span></a></h2><ul>
<li>可以使用 <a href="https://ocr.space/ocrapi" target="_blank">ocr.space</a> 的免费 API，每日 500 次够用了，但是效果不太好</li>
<li>可以使用 <a href="https://ai.baidu.com/tech/ocr" target="_blank">百度OCR</a>，高精度识别每日也免费 500 次，效果更好</li>
</ul><p>至于展示结果的方法，我最开始用的是直接纯文字输出，但是发现这样很不直观甚至还会眼花（</p><p>后来我决定仿照 graueneko 的排版生成图片，考虑到 javascript 特色……我去花了半小时现学了下 canvas 就直接用上了，效果大概这样</p><p><img src="/usr/uploads/2019/05/775805416.png" alt="" /></p><p>最终成果可以参考 <a href="https://github.com/Tsuk1ko/CQ-picfinder-robot/blob/master/modules/plugin/akhr.js" target="_blank">akhr.js</a> 和 <a href="https://github.com/Tsuk1ko/CQ-picfinder-robot/blob/master/modules/plugin/akhr.draw.js" target="_blank">akhr.draw.js</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/comment2ifttt/</id>
      <title type="text">[Typecho插件] 新评论推送至 IFTTT Webhooks</title>
      <published>2019-03-31T05:54:00.000Z</published>
      <updated>2019-05-07T18:36:53.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/comment2ifttt/"/>
      <summary type="text">借由 IFTTT 与多种服务的联动以及该插件，可以有很多玩法。 我目前用来将新评论提醒推送到 Telegram，比以前使用 Server酱 的方案在查看信息上要方便不少。</summary>
      <content type="html"><![CDATA[<p>借由 IFTTT 与多种服务的联动以及该插件，可以有很多玩法。
我目前用来将新评论提醒推送到 Telegram，比以前使用 Server酱 的方案在查看信息上要方便不少。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=73907300" target="_blank">【カーマ(Fate)】「愛の神」/「色谷あすか＠例大祭あ37ab」的插画 [pixiv]</a>
我永远只喜欢第一再临状态.jpg，可惜抽不到</p>
<hr />
<a href="https://github.com/Tsuk1ko/Comment2IFTTT" target="_blank"><div><div><div><div></div><div>Tsuk1ko</div></div><div>/</div><div>Comment2IFTTT</div></div><div></div></div><div>A Typecho plugin to push new comments to IFTTT Webhooks</div><div><div>—</div><div>—</div><div>MIT</div><span>PHP</span></div></a>
<section><h2>安装插件<a href="#安装插件"><span>#</span></a></h2><section><h3>方法一<a href="#方法一"><span>#</span></a></h3><p>进入 Typecho 插件目录<code>usr/plugins/</code>，直接克隆该项目</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/Tsuk1ko/Comment2IFTTT.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方法二<a href="#方法二"><span>#</span></a></h3><p>进入 Typecho 插件目录<code>usr/plugins/</code>，创建名为<code>Comment2IFTTT</code>的文件夹，然后将 <a href="https://github.com/Tsuk1ko/Comment2IFTTT/raw/master/Plugin.php" target="_blank">Plugin.php</a> 文件下载到此文件夹内</p></section></section>
<section><h2>配置插件<a href="#配置插件"><span>#</span></a></h2><p>在 Typecho 后台启用插件后需要先进入该插件的设置页面设置 <strong>Webhooks Key</strong> 和 <strong>Event Name</strong> 后才能使用</p><section><h3>Webhooks Key<a href="#webhooks-key"><span>#</span></a></h3><p>当然你得需要有一个 IFTTT 帐号……</p><p>首先到 IFTTT 的 <a href="https://ifttt.com/maker_webhooks" target="_blank">Webhooks</a> 服务页面启用服务，然后点击右上角的“Documentation”即可得到</p></section><section><h3>Event Name<a href="#event-name"><span>#</span></a></h3><p>Webhooks 事件名，自己起一个名字，例如<code>typecho</code>什么的</p></section></section>
<section><h2>在 IFTTT 中运用 Webhooks<a href="#在-ifttt-中运用-webhooks"><span>#</span></a></h2><p>如果你从未使用过 IFTTT，可以先试着自己玩一下熟悉一下（</p><p>该插件会向 Webhooks 推送3个 value：</p><ul>
<li>value1 - 收到评论的文章标题</li>
<li>value2 - 评论人昵称</li>
<li>value3 - 评论内容</li>
</ul><p>于是你就可以自由构建收到通知的格式了</p><section><h3>举个栗子<a href="#举个栗子"><span>#</span></a></h3><p>例如我自己的用法是将评论推送到 Telegram，需要先在 IFTTT 中<a href="https://ifttt.com/telegram" target="_blank">关联 Telegram 帐号</a></p><p>关联时会让你先点击一个链接跳转至 Telegram 的 IFTTT 机器人，Start 后机器人会发送一条信息，点击“Authorize IFTTT”即可</p><p>首先新建一个 Applet：if <strong>Webhooks</strong> then <strong>Telegram</strong></p><p>Webhooks 选（也只能选）“Receive a web request”，然后填入 Event Name，就是你在插件里设置的那个</p><p>Telegram 选“Send message”，Message text 便是你可以自由利用 value1~3 来构建的消息内容，以下是我的例子</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>文章《{{Value1}}》有新评论啦&lt;</span><span>br</span><span> /&gt;</span></div></div><div><div><div>2</div></div><div><span>&lt;</span><span>b</span><span>&gt;{{Value2}}&lt;/</span><span>b</span><span>&gt;&lt;</span><span>br</span><span> /&gt;</span></div></div><div><div><div>3</div></div><div><span>{{Value3}}&lt;</span><span>br</span><span> /&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后就可以开始享受 IFTTT 带来的便利了（</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/bilibili-live-chat/</id>
      <title type="text">[Bilibili Live Chat] OBS用B站直播弹幕展示</title>
      <published>2019-02-14T07:36:00.000Z</published>
      <updated>2020-10-31T03:54:38.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/bilibili-live-chat/"/>
      <summary type="text">前阵子朋友突然和我提起 VTuber 们直播时用的 YouTube Live Chat 展示，“这玩意真好啊，怎么B站没有类似的东西呢”（其实只是当时没找到），然后我就做了这玩意……</summary>
      <content type="html"><![CDATA[<p>前阵子朋友突然和我提起 VTuber 们直播时用的 YouTube Live Chat 展示，“这玩意真好啊，怎么B站没有类似的东西呢”（其实只是当时没找到），然后我就做了这玩意……</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=73166799" target="_blank">【アズールレーン】「バレンタイン」/「ここね」的插画 [pixiv]</a></p>
<hr />
<p><img src="https://i.loli.net/2020/06/20/vXuZKCq396co2HO.gif" alt="" /></p>
<p>这是一个无后端的，仿 YouTube Live Chat 的，箱都不用开就能食用的 Bilibili 直播弹幕姬</p>
<p>主要用于 OBS，为的是在低功能需求的情况下，不依靠任何第三方本地软件实现弹幕和礼物的展示</p>
<a href="https://github.com/Tsuk1ko/bilibili-live-chat" target="_blank"><div><div><div><div></div><div>Tsuk1ko</div></div><div>/</div><div>bilibili-live-chat</div></div><div></div></div><div>📽️ 主要用于 OBS 的纯 Web 仿 YouTube Live Chat 风格的简易 Bilibili 弹幕姬</div><div><div>—</div><div>—</div><div>MIT</div><span>Vue</span></div></a>
<p>成品及使用方法请查看上面的 GitHub 项目</p>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/nhentai-download-as-zip/</id>
      <title type="text">[Script] nhentai 下载增强</title>
      <published>2019-01-26T15:00:00.000Z</published>
      <updated>2020-08-17T14:29:06.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/nhentai-download-as-zip/"/>
      <summary type="text">因为 nhentai 本身仅提供登陆后 BT 下载的方式，比较麻烦而且速度较慢，因此编写了这个脚本，增加了直接 zip 打包下载的方式</summary>
      <content type="html"><![CDATA[<p>因为 nhentai 本身仅提供登陆后 BT 下载的方式，比较麻烦而且速度较慢，因此编写了这个脚本，增加了直接 zip 打包下载的方式</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=72805631" target="_blank">【オリジナル】「だいすき」/「空維深夜」のイラスト [pixiv]</a></p>
<hr />
<p>需要浏览器先安装 Tampermonkey 插件</p>
<p><a href="https://cdn.jsdelivr.net/gh/Tsuk1ko/nhentai-helper@master/script.user.js" target="_blank">点此直接安装</a></p>
<a href="https://github.com/Tsuk1ko/nhentai-download-as-zip" target="_blank"><div><div><div><div></div><div>Tsuk1ko</div></div><div>/</div><div>nhentai-download-as-zip</div></div><div></div></div><div>🔞 A user script make it easy for you to download nHentai manga as zip (or cbz), also support some mirror sites. 一个可以让你轻松打包下载 nHentai 本子的用户脚本，并支持一些镜像站</div><div><div>—</div><div>—</div><div>GPL-3.0</div><span>TypeScript</span></div></a>
<p><a href="https://greasyfork.org/zh-CN/scripts/375992-nhentai-download-as-zip" target="_blank">GreasyFork（登录可见）</a></p>

简略说明及效果预览 (NSFW)
<p>说明请参阅 <a href="https://github.com/Tsuk1ko/nhentai-helper/blob/master/README-ZH.md" target="_blank">GitHub README</a></p>
<p><img src="https://i.loli.net/2019/01/26/5c4c5d5914197.png" alt="" /></p>
<p><img src="https://i.loli.net/2018/12/26/5c23a39505d14.png" alt="" /></p>
]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/front-end-developer-interview/</id>
      <title type="text">前端面试常见知识点归纳</title>
      <published>2019-01-21T06:53:00.000Z</published>
      <updated>2019-01-27T06:34:31.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/front-end-developer-interview/"/>
      <summary type="text">去年底除了忙期末还要忙找工作真是非常煎熬，不过总归是找到了~</summary>
      <content type="html"><![CDATA[<p>去年底除了忙期末还要忙找工作真是非常煎熬，不过总归是找到了~</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=66072038" target="_blank">【FF14】「FF14」/「sabet@お仕事募集中」のイラスト [pixiv]</a></p>
<section><h1>推荐<a href="#推荐"><span>#</span></a></h1><p>强烈推荐该汇总，含盖很多细节知识点</p><p><a href="https://github.com/markyun/My-blog/tree/master/Front-end-Developer-Questions" target="_blank">https://github.com/markyun/My-blog/tree/master/Front-end-Developer-Questions</a></p></section>
<section><h1>网络<a href="#网络"><span>#</span></a></h1><section><h2>请求相关<a href="#请求相关"><span>#</span></a></h2><section><h3>请求头<a href="#请求头"><span>#</span></a></h3><p><img src="http://static.oschina.net/uploads/img/201512/22172741_qj7p.jpg" alt="" /></p><section><h4>头部字段<a href="#头部字段"><span>#</span></a></h4><section><h5>Content-Length<a href="#content-length"><span>#</span></a></h5><p>Content-Length 首部告诉浏览器报文中实体主体的大小。这个大小是包含了内容编码的，比如对文件进行了 gzip 压缩，Content-Length 就是压缩后的大小，而不是原始大小</p><p>Content-Length 对于长连接是必不可少的，长连接代表在连接期间会有多个 http 请求响应在排队，而服务器不能够关闭连接，客户端只能通过 Content-Length 知道一条报文在哪里结束，下一条报文在哪里开始。</p><p>除非使用了分块编码<code>Transfer-Encoding: chunked</code>，否则响应头必须包含 Content-Length 。</p></section></section></section><section><h3>请求方法<a href="#请求方法"><span>#</span></a></h3>

<table><thead><tr><th>方法</th><th>描述</th></tr></thead><tbody><tr><td>GET</td><td>请求指定的页面信息，并返回实体主体。</td></tr><tr><td>HEAD</td><td>类似于GET请求，只不过返回的响应中没有具体的内容，用于获取报头</td></tr><tr><td>POST</td><td>向指定资源提交数据进行处理请求（例如提交表单或者上传文件）。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。</td></tr><tr><td>PUT</td><td>从客户端向服务器传送的数据取代指定的文档的内容。</td></tr><tr><td>DELETE</td><td>请求服务器删除指定的页面。</td></tr><tr><td>CONNECT</td><td>HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。</td></tr><tr><td>OPTIONS</td><td>允许客户端查看服务器的性能。</td></tr><tr><td>TRACE</td><td>回显服务器收到的请求，主要用于测试或诊断。</td></tr></tbody></table></section><section><h3>常见状态码<a href="#常见状态码"><span>#</span></a></h3>

<table><thead><tr><th>分类</th><th>分类描述</th></tr></thead><tbody><tr><td>1**</td><td>信息，服务器收到请求，需要请求者继续执行操作</td></tr><tr><td>2**</td><td>成功，操作被成功接收并处理</td></tr><tr><td>3**</td><td>重定向，需要进一步的操作以完成请求</td></tr><tr><td>4**</td><td>客户端错误，请求包含语法错误或无法完成请求</td></tr><tr><td>5**</td><td>服务器错误，服务器在处理请求的过程中发生了错误</td></tr></tbody></table>

<table><thead><tr><th>状态码</th><th>状态码英文名称</th><th>中文描述</th></tr></thead><tbody><tr><td>200</td><td>OK</td><td>请求成功。一般用于GET与POST请求</td></tr><tr><td>301</td><td>Moved Permanently</td><td>永久移动。请求的资源已被永久的移动到新URI，返回信息会包括新的URI，浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替</td></tr><tr><td>302</td><td>Found</td><td>临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI</td></tr><tr><td>304</td><td>Not Modified</td><td>未修改。所请求的资源未修改，服务器返回此状态码时，不会返回任何资源。客户端通常会缓存访问过的资源，通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源</td></tr><tr><td>307</td><td>Temporary Redirect</td><td>临时重定向。与302类似。使用GET请求重定向</td></tr><tr><td>400</td><td>Bad Request</td><td>客户端请求的语法错误，服务器无法理解</td></tr><tr><td>401</td><td>Unauthorized</td><td>请求要求用户的身份认证</td></tr><tr><td>403</td><td>Forbidden</td><td>服务器理解请求客户端的请求，但是拒绝执行此请求</td></tr><tr><td>404</td><td>Not Found</td><td>服务器无法根据客户端的请求找到资源（网页）。通过此代码，网站设计人员可设置”您所请求的资源无法找到”的个性页面</td></tr><tr><td>413</td><td>Request Entity Too Large</td><td>由于请求的实体过大，服务器无法处理，因此拒绝请求。为防止客户端的连续请求，服务器可能会关闭连接。如果只是服务器暂时无法处理，则会包含一个Retry-After的响应信息</td></tr><tr><td>414</td><td>Request-URI Too Large</td><td>请求的URI过长（URI通常为网址），服务器无法处理</td></tr><tr><td>429</td><td>Too Many Requests</td><td>请求速度超过服务端限制</td></tr><tr><td>500</td><td>Internal Server Error</td><td>服务器内部错误，无法完成请求</td></tr><tr><td>502</td><td>Bad Gateway</td><td>作为网关或者代理工作的服务器尝试执行请求时，从远程服务器接收到了一个无效的响应</td></tr><tr><td>503</td><td>Service Unavailable</td><td>由于超载或系统维护，服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中</td></tr><tr><td>504</td><td>Gateway Time-out</td><td>充当网关或代理的服务器，未及时从远端服务器获取请求</td></tr></tbody></table></section></section><section><h2>TCP 三次握手<a href="#tcp-三次握手"><span>#</span></a></h2><ol>
<li>建立连接时，客户端发送 SYN 包（SYN=j）到服务器，并进入 SYN_SENT 状态，等待服务器确认</li>
<li>服务器收到 SYN 包，必须确认客户的 SYN（ACK=j+1），同时自己也发送一个 SYN 包（SYN=k），即 SYN+ACK 包，此时服务器进入 SYN_RECV 状态</li>
<li>客户端收到服务器的 SYN+ACK 包，向服务器发送确认包 ACK（ACK=k+1），此包发送完毕，客户端和服务器进入 ESTABLISHED（TCP连接成功）状态，完成三次握手</li>
</ol></section><section><h2>跨域<a href="#跨域"><span>#</span></a></h2><section><h3>同源策略<a href="#同源策略"><span>#</span></a></h3><p>同源策略/SOP（Same origin policy）是一种约定，由Netscape公司1995年引入浏览器，它是浏览器最核心也最基本的安全功能，如果缺少了同源策略，浏览器很容易受到XSS、CSFR等攻击。所谓同源是指“协议+域名+端口”三者相同，即便两个不同的域名指向同一个ip地址，也非同源。</p><p>同源策略限制以下几种行为：</p><ol>
<li>Cookie、LocalStorage 和 IndexDB 无法读取</li>
<li>DOM 和 Js 对象无法获得</li>
<li>AJAX 请求不能发送</li>
</ol></section><section><h3>跨域解决方案<a href="#跨域解决方案"><span>#</span></a></h3><ol>
<li>
<p>通过 jsonp（只能 GET）</p>
</li>
<li>
<p>document.domain + iframe（仅限主域相同，子域不同）</p>
</li>
<li>
<p>location.hash + iframe</p>
</li>
<li>
<p>window.name + iframe</p>
</li>
<li>
<p>postMessage</p>
</li>
<li>
<p>跨域资源共享（CORS）</p>
<p>服务端 Header: Access-Control-Allow-Origin</p>
</li>
<li>
<p>nginx 反向代理</p>
<p>nodejs 中间件代理</p>
</li>
<li>
<p>WebSocket 协议</p>
</li>
</ol></section></section><section><h2>储存<a href="#储存"><span>#</span></a></h2>

<table><thead><tr><th>特性</th><th>Cookie</th><th>localStorage</th><th>sessionStorage</th></tr></thead><tbody><tr><td>数据的生命期</td><td>一般由服务器生成，可设置失效时间。如果在浏览器端生成 Cookie，默认是关闭浏览器后失效</td><td>除非被清除，否则永久保存</td><td>仅在当前会话下有效， 关闭页面或浏览器后被清除</td></tr><tr><td>存放数据大小</td><td>4K左右</td><td>一般为5MB</td><td>同左</td></tr><tr><td>与服务器端通信</td><td>每次都会携带在 HTTP 头中，如果使用 cookie 保存过多数据会带来性能问题</td><td>仅在客户端（即浏览器）中保存，不参与和服务器的通信</td><td>同左</td></tr><tr><td>易用性</td><td>需要程序员自己封装，原生的 Cookie 接口不友好</td><td>原生接口可以接受，亦可再次封装来对 Object 和 Array 有更好的支持</td><td>同左</td></tr></tbody></table></section><section><h2>HTTP/2 新特性<a href="#http2-新特性"><span>#</span></a></h2><p><a href="https://www.jianshu.com/p/67c541a421f9" target="_blank">https://www.jianshu.com/p/67c541a421f9</a></p><ol>
<li>二进制帧层：减小体积，提高传输性能</li>
<li>流、消息、帧</li>
<li>请求和响应的多路复用：由于二进制帧的出现，帧可以在流中不按序传输，到达后再组装，解决了 HTTP/1.x 可能出现的头部阻塞问题</li>
<li>流具有优先级</li>
<li>每个源仅需要一个连接：充分利用 TCP，减小整体协议的头部</li>
<li>流量控制</li>
<li>头部压缩</li>
</ol></section><section><h2>HTTPS 相关<a href="#https-相关"><span>#</span></a></h2><section><h3>SSL 连接建立过程<a href="#ssl-连接建立过程"><span>#</span></a></h3><p>SSL 使用不对称+对称加密</p><p><img src="/usr/uploads/2019/01/3392339120.png" alt="" /></p><section><h4>对公钥进行认证<a href="#对公钥进行认证"><span>#</span></a></h4><p>黑客可以替换你的公钥，然后用他的私钥做数字签名给你发信息，而你用黑客伪造的公钥能成功验证，会让你误认为消息来源没变。</p><p>这种情况下需要CA(证书中心certificate authority)对公钥进行认证。证书中心用自己的私钥，对信息发送者的公钥和一些相关信息一起加密，生成”数字证书”（Digital Certificate）。</p></section></section></section><section><h2>攻击<a href="#攻击"><span>#</span></a></h2><section><h3>CSRF 跨站请求伪造<a href="#csrf-跨站请求伪造"><span>#</span></a></h3><p><img src="https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=407db661b412c8fca0fefe9f9d6af920/f603918fa0ec08fa63cbd7e654ee3d6d54fbdaac.jpg" alt="" /></p><p>防范方法：</p><p>在要提交的表单中加入一个一次性验证字段，这个字段由服务端生成并且储存于 session 中，服务端接收到表单提交请求后对字段进行验证。</p><p>相似的解决方案还有“双提交”Cookie，在 ajax 提交 POST 请求时将 Cookie 一并作为表单字段提交，因为读取 Cookie 只有在信任域内才能做到。</p></section><section><h3>XSS 跨站脚本攻击<a href="#xss-跨站脚本攻击"><span>#</span></a></h3><p>XSS是指恶意攻击者利用网站<strong>没有对用户提交数据进行转义处理或者过滤不足</strong>的缺点，进而添加一些代码，嵌入到web页面中去，使别的用户访问都会执行相应的嵌入代码，从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。</p><p>防范方法：不可信任任何用户提交的数据，必须对部分敏感字符进行转义、过滤。</p></section></section><section><h2>协商缓存与强缓存<a href="#协商缓存与强缓存"><span>#</span></a></h2><section><h3>强制缓存<a href="#强制缓存"><span>#</span></a></h3><p>强制缓存整体流程比较简单，就是在第一次访问服务器取到数据之后，在过期时间之内不会再去重复请求。实现这个流程的核心就是如何知道当前时间是否超过了过期时间。</p><p>强制缓存的过期时间通过第一次访问服务器时返回的响应头获取。在 <code>http 1.0</code> 和 <code>http 1.1</code> 版本中通过不同的响应头字段实现。</p><p><strong>http 1.0</strong></p><p>在 <code>http 1.0</code> 版本中，强制缓存通过 <code>Expires</code> 响应头来实现。 <code>expires</code> 表示未来资源会过期的时间。也就是说，当发起请求的时间超过了 <code>expires</code> 设定的时间，即表示资源缓存时间到期，会发送请求到服务器重新获取资源。而如果发起请求的时间在 <code>expires</code> 限定的时间之内，浏览器会直接读取本地缓存数据库中的信息（<code>from memory</code> or <code>from disk</code>），两种方式根据浏览器的策略随机获取。</p><p><strong>http 1.1</strong></p><p>在 <code>http 1.1</code> 版本中，强制缓存通过 <code>Cache-Control</code> 响应头来实现。<code>Cache-Control</code> 拥有多个值：</p><blockquote><p><strong>private</strong>：客户端可以缓存
<strong>public</strong>：客户端和代理服务器均可缓存；
<strong>max-age=xxx</strong>：缓存的资源将在 xxx 秒后过期；
<strong>no-cache</strong>：需要使用协商缓存来验证是否过期；
<strong>no-store</strong>：不可缓存</p></blockquote><p>最常用的字段就是 <code>max-age=xxx</code> ，表示缓存的资源将在 xxx 秒后过期。一般来说，为了兼容，两个版本的强制缓存都会被实现。</p><p><strong>总结</strong></p><p>强制缓存只有首次请求才会跟服务器通信，读取缓存资源时不会发出任何请求，资源的 <code>Status</code> 状态码为 <code>200</code>，资源的 <code>Size</code> 为 <code>from memory</code> 或者 <code>from disk</code> ，http 1.1 版本的实现优先级会高于 http 1.0 版本的实现。</p></section><section><h3>协商缓存<a href="#协商缓存"><span>#</span></a></h3><p>协商缓存与强制缓存的不同之处在于，协商缓存每次读取数据时都需要跟服务器通信，并且会增加缓存标识。在第一次请求服务器时，服务器会返回资源，并且返回一个资源的缓存标识，一起存到浏览器的缓存数据库。当第二次请求资源时，浏览器会首先将缓存标识发送给服务器，服务器拿到标识后判断标识是否匹配，如果不匹配，表示资源有更新，服务器会将新数据和新的缓存标识一起返回到浏览器；如果缓存标识匹配，表示资源没有更新，并且返回 <code>304</code> 状态码，浏览器就读取本地缓存服务器中的数据。</p><p>在 http 协议的 <code>1.0</code> 和 <code>1.1</code> 版本中也有不同的实现方式。</p><p><strong>http 1.0</strong></p><p>在 <code>http 1.0</code> 版本中，第一次请求资源时服务器通过 <code>Last-Modified</code> 来设置响应头的缓存标识，并且把资源最后修改的时间作为值填入，然后将资源返回给浏览器。在第二次请求时，浏览器会首先带上 <code>If-Modified-Since</code> 请求头去访问服务器，服务器会将 <code>If-Modified-Since</code> 中携带的时间与资源修改的时间匹配，如果时间不一致，服务器会返回新的资源，并且将 <code>Last-Modified</code> 值更新，作为响应头返回给浏览器。如果时间一致，表示资源没有更新，服务器返回 304 状态码，浏览器拿到响应状态码后从本地缓存数据库中读取缓存资源。</p><p>这种方式有一个弊端，就是当服务器中的资源增加了一个字符，后来又把这个字符删掉，本身资源文件并没有发生变化，但修改时间发生了变化。当下次请求过来时，服务器也会把这个本来没有变化的资源重新返回给浏览器。</p><p><strong>http 1.1</strong></p><p>在 <code>http 1.1</code> 版本中，服务器通过 <code>Etag</code> 来设置响应头缓存标识。<code>Etag</code> 的值由服务端生成。在第一次请求时，服务器会将资源和 <code>Etag</code> 一并返回给浏览器，浏览器将两者缓存到本地缓存数据库。在第二次请求时，浏览器会将 <code>Etag</code> 信息放到 <code>If-None-Match</code> 请求头去访问服务器，服务器收到请求后，会将服务器中的文件标识与浏览器发来的标识进行对比，如果不相同，服务器返回更新的资源和新的 <code>Etag</code> ，如果相同，服务器返回 <code>304</code> 状态码，浏览器读取缓存。</p><p><strong>总结</strong></p><p>协商缓存每次请求都会与服务器交互，第一次是拿数据和标识的过程，第二次开始，就是浏览器询问服务器资源是否有更新的过程。每次请求都会传输数据，如果命中缓存，则资源的 <code>Status</code> 状态码为 <code>304</code> 而不是 <code>200</code> 。同样的，一般来讲为了兼容，两个版本的协商缓存都会被实现，<code>http 1.1</code> 版本的实现优先级会高于 <code>http 1.0</code> 版本的实现。</p></section></section></section>
<section><h1>HTML<a href="#html"><span>#</span></a></h1><section><h2>页面渲染<a href="#页面渲染"><span>#</span></a></h2><section><h3>渲染过程<a href="#渲染过程"><span>#</span></a></h3><p>不同的浏览器工作方式是不一样的，下面的图表提供了渲染时的共同实现，一旦他们已经下载好了你页面的代码，多半都会通过浏览器这样实现。</p><p></p><figure><img src="https://user-gold-cdn.xitu.io/2016/11/29/684a6bbe55267fdc310e8b2fd283bc25.png?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="Rendering process in the browser" /><figcaption>Rendering process in the browser</figcaption></figure><p></p></section></section><section><h2>重排和重绘<a href="#重排和重绘"><span>#</span></a></h2><p>无论何时总会有一个初始化的页面布局伴随着一次绘制（除非你希望你的页面是空白的）。之后，每一次改变用于构建渲染树的信息都会导致以下至少一个的行为：</p><ol>
<li>部分渲染树（或者整个渲染树）需要重新分析并且节点尺寸需要重新计算。这被称为<strong>重排</strong>。注意这里至少会有一次重排-初始化页面布局。</li>
<li>由于节点的几何属性发生改变或者由于样式发生改变，例如改变元素背景色时，屏幕上的部分内容需要更新。这样的更新被称为<strong>重绘</strong>。</li>
</ol><p>重排和重绘代价是高昂的，它们会破坏用户体验，并且让UI展示非常迟缓。</p><section><h3>什么情况会触发重排和重绘<a href="#什么情况会触发重排和重绘"><span>#</span></a></h3><p>任何改变用来构建渲染树的信息都会导致一次重排或重绘。</p><ul>
<li>添加、删除、更新DOM节点</li>
<li>通过<code>display: none</code>隐藏一个DOM节点</li>
<li>通过<code>visibility: hidden</code>隐藏一个DOM节点：只触发重绘</li>
<li>移动或者给页面中的DOM节点添加动画</li>
<li>添加一个样式表，调整样式属性
<ul>
<li>当仅改变颜色时只触发重绘</li>
</ul>
</li>
<li>用户行为，例如调整窗口大小，改变字号，或者滚动。</li>
</ul></section><section><h3>最小化重排和重绘<a href="#最小化重排和重绘"><span>#</span></a></h3><p>通过减少重排/重绘的负面影响来提高用户体验的最简单方式就是，尽可能少的去使用他们的同时尽可能少的请求样式信息，这样浏览器就可以优化重排。</p><ul>
<li>不要逐个变样式。对于静态页面来说，明智且兼具可维护性的做法是改变类名而不是样式。对于动态改变的样式来说，相较每次微小修改都直接触及元素，更好的办法是统一在<code>cssText</code>变量中编辑。</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// bad</span></div></div><div><div><div>2</div></div><div><span>var</span><span><span> </span><span>left</span><span> </span></span><span>=</span><span> </span><span>10</span><span>,</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>top</span><span> </span><span>=</span><span> </span><span>10</span><span>;</span></div></div><div><div><div>4</div></div><div><span><span>el</span><span>.</span></span><span>style</span><span>.</span><span>left</span><span> </span><span>=</span><span><span> </span><span>left</span><span> </span></span><span>+</span><span> </span><span>"px"</span><span>;</span></div></div><div><div><div>5</div></div><div><span><span>el</span><span>.</span></span><span>style</span><span>.</span><span>top</span><span> </span><span>=</span><span><span> </span><span>top</span><span> </span></span><span>+</span><span> </span><span>"px"</span><span>;</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>// better</span></div></div><div><div><div>8</div></div><div><span><span>el</span><span>.</span></span><span>className</span><span> </span><span>+=</span><span> </span><span>" theclassname"</span><span>;</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>// 当top和left的值是动态计算而成时...</span></div></div><div><div><div>11</div></div><div><span>// better</span></div></div><div><div><div>12</div></div><div><span><span>el</span><span>.</span></span><span>style</span><span>.</span><span>cssText</span><span> </span><span>+=</span><span> </span><span>"; left: "</span><span> </span><span>+</span><span><span> </span><span>left</span><span> </span></span><span>+</span><span> </span><span>"px; top: "</span><span> </span><span>+</span><span><span> </span><span>top</span><span> </span></span><span>+</span><span> </span><span>"px;"</span><span>;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>“离线”地批量改变和表现DOM。“离线”意味着不在当前的DOM树中做修改。你可以：
<ul>
<li>通过<code>documentFragment</code>来保留临时变动。</li>
<li>复制你即将更新的节点，在副本上工作，然后将之前的节点和新节点交换。</li>
<li>通过<code>display:none</code>属性隐藏元素（只有一次重排重绘），添加足够多的变更后，通过<code>display</code>属性显示（另一次重排重绘）。通过这种方式即使大量变更也只触发两次重排。</li>
</ul>
</li>
<li>不要频繁计算样式。如果你有一个样式需要计算，只取一次，将它缓存在一个变量中并且在这个变量上工作。</li>
</ul><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>// no-no!</span></div></div><div><div><div>2</div></div><div><span>for</span><span><span> (</span><span>big</span><span>; </span><span>loop</span><span>; </span><span>here</span><span>) {</span></span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>el</span><span>.</span><span>style</span><span>.</span><span>left</span><span> </span><span>=</span><span><span> </span><span>el</span><span>.</span></span><span>offsetLeft</span><span> </span><span>+</span><span> </span><span>10</span><span> </span><span>+</span><span> </span><span>"px"</span><span>;</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>el</span><span>.</span><span>style</span><span>.</span><span>top</span><span> </span><span>=</span><span><span> </span><span>el</span><span>.</span></span><span>offsetTop</span><span> </span><span>+</span><span> </span><span>10</span><span> </span><span>+</span><span> </span><span>"px"</span><span>;</span></div></div><div><div><div>5</div></div><div><span>}</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>// better</span></div></div><div><div><div>8</div></div><div><span>var</span><span><span> </span><span>left</span><span> </span></span><span>=</span><span><span> </span><span>el</span><span>.</span></span><span>offsetLeft</span><span>,</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>top</span><span> </span><span>=</span><span><span> </span><span>el</span><span>.</span></span><span>offsetTop</span><span>,</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>esty</span><span> </span><span>=</span><span><span> </span><span>el</span><span>.</span></span><span>style</span><span>;</span></div></div><div><div><div>11</div></div><div><span>for</span><span><span> (</span><span>big</span><span>; </span><span>loop</span><span>; </span><span>here</span><span>) {</span></span></div></div><div><div><div>12</div></div><div><span><span>  </span></span><span>left</span><span> </span><span>+=</span><span> </span><span>10</span><span>;</span></div></div><div><div><div>13</div></div><div><span><span>  </span></span><span>top</span><span> </span><span>+=</span><span> </span><span>10</span><span>;</span></div></div><div><div><div>14</div></div><div><span><span>  </span></span><span>esty</span><span>.</span><span>left</span><span> </span><span>=</span><span><span> </span><span>left</span><span> </span></span><span>+</span><span> </span><span>"px"</span><span>;</span></div></div><div><div><div>15</div></div><div><span><span>  </span></span><span>esty</span><span>.</span><span>top</span><span> </span><span>=</span><span><span> </span><span>top</span><span> </span></span><span>+</span><span> </span><span>"px"</span><span>;</span></div></div><div><div><div>16</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><ul>
<li>通常情况下，考虑一下渲染树和变更后需要重新验证的消耗。举个例子，使用绝对定位会使得该元素单独成为渲染树中 body 的一个子元素，所以当你对其添加动画时，它不会对其它节点造成太多影响。当你在这些节点上放置这个元素时，一些其它在这个区域内的节点可能需要重绘，但是不需要重排。</li>
</ul></section></section><section><h2>性能优化<a href="#性能优化"><span>#</span></a></h2><p><img src="/usr/uploads/2019/01/3483538849.jpg" alt="" /></p></section></section>
<section><h1>CSS<a href="#css"><span>#</span></a></h1><section><h2>单位<a href="#单位"><span>#</span></a></h2><ul>
<li>px：像素</li>
<li>em：相对大小，默认 1em = 16px</li>
<li>rem：相对 HTML 根元素的字体大小，优点是只修改根元素就能成比例地调整所有字体大小，并且可以避免字体大小逐层复合的连锁反应</li>
</ul></section><section><h2>模型<a href="#模型"><span>#</span></a></h2><p><img src="/usr/uploads/2019/01/1404307731.png" alt="" /></p><p><img src="/usr/uploads/2019/01/1260770776.png" alt="" /></p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>/* 标准模型 */</span></div></div><div><div><div>2</div></div><div><span>box-sizing: content-box;</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>/*IE模型*/</span></div></div><div><div><div>5</div></div><div><span>box-sizing: border-box;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h3>边距重叠<a href="#边距重叠"><span>#</span></a></h3><p><img src="/usr/uploads/2019/01/2593026252.png" alt="" /></p><p><img src="/usr/uploads/2019/01/304123743.png" alt="" /></p></section><section><h3>边距重叠解决方案 (BFC)<a href="#边距重叠解决方案-bfc"><span>#</span></a></h3><ol>
<li>float 属性不为 none（脱离文档流）</li>
<li>position 为 absolute 或 fixed</li>
<li>display 为 inline-block, table-cell, table-caption, flex, inine-flex</li>
<li>overflow 不为 visible</li>
<li>根元素</li>
</ol><p><img src="/usr/uploads/2019/01/1295584283.png" alt="" /></p></section></section><section><h2>元素的居中<a href="#元素的居中"><span>#</span></a></h2><section><h3>行内元素（文字）<a href="#行内元素文字"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>.xxx</span><span> {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>vertical-align: </span><span>middle</span><span>;</span></div></div><div><div><div>4</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>块状元素<a href="#块状元素"><span>#</span></a></h3><ol>
<li>
<p>绝对定位 + 负margin</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>.xxx</span><span> {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>width: </span><span><span>200</span><span>px</span></span><span>;</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>height: </span><span><span>200</span><span>px</span></span><span>;</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>top: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>margin-top: </span><span><span>-100</span><span>px</span></span><span>; </span><span>/*自身的一半*/</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>margin-left: </span><span><span>-100</span><span>px</span></span><span>;</span></div></div><div><div><div>9</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>绝对定位 + margin</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>.xxx</span><span> {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>width: </span><span><span>200</span><span>px</span></span><span>;</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>height: </span><span><span>200</span><span>px</span></span><span>;</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>top: </span><span>0</span><span>;</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>left: </span><span>0</span><span>;</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>bottom: </span><span>0</span><span>;</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>right: </span><span>0</span><span>;</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>margin: </span><span>auto</span><span>;</span></div></div><div><div><div>10</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>Flex（给父元素设置）</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>.father</span><span> {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>display: </span><span>flex</span><span>;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>justify-content: </span><span>center</span><span>;</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>align-items: </span><span>center</span><span>;</span></div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>Transform</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>.xxx</span><span> {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>position: </span><span>absolute</span><span>;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>top: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>left: </span><span><span>50</span><span>%</span></span><span>;</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>transform: </span><span>translate</span><span>(</span><span><span>-50</span><span>%</span></span><span>, </span><span><span>-50</span><span>%</span></span><span>);</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>Table</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>.father</span><span> {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>display: </span><span>table</span><span>;</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div><div><div><div>4</div></div><div><span>.xxx</span><span> {</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>text-align: </span><span>center</span><span>;</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>vertical-align: </span><span>middle</span><span>;</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>display: </span><span>table-cell</span><span>;</span></div></div><div><div><div>8</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol></section></section><section><h2>清除浮动<a href="#清除浮动"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"outer clearfix"</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"float-left"</span><span>&gt;left&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"float-right"</span><span>&gt;right&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>&lt;</span><span>div</span><span> </span><span>class</span><span>=</span><span>"clear"</span><span>&gt;&lt;/</span><span>div</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span>&lt;/</span><span>div</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>
<p>添加新元素，应用<code>clear: both;</code></p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>.clear</span><span> {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>clear: </span><span>both</span><span>;</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
<p>优点：简单，代码少，浏览器兼容性好。</p>
<p>缺点：需要添加无语义的 html 元素，代码不够优雅，后期不容易维护。</p>
</li>
<li>
<p>给父元素应用<code>overflow: hidden</code>，另外在 IE6 中还需要触发 hasLayout ，可以为父元素设置容器宽高或设置<code>zoom: 1</code></p>
<p>原理是触发了浮动元素的父元素的 BFC (Block Formatting Contexts, 块级格式化上下文)，使到该父元素可以包含浮动元素</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>.outer</span><span> {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>overflow: </span><span>hidden</span><span>;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>*zoom: </span><span>1</span><span>;</span></div></div><div><div><div>4</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>使用伪元素</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>.clearfix</span><span>::after</span></span><span> {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>display: </span><span>block</span><span>;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>clear: </span><span>both</span><span>;</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>content: </span><span>""</span><span>;</span></div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol></section><section><h2>Flex 布局<a href="#flex-布局"><span>#</span></a></h2><p>采用Flex布局的元素，称为Flex容器（flex container），简称”容器”。它的所有子元素自动成为容器成员，称为Flex项目（flex item），简称”项目”。</p><p><img src="http://www.runoob.com/wp-content/uploads/2015/07/3791e575c48b3698be6a94ae1dbff79d.png" alt="" /></p><p>容器默认存在两根轴：水平的主轴（main axis）和垂直的交叉轴（cross axis）。主轴的开始位置（与边框的交叉点）叫做main start，结束位置叫做main end；交叉轴的开始位置叫做cross start，结束位置叫做cross end。</p><p>项目默认沿主轴排列。单个项目占据的主轴空间叫做main size，占据的交叉轴空间叫做cross size。</p><section><h3>容器属性<a href="#容器属性"><span>#</span></a></h3><ol>
<li>
<p><strong>flex-direction</strong> 决定主轴的方向（即项目的排列方向）</p>
<p><img src="http://www.runoob.com/wp-content/uploads/2015/07/0cbe5f8268121114e87d0546e53cda6e.png" alt="" /></p>
<ul>
<li>row（默认值）：主轴为水平方向，起点在左端。</li>
<li>row-reverse：主轴为水平方向，起点在右端。</li>
<li>column：主轴为垂直方向，起点在上沿。</li>
<li>column-reverse：主轴为垂直方向，起点在下沿。</li>
</ul>
</li>
<li>
<p><strong>flex-wrap</strong> 决定如何换行</p>
<ul>
<li>
<p>nowrap（默认）：不换行</p>
<p></p><figure><img src="http://www.runoob.com/wp-content/uploads/2015/07/9da1f23965756568b4c6ea7124db7b9a.png" alt="img" /><figcaption>img</figcaption></figure><p></p>
</li>
<li>
<p>wrap：换行，第一行在上方</p>
<p><img src="http://www.runoob.com/wp-content/uploads/2015/07/3c6b3c8b8fe5e26bca6fb57538cf72d9.jpg" alt="" /></p>
</li>
<li>
<p>wrap-reverse：换行，第一行在下方</p>
<p><img src="http://www.runoob.com/wp-content/uploads/2015/07/fb4cf2bab8b6b744b64f6d7a99cd577c.jpg" alt="" /></p>
</li>
</ul>
</li>
<li>
<p><strong>flex-flow</strong> 上述两个的简写形式，默认值为<code>row nowrap</code></p>
</li>
<li>
<p><strong>justify-content</strong> 定义项目在主轴上的对齐方式</p>
<p><img src="http://www.runoob.com/wp-content/uploads/2015/07/c55dfe8e3422458b50e985552ef13ba5.png" alt="" /></p>
</li>
<li>
<p><strong>align-items</strong> 定义项目在交叉轴上如何对齐，默认<code>flex-start</code></p>
<p><img src="http://www.runoob.com/wp-content/uploads/2015/07/2b0c39c7e7a80d5a784c8c2ca63cde17.png" alt="" /></p>
</li>
<li>
<p><strong>align-content</strong> 定义了多根轴线的对齐方式，如果项目只有一根轴线则该属性不起作用，默认<code>stretch</code></p>
<p><img src="http://www.runoob.com/wp-content/uploads/2015/07/f10918ccb8a13247c9d47715a2bd2c33.png" alt="" /></p>
</li>
</ol></section><section><h3>项目属性<a href="#项目属性"><span>#</span></a></h3><ol>
<li>
<p><strong>order</strong> 定义项目的排列顺序：数值越小，排列越靠前，默认为<code>0</code></p>
</li>
<li>
<p><strong>flex-grow</strong> 定义项目的放大比例，默认为<code>0</code>，即如果存在剩余空间，也不放大</p>
<p><img src="http://www.runoob.com/wp-content/uploads/2015/07/f41c08bb35962ed79e7686f735d6cd78.png" alt="" /></p>
</li>
<li>
<p><strong>flex-shrink</strong> 定义了项目的缩小比例，默认为<code>1</code>，即如果空间不足，该项目将缩小</p>
<p><img src="http://www.runoob.com/wp-content/uploads/2015/07/240d3e960043a729bb3ff5e34987904f.jpg" alt="" /></p>
</li>
<li>
<p><strong>flex-basis</strong> 定义了在分配多余空间之前，项目占据的主轴空间，类似<code>width</code>或<code>height</code>，默认<code>auto</code></p>
</li>
<li>
<p><strong>flex</strong> 是上面三个属性的简写，默认值<code>0 1 auto</code></p>
</li>
<li>
<p><strong>align-self</strong> 允许单个项目有与其他项目不一样的对齐方式，可覆盖<code>align-items</code>属性,默认值为<code>auto</code></p>
</li>
</ol></section></section></section>
<section><h1>Javascript<a href="#javascript"><span>#</span></a></h1><section><h2>部分值得一提的函数（常用的烂熟的就不写了）<a href="#部分值得一提的函数常用的烂熟的就不写了"><span>#</span></a></h2><section><h3>Array<a href="#array"><span>#</span></a></h3>

<table><thead><tr><th>方法</th><th>语法</th><th>描述</th></tr></thead><tbody><tr><td><a href="http://www.runoob.com/jsref/jsref-entries.html" target="_blank">entries()</a></td><td><em>array</em>.entries()</td><td>返回数组的可迭代对象，该对象包含数组的<strong>键值对</strong></td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-every.html" target="_blank">every()</a></td><td><em>array</em>.every(function(currentValue, index, arr), thisValue)</td><td>检测数值元素的每个元素是否都符合条件</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-fill.html" target="_blank">fill()</a></td><td><em>array</em>.fill(value, start, end)</td><td>使用一个固定值来填充数组</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-filter.html" target="_blank"><strong>filter()</strong></a></td><td><em>array</em>.filter(function(currentValue, index, arr), thisValue)</td><td>检测数值元素，并返回符合条件所有元素的数组</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-find.html" target="_blank">find()</a></td><td><em>array</em>.find(function(currentValue, index, arr), thisValue)</td><td>返回<strong>第一个</strong>符合传入测试（函数）条件的数组元素</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-findindex.html" target="_blank">findIndex()</a></td><td><em>array</em>.findIndex(function(currentValue, index, arr), thisValue)</td><td>返回<strong>第一个</strong>符合传入测试（函数）条件的数组元素<strong>索引</strong></td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-from.html" target="_blank">from()</a></td><td><strong>Array</strong>.from(object, mapFunction, thisValue)</td><td>通过给定的对象中创建一个数组</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-map.html" target="_blank"><strong>map()</strong></a></td><td><em>array</em>.map(function(currentValue, index, arr), thisValue)</td><td>通过指定函数处理数组的每个元素，并返回处理后的数组，<strong>不会改变原数组</strong></td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-pop.html" target="_blank">pop()</a></td><td><em>array</em>.pop()</td><td>删除并返回数组的<strong>最后一个元素</strong></td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-reduce.html" target="_blank">reduce()</a></td><td><em>array</em>.reduce(function(total, currentValue, currentIndex, arr), initialValue)</td><td>将数组元素计算为一个值（从左到右）</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-reduceright.html" target="_blank">reduceRight()</a></td><td><em>array</em>.reduceRight(function(total, currentValue, currentIndex, arr), initialValue)</td><td>将数组元素计算为一个值（从右到左）</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-reverse.html" target="_blank">reverse()</a></td><td><em>array</em>.reverse()</td><td>反转数组的元素顺序</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-shift.html" target="_blank">shift()</a></td><td><em>array</em>.shift()</td><td>删除并返回数组的<strong>第一个元素</strong></td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-slice-array.html" target="_blank"><strong>slice()</strong></a></td><td><em>array</em>.slice(<em>start</em>, <em>end</em>)</td><td>选取数组的的一部分，并返回一个新数组</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-some.html" target="_blank">some()</a></td><td><em>array</em>.some(function(currentValue, index, arr), thisValue)</td><td>检测数组元素中是否有元素符合指定条件</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-sort.html" target="_blank"><strong>sort()</strong></a></td><td><em>array</em>.sort(<em>sortfunction</em>)<br />sortfunction(a, b){return a-b} //升序</td><td>对数组的元素进行排序（默认均以字符串的规则进行排序）</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-splice.html" target="_blank"><strong>splice()</strong></a></td><td><em>array</em>.splice(<em>index</em>, <em>howmany</em>, <em>item1</em>, …, <em>itemX</em>)</td><td>从数组中 index 开始删除 howmany 个元素然后插入新元素</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-unshift.html" target="_blank">unshift()</a></td><td><em>array</em>.unshift(<em>item1</em>, <em>item2</em>, …, <em>itemX</em>)</td><td>向数组的开头添加一个或更多元素，并返回新的长度</td></tr></tbody></table></section><section><h3>String<a href="#string"><span>#</span></a></h3>

<table><thead><tr><th>方法</th><th>语法</th><th>描述</th></tr></thead><tbody><tr><td><a href="http://www.runoob.com/jsref/jsref-fromcharcode.html" target="_blank">fromCharCode()</a></td><td><strong>String</strong>.fromCharCode(<em>n1</em>, <em>n2</em>, …, <em>nX</em>)</td><td>将 Unicode 编码转为字符。</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-match.html" target="_blank">match()</a></td><td><em>string</em>.match(<em>regexp</em>)</td><td>查找找到一个或多个正则表达式的匹配，返回数组</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-replace.html" target="_blank">replace()</a></td><td><em>string</em>.replace(<em>searchvalue, newvalue</em>)</td><td>在字符串中查找匹配的子串， 并替换与正则表达式匹配的子串，searchvalue 可以是正则表达式</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-search.html" target="_blank">search()</a></td><td><em>string</em>.search(<em>searchvalue</em>)</td><td>查找与正则表达式或字符串相匹配的值，返回匹配的起始位置</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-slice-string.html" target="_blank"><strong>slice()</strong></a></td><td><em>string</em>.slice(<em>start</em>, <em>end</em>)</td><td>提取字符串的片断，并在新的字符串中返回被提取的部分，end 可以为负数（从尾部算起）</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-split.html" target="_blank"><strong>split()</strong></a></td><td><em>string</em>.split(<em>separator</em>, <em>limit</em>)</td><td>把字符串按 separator 分割为字符串数组，最多 limit 个</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-substr.html" target="_blank"><strong>substr()</strong></a></td><td><em>string</em>.substr(<em>start</em>, <em>length</em>)</td><td>从起始索引号提取字符串中指定数目的字符</td></tr><tr><td><a href="http://www.runoob.com/jsref/jsref-substring.html" target="_blank"><strong>substring()</strong></a></td><td><em>string</em>.substring(<em>from</em>, <em>to</em>)</td><td>提取字符串中两个指定的索引号之间的字符</td></tr><tr><td>trim()</td><td></td><td>去除字符串两边的空白</td></tr></tbody></table></section></section><section><h2>原型规则<a href="#原型规则"><span>#</span></a></h2><ol>
<li>
<p>所有的函数，都有一个 <code>prototype</code>（显式原型）属性，属性值是一个普通的对象</p>
</li>
<li>
<p>所有的引用类型（数组、对象、函数）， <code>__proto__ </code>属性值（隐式原型）指向它的构造函数的<code>prototype</code>属性值</p>
</li>
<li>
<p>当试图得到一个对象的某个属性时，如果这个对象本身没有这个属性，那么会去它的<code>__proto__</code>（即它的构造函数的<code>prototype</code>）中寻找</p>
</li>
<li>
<p><code>instanceof</code>：判断 <strong>引用类型</strong> 属于哪个 <strong>构造函数</strong> 的方法（如果是 <strong>基本类型</strong> 则一定<code>false</code>）</p>
<p>与<code>typeof</code>对比：一个一元运算，返回一个字符串，说明运算数的类型，一般只返回<code>number</code>、<code>string</code>、<code>boolean</code>、<code>object</code>、<code>function</code> 和 <code>undefined</code>（当运算数未定义时）</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>Object</span><span> </span></span><span>instanceof</span><span> </span><span>Object</span><span>; </span><span>//true</span></div></div><div><div><div>2</div></div><div><span><span>Object</span><span>.</span></span><span>__proto__</span><span> </span><span>===</span><span> </span><span>Function</span><span>.</span><span>prototype</span><span>;</span></div></div><div><div><div>3</div></div><div><span>Function</span><span>.</span><span>prototype</span><span>.</span><span>__proto__</span><span> </span><span>===</span><span> </span><span>Object</span><span>.</span><span>prototype</span><span>;</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>//特别地</span></div></div><div><div><div>6</div></div><div><span>Object</span><span>.</span><span>prototype</span><span>.</span><span>__proto__</span><span> </span><span>===</span><span> </span><span>null</span><span>;</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span><span>Function</span><span> </span></span><span>instanceof</span><span> </span><span>Function</span><span>; </span><span>//true</span></div></div><div><div><div>9</div></div><div><span><span>Function</span><span>.</span></span><span>__proto__</span><span> </span><span>===</span><span> </span><span>Function</span><span>.</span><span>prototype</span><span>;</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol></section><section><h2>this 指向<a href="#this-指向"><span>#</span></a></h2><p>在闭包中，由于匿名函数的执行具有全局性，所以其 this 会指向 window</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>var</span><span><span> </span><span>myNumber</span><span> </span></span><span>=</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>value</span><span>:</span><span> </span><span>1</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>add</span><span>:</span><span> </span><span>function</span><span><span> (</span><span>i</span><span>) {</span></span></div></div><div><div><div>4</div></div><div><span>    </span><span>var</span><span> </span><span>helper</span><span> </span><span>=</span><span> </span><span>function</span><span><span> (</span><span>i</span><span>) {</span></span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>this</span><span>);</span></div></div><div><div><div>6</div></div><div><span>      </span><span>this</span><span>.</span><span>value</span><span> </span><span>+=</span><span><span> </span><span>i</span><span>;</span></span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>};</span></div></div><div><div><div>8</div></div><div><span>    </span><span>helper</span><span><span>(</span><span>i</span><span>);</span></span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>10</div></div><div><span>};</span></div></div><div><div><div>11</div></div><div><span><span>myNumber</span><span>.</span></span><span>add</span><span>(</span><span>1</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>例如此代码无法实现 value 加1</p><section><h3>修改方法<a href="#修改方法"><span>#</span></a></h3><ol>
<li>
<p>使用另一个变量保存 this</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>var</span><span><span> </span><span>myNumber</span><span> </span></span><span>=</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>value</span><span>:</span><span> </span><span>1</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>add</span><span>:</span><span> </span><span>function</span><span><span> (</span><span>i</span><span>) {</span></span></div></div><div><div><div>4</div></div><div><span>    </span><span>var</span><span><span> </span><span>that</span><span> </span></span><span>=</span><span> </span><span>this</span><span>; </span><span>//定义变量that用于保存上层函数的this对象</span></div></div><div><div><div>5</div></div><div><span>    </span><span>var</span><span> </span><span>helper</span><span> </span><span>=</span><span> </span><span>function</span><span><span> (</span><span>i</span><span>) {</span></span></div></div><div><div><div>6</div></div><div><span><span>      </span></span><span>console</span><span>.</span><span>log</span><span><span>(</span><span>that</span><span>);</span></span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>that</span><span>.</span><span>value</span><span> </span><span>+=</span><span><span> </span><span>i</span><span>;</span></span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>};</span></div></div><div><div><div>9</div></div><div><span>    </span><span>helper</span><span><span>(</span><span>i</span><span>);</span></span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>11</div></div><div><span>};</span></div></div><div><div><div>12</div></div><div><span><span>myNumber</span><span>.</span></span><span>add</span><span>(</span><span>1</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>使用 apply 或 call 改变 this 指向</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>var</span><span><span> </span><span>myNumber</span><span> </span></span><span>=</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>value</span><span>:</span><span> </span><span>1</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>add</span><span>:</span><span> </span><span>function</span><span><span> (</span><span>i</span><span>) {</span></span></div></div><div><div><div>4</div></div><div><span>    </span><span>var</span><span> </span><span>helper</span><span> </span><span>=</span><span> </span><span>function</span><span><span> (</span><span>i</span><span>) {</span></span></div></div><div><div><div>5</div></div><div><span>      </span><span>this</span><span>.</span><span>value</span><span> </span><span>+=</span><span><span> </span><span>i</span><span>;</span></span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>};</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>helper</span><span>.</span><span>apply</span><span>(</span><span>this</span><span><span>, [</span><span>i</span><span>]); </span></span><span>//使用apply改变helper的this对象指向</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>9</div></div><div><span>};</span></div></div><div><div><div>10</div></div><div><span><span>myNumber</span><span>.</span></span><span>add</span><span>(</span><span>1</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>使用 bind 绑定 this</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>var</span><span><span> </span><span>myNumber</span><span> </span></span><span>=</span><span> {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>value</span><span>:</span><span> </span><span>1</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>add</span><span>:</span><span> </span><span>function</span><span><span> (</span><span>i</span><span>) {</span></span></div></div><div><div><div>4</div></div><div><span>    </span><span>var</span><span> </span><span>helper</span><span> </span><span>=</span><span> </span><span>function</span><span><span> (</span><span>i</span><span>) {</span></span></div></div><div><div><div>5</div></div><div><span>      </span><span>this</span><span>.</span><span>value</span><span> </span><span>+=</span><span><span> </span><span>i</span><span>;</span></span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>}.</span><span>bind</span><span>(</span><span>this</span><span><span>, </span><span>i</span><span>); </span></span><span>//使用bind绑定，它返回的是对函数的引用，不会立即执行</span></div></div><div><div><div>7</div></div><div><span>    </span><span>helper</span><span><span>(</span><span>i</span><span>);</span></span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>9</div></div><div><span>};</span></div></div><div><div><div>10</div></div><div><span><span>myNumber</span><span>.</span></span><span>add</span><span>(</span><span>1</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol></section></section><section><h2>运行机制<a href="#运行机制"><span>#</span></a></h2><p>JavaScript语言的一大特点就是单线程，也就是说，同一个时间只能做一件事。那么，为什么JavaScript不能有多个线程呢？这样能提高效率啊。</p><p>JavaScript的单线程，与它的用途有关。作为浏览器脚本语言，JavaScript的主要用途是与用户互动，以及操作DOM。这决定了它只能是单线程，否则会带来很复杂的同步问题。比如，假定JavaScript同时有两个线程，一个线程在某个DOM节点上添加内容，另一个线程删除了这个节点，这时浏览器应该以哪个线程为准？</p><p>所以，为了避免复杂性，从一诞生，JavaScript就是单线程，这已经成了这门语言的核心特征，将来也不会改变。</p><p>为了利用多核CPU的计算能力，HTML5提出Web Worker标准，允许JavaScript脚本创建多个线程，但是子线程完全受主线程控制，且不得操作DOM。所以，这个新标准并没有改变JavaScript单线程的本质。</p><section><h3>任务队列<a href="#任务队列"><span>#</span></a></h3><p>单线程就意味着，所有任务需要排队，前一个任务结束，才会执行后一个任务。如果前一个任务耗时很长，后一个任务就不得不一直等着。</p><p>JavaScript语言的设计者意识到，这时主线程完全可以不管IO设备，挂起处于等待中的任务，先运行排在后面的任务。等到IO设备返回了结果，再回过头，把挂起的任务继续执行下去。</p><p>于是，所有任务可以分成两种，一种是同步任务（synchronous），另一种是异步任务（asynchronous）。同步任务指的是，在主线程上排队执行的任务，只有前一个任务执行完毕，才能执行后一个任务；异步任务指的是，不进入主线程、而进入”任务队列”（task queue）的任务，只有”任务队列”通知主线程，某个异步任务可以执行了，该任务才会进入主线程执行。</p><p>异步执行的运行机制如下：</p><ol>
<li>
<p>所有同步任务都在主线程上执行，形成一个<a href="http://www.ruanyifeng.com/blog/2013/11/stack.html" target="_blank">执行栈</a>（execution context stack）。</p>
</li>
<li>
<p>主线程之外，还存在一个”任务队列”（task queue）。只要异步任务有了运行结果，就在”任务队列”之中放置一个事件。</p>
</li>
<li>
<p>一旦”执行栈”中的所有同步任务执行完毕，系统就会读取”任务队列”，看看里面有哪些事件。那些对应的异步任务，于是结束等待状态，进入执行栈，开始执行。</p>
</li>
<li>
<p>主线程不断重复上面的第三步。</p>
<p><img src="http://www.ruanyifeng.com/blogimg/asset/2014/bg2014100801.jpg" alt="" /></p>
</li>
</ol></section><section><h3>Event Loop<a href="#event-loop"><span>#</span></a></h3><p>主线程从”任务队列”中读取事件，这个过程是循环不断的，所以整个的这种运行机制又称为Event Loop（事件循环）。</p><p></p><figure><img src="http://www.ruanyifeng.com/blogimg/asset/2014/bg2014100802.png" alt="Event Loop" /><figcaption>Event Loop</figcaption></figure><p></p><p>主线程运行的时候，产生堆（heap）和栈（stack），栈中的代码调用各种外部API，它们在”任务队列”中加入各种事件（click，load，done）。只要栈中的代码执行完毕，主线程就会去读取”任务队列”，依次执行那些事件所对应的回调函数。</p><p>执行栈中的代码（同步任务），总是在读取”任务队列”（异步任务）之前执行，例如以下两段代码是等价的：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>var</span><span><span> </span><span>req</span><span> </span></span><span>=</span><span> </span><span>new</span><span> </span><span>XMLHttpRequest</span><span>();</span></div></div><div><div><div>2</div></div><div><span><span>req</span><span>.</span></span><span>open</span><span>(</span><span>"GET"</span><span><span>, </span><span>url</span><span>);</span></span></div></div><div><div><div>3</div></div><div><span><span>req</span><span>.</span></span><span>onload</span><span> </span><span>=</span><span> </span><span>function</span><span> () {};</span></div></div><div><div><div>4</div></div><div><span><span>req</span><span>.</span></span><span>onerror</span><span> </span><span>=</span><span> </span><span>function</span><span> () {};</span></div></div><div><div><div>5</div></div><div><span><span>req</span><span>.</span></span><span>send</span><span>();</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>var</span><span><span> </span><span>req</span><span> </span></span><span>=</span><span> </span><span>new</span><span> </span><span>XMLHttpRequest</span><span>();</span></div></div><div><div><div>2</div></div><div><span><span>req</span><span>.</span></span><span>open</span><span>(</span><span>"GET"</span><span><span>, </span><span>url</span><span>);</span></span></div></div><div><div><div>3</div></div><div><span><span>req</span><span>.</span></span><span>send</span><span>();</span></div></div><div><div><div>4</div></div><div><span><span>req</span><span>.</span></span><span>onload</span><span> </span><span>=</span><span> </span><span>function</span><span> () {};</span></div></div><div><div><div>5</div></div><div><span><span>req</span><span>.</span></span><span>onerror</span><span> </span><span>=</span><span> </span><span>function</span><span> () {};</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>指定回调函数的部分（onload 和 onerror），在 send() 方法的前面或后面无关紧要，因为它们属于执行栈的一部分，系统总是执行完它们，才会去读取”任务队列”。</p></section><section><h3>宏任务与微任务<a href="#宏任务与微任务"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>setTimeout</span><span>(</span><span>function</span><span> () {</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>"1"</span><span>);</span></div></div><div><div><div>3</div></div><div><span>});</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>new</span><span> </span><span>Promise</span><span>(</span><span>function</span><span><span> (</span><span>resolve</span><span>) {</span></span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>"2"</span><span>);</span></div></div><div><div><div>7</div></div><div><span>  </span><span>resolve</span><span>();</span></div></div><div><div><div>8</div></div><div><span>}).</span><span>then</span><span>(</span><span>function</span><span> () {</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>"3"</span><span>);</span></div></div><div><div><div>10</div></div><div><span>});</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>"4"</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>代码运行顺序：2 4 3 1</p><p>宏任务：包括整体代码、<code>setTimeout</code>、<code>setInterval</code></p><p>微任务：<code>Promise</code>、<code>process.nextTick</code></p><p>异步有一个机制，就是遇到宏任务，先执行宏任务，将宏任务放入 eventqueue，然后在执行微任务，将微任务放入 eventqueue，并且这两个队列不是一个队列。当你往外拿的时候，先从微任务队列里拿回掉函数，然后再从宏任务队列里拿回掉函数。</p><p><img src="/usr/uploads/2019/01/4250245252.png" alt="" /></p></section></section><section><h2>事件<a href="#事件"><span>#</span></a></h2><section><h3>事件捕获<a href="#事件捕获"><span>#</span></a></h3><p>通俗的理解就是，当鼠标点击或者触发dom事件时，浏览器会从根节点开始<strong>由外到内</strong>进行事件传播，即点击了子元素，如果父元素通过事件捕获方式注册了对应的事件的话，会先触发父元素绑定的事件。</p></section><section><h3>事件冒泡<a href="#事件冒泡"><span>#</span></a></h3><p>与事件捕获恰恰相反，事件冒泡顺序是由内到外进行事件传播，直到根节点。</p></section><section><h3>事件传播<a href="#事件传播"><span>#</span></a></h3><p>DOM 标准事件流的触发的先后顺序为：<strong>先捕获再冒泡</strong>，即当触发dom事件时，会先进行事件捕获，捕获到事件源之后通过事件传播进行事件冒泡。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>element</span><span>.</span></span><span>addEventListener</span><span><span>(</span><span>event</span><span>, </span></span><span>function</span><span>, </span><span>useCapture</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>第一个参数是需要绑定的事件<br />
第二个参数是触发事件后要执行的函数<br />
第三个参数默认值是<code>false</code>，表示在<strong>事件冒泡阶段</strong>调用事件处理函数；如果参数为<code>true</code>，则表示在<strong>事件捕获阶段</strong>调用处理函数。</p></section></section><section><h2>bind / apply / call<a href="#bind--apply--call"><span>#</span></a></h2><section><h3>bind<a href="#bind"><span>#</span></a></h3><p><code>bind()</code>用于创建一个函数，并将这个函数的<code>this</code>值绑定到某个对象</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>this</span><span>.</span><span>num</span><span> </span><span>=</span><span> </span><span>9</span><span>;</span></div></div><div><div><div>2</div></div><div><span>var</span><span><span> </span><span>mymodule</span><span> </span></span><span>=</span><span> {</span></div></div><div><div><div>3</div></div><div><span>  </span><span>num</span><span>:</span><span> </span><span>81</span><span>,</span></div></div><div><div><div>4</div></div><div><span>  </span><span>getNum</span><span>:</span><span> </span><span>function</span><span> () {</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>this</span><span>.</span><span>num</span><span>);</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>7</div></div><div><span>};</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span><span>mymodule</span><span>.</span></span><span>getNum</span><span>(); </span><span>// 81</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>var</span><span><span> </span><span>getNum</span><span> </span></span><span>=</span><span><span> </span><span>mymodule</span><span>.</span></span><span>getNum</span><span>;</span></div></div><div><div><div>12</div></div><div><span>getNum</span><span>(); </span><span>// 9, 因为在这个例子中，"this"指向全局对象</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>var</span><span><span> </span><span>boundGetNum</span><span> </span></span><span>=</span><span><span> </span><span>getNum</span><span>.</span></span><span>bind</span><span><span>(</span><span>mymodule</span><span>);</span></span></div></div><div><div><div>15</div></div><div><span>boundGetNum</span><span>(); </span><span>// 81</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>apply / call<a href="#apply--call"><span>#</span></a></h3><p>作用完全一样，只是参数接收方式不一样</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>func</span><span>.</span></span><span>call</span><span>(</span><span>this</span><span><span>, </span><span>arg1</span><span>, </span><span>arg2</span><span>);</span></span></div></div><div><div><div>2</div></div><div><span><span>func</span><span>.</span></span><span>apply</span><span>(</span><span>this</span><span><span>, [</span><span>arg1</span><span>, </span><span>arg2</span><span>]);</span></span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>//在ES6中可以利用rest参数</span></div></div><div><div><div>5</div></div><div><span><span>func</span><span>.</span></span><span>call</span><span>(</span><span>this</span><span>, </span><span>...</span><span><span>args</span><span>);</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h2>Promise<a href="#promise"><span>#</span></a></h2><section><h3>then 的第二个参数和 catch 的区别<a href="#then-的第二个参数和-catch-的区别"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>getJSON</span><span>(</span><span>"/post/1.json"</span><span>)</span></div></div><div><div><div>2</div></div><div><span><span>  </span></span><span>.</span><span>then</span><span><span>((</span><span>post</span><span>) </span></span><span>=&gt;</span><span> </span><span>getJSON</span><span><span>(</span><span>post</span><span>.</span></span><span>commentURL</span><span>))</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>.</span><span>then</span><span>(</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>(</span><span>comments</span><span>) </span><span>=&gt;</span><span><span> </span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>"resolved: "</span><span><span>, </span><span>comments</span><span>),</span></span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>(</span><span>err</span><span>) </span><span>=&gt;</span><span><span> </span><span>console</span><span>.</span></span><span>log</span><span>(</span><span>"rejected: "</span><span><span>, </span><span>err</span><span>),</span></span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>在第一个<code>then()</code>中的异常可以被第二个<code>then()</code>的第二个参数指定的回调函数处理，但第二个<code>then()</code>中第一个参数指定的回调函数如果产生了异常，则不能被第二个参数指定的回调函数处理</p><p>如果在最后使用<code>catch()</code>捕获处理，则没有这个问题</p></section><section><h3>all 和 rase<a href="#all-和-rase"><span>#</span></a></h3><p><code>Promise.all</code>和<code>Promise.rase</code>方法都用于将多个 Promise 实例，包装成一个新的 Promise 实例</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> </span><span>p_all</span><span> </span><span>=</span><span> </span><span>Promise</span><span>.</span><span>all</span><span><span>([</span><span>p1</span><span>, </span><span>p2</span><span>, </span><span>p3</span><span>]);</span></span></div></div><div><div><div>2</div></div><div><span>const</span><span> </span><span>p_rase</span><span> </span><span>=</span><span> </span><span>Promise</span><span>.</span><span>rase</span><span><span>([</span><span>p1</span><span>, </span><span>p2</span><span>, </span><span>p3</span><span>]);</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>其区别是：</p><ul>
<li><code>Promise.all</code>
<ul>
<li>只有<code>p1</code>、<code>p2</code>、<code>p3</code>的状态都变成<code>fulfilled</code>，<code>p_all</code>的状态才会变成<code>fulfilled</code>，此时<code>p1</code>、<code>p2</code>、<code>p3</code>的返回值组成一个数组，传递给<code>p_all</code>的回调函数</li>
<li>只要<code>p1</code>、<code>p2</code>、<code>p3</code>之中有一个被<code>rejected</code>，<code>p_all</code>的状态就变成<code>rejected</code>，此时第一个被<code>reject</code>的实例的返回值，会传递给<code>p_all</code>的回调函数。</li>
</ul>
</li>
<li><code>Promise.rase</code>
<ul>
<li>只要<code>p1</code>、<code>p2</code>、<code>p3</code>之中有一个实例率先改变状态，<code>p_rase</code>的状态就跟着改变，那个率先改变的 Promise 实例的返回值，就传递给<code>p</code>的回调函数</li>
</ul>
</li>
</ul></section></section><section><h2>Ajax<a href="#ajax"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>let</span><span><span> </span><span>xmlhttp</span><span> </span></span><span>=</span><span> </span><span>new</span><span> </span><span>XMLHttpRequest</span><span>();</span></div></div><div><div><div>2</div></div><div><span><span>xmlhttp</span><span>.</span></span><span>open</span><span>(</span><span>"GET"</span><span>, </span><span>"index.html"</span><span>, </span><span>true</span><span>); </span><span>//method, url, async</span></div></div><div><div><div>3</div></div><div><span><span>xmlhttp</span><span>.</span></span><span>send</span><span>();</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h3>属性和事件<a href="#属性和事件"><span>#</span></a></h3><section><h4>ReadyState 属性<a href="#readystate-属性"><span>#</span></a></h4>

<table><thead><tr><th>取值</th><th>描述</th></tr></thead><tbody><tr><td>0</td><td>描述一种”未初始化”状态；此时，已经创建一个 XMLHttpRequest 对象，但是还没有初始化。</td></tr><tr><td>1</td><td>描述一种”发送”状态；此时，代码已经调用了 open() 方法并且 XMLHttpRequest 已经准备好把一个请求发送到服务器。</td></tr><tr><td>2</td><td>描述一种”发送”状态；此时，已经通过 send() 方法把一个请求发送到服务器端，但是还没有收到一个响应。</td></tr><tr><td>3</td><td>描述一种”正在接收”状态；此时，已经接收到 HTTP 响应头部信息，但是消息体部分还没有完全接收结束。</td></tr><tr><td>4</td><td>描述一种”已加载”状态；此时，响应已经被完全接收。</td></tr></tbody></table></section><section><h4>onreadystatechange 事件<a href="#onreadystatechange-事件"><span>#</span></a></h4><p>无论 readyState 值何时发生改变，XMLHttpRequest 对象都会激发一个 readystatechange 事件。</p></section><section><h4>responseText 属性<a href="#responsetext-属性"><span>#</span></a></h4><p>这个 responseText 属性包含客户端接收到的 HTTP 响应的文本内容。当 readyState 值为0、1或2时， responseText 包含一个空字符串。当 readyState 值为3（正在接收）时，响应中包含客户端还未完成的响应信息。当 readyState 为4（已加载）时，该 responseText 包含完整的响应信息。</p></section><section><h4>responseXML 属性<a href="#responsexml-属性"><span>#</span></a></h4><p>如果 Content-Type 头部并不包含 text/xml、application/xml 或以 +xml 结尾的这些媒体类型之一，那么 responseXML 的值为 null。无论何时，只要 readyState 值不为4，那么该 responseXML 的值也为null。</p></section><section><h4>status / statusText 属性<a href="#status--statustext-属性"><span>#</span></a></h4><p>这个属性描述了 HTTP 状态代码以及状态码文本。仅当 readyState 值为3（正在接收中）或4（已加载）时，这个属性才可用。当 readyState 的值小于3时试图存取 status 的值将引发一个异常。</p></section></section></section><section><h2>函数节流与函数防抖<a href="#函数节流与函数防抖"><span>#</span></a></h2><ul>
<li>
<p>函数节流：指定时间间隔内只会执行一次任务</p>
</li>
<li>
<p>函数防抖：任务频繁触发的情况下，只有任务触发的间隔超过指定间隔的时候，任务才会执行</p>
</li>
</ul><section><h3>函数节流 (throttle)<a href="#函数节流-throttle"><span>#</span></a></h3><p>例如你需要监听<code>window</code>的<code>scroll</code>事件，但连续滚动时每一次微小的滚动都会触发一次事件，使得函数被高频率调用，此时你希望在一个固定时间段内只执行一次函数中的操作</p><p>函数的节流就是通过闭包保存一个标记（<code>canRun = true</code>），在函数的开头<strong>判断</strong>这个标记是否为 <code>true</code>，如果为 <code>true</code> 的话就继续执行函数，否则 return 掉，判断完标记后立即把这个标记设为 <code>false</code>，然后把外部传入的函数的执行包在一个 <code>setTimeout</code> 中，最后在 <code>setTimeout</code>执行完毕后再把标记设置为 <code>true</code>（这里很关键），表示可以执行下一次的循环了。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>throttle</span><span><span>(</span><span>fn</span><span>, </span><span>interval</span><span> </span></span><span>=</span><span> </span><span>300</span><span>) {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>let</span><span><span> </span><span>canRun</span><span> </span></span><span>=</span><span> </span><span>true</span><span>; </span><span>//标记</span></div></div><div><div><div>3</div></div><div><span>  </span><span>return</span><span> </span><span>function</span><span> () {</span></div></div><div><div><div>4</div></div><div><span>    </span><span>if</span><span> (</span><span>!</span><span><span>canRun</span><span>) </span></span><span>return</span><span>;</span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>canRun</span><span> </span><span>=</span><span> </span><span>false</span><span>;</span></div></div><div><div><div>6</div></div><div><span>    </span><span>setTimeout</span><span>(() </span><span>=&gt;</span><span> {</span></div></div><div><div><div>7</div></div><div><span><span>      </span></span><span>fn</span><span>.</span><span>apply</span><span>(</span><span>this</span><span>, </span><span>arguments</span><span>);</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>canRun</span><span> </span><span>=</span><span> </span><span>true</span><span>;</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>}, </span><span>interval</span><span>);</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>};</span></div></div><div><div><div>11</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>函数防抖 (debounce)<a href="#函数防抖-debounce"><span>#</span></a></h3><p>以用户注册时验证用户名是否被占用为例，如今很多网站为了提高用户体验，不会再输入框失去焦点的时候再去判断用户名是否被占用，而是在输入的时候就在判断这个用户名是否已被注册。</p><p>如果每次输入一个字符就验证一次，不仅对服务器的压力增大了，对用户体验也未必比原来的好。而理想的做法应该是这样的，当用户输入第一个字符后的一段时间内如果还有字符输入的话，那就暂时不去请求判断用户名是否被占用。</p><p>通过闭包保存一个标记来保存 <code>setTimeout</code> 返回的值，每当用户输入时就把 <code>setTimeout</code> clear 掉，然后又创建一个新的 <code>setTimeout</code>，这样就能保证输入字符后的 <code>interval</code> 间隔内如果还有字符输入的话，就不会执行 <code>fn</code> 函数了。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>debounce</span><span><span>(</span><span>fn</span><span>, </span><span>interval</span><span> </span></span><span>=</span><span> </span><span>300</span><span>) {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>let</span><span><span> </span><span>timeout</span><span> </span></span><span>=</span><span> </span><span>null</span><span>;</span></div></div><div><div><div>3</div></div><div><span>  </span><span>return</span><span> </span><span>function</span><span> () {</span></div></div><div><div><div>4</div></div><div><span>    </span><span>clearTimeout</span><span><span>(</span><span>timeout</span><span>);</span></span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>timeout</span><span> </span><span>=</span><span> </span><span>setTimeout</span><span>(() </span><span>=&gt;</span><span> {</span></div></div><div><div><div>6</div></div><div><span><span>      </span></span><span>fn</span><span>.</span><span>apply</span><span>(</span><span>this</span><span>, </span><span>arguments</span><span>);</span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>}, </span><span>interval</span><span>);</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>};</span></div></div><div><div><div>9</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h2>垃圾回收<a href="#垃圾回收"><span>#</span></a></h2><p>JavaScript 垃圾回收的机制很简单：找出不再使用的变量，然后释放掉其占用的内存，但是这个过程不是时时的，因为其开销比较大，所以垃圾回收器会按照固定的时间间隔周期性的执行。</p><section><h3>变量生命周期<a href="#变量生命周期"><span>#</span></a></h3><p>不再使用的变量也就是生命周期结束的变量，当然只可能是局部变量，全局变量的生命周期直至浏览器卸载页面才会结束。</p><p>局部变量只在函数的执行过程中存在，而在这个过程中会为局部变量在栈或堆上分配相应的空间，以存储它们的值，然后再函数中使用这些变量，直至函数结束（闭包中由于内部函数的原因，外部函数并不能算是结束）。</p></section><section><h3>标记清除 (mark and sweep)<a href="#标记清除-mark-and-sweep"><span>#</span></a></h3><p>这是 JavaScript 最常见的垃圾回收方式，当变量进入执行环境的时候，比如函数中声明一个变量，垃圾回收器将其标记为“进入环境”，当变量离开环境的时候（函数执行结束）将其标记为“离开环境”。</p><p>垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记，然后去掉环境中的变量以及被环境中变量所引用的变量（闭包），在这些完成之后仍存在标记的就是要删除的变量了，因为环境中的变量已经无法访问到这些变量了。</p></section><section><h3>引用计数 (reference counting)<a href="#引用计数-reference-counting"><span>#</span></a></h3><p>引用计数的策略是跟踪记录每个值被使用的次数，当声明了一个变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1，如果该变量的值变成了另外一个，则这个值得引用次数减1，当这个值的引用次数变为0的时候，说明没有变量在使用，这个值没法被访问了，因此可以将其占用的空间回收，这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。</p><p>在低版本IE中经常会出现内存泄露，很多时候就是因为其采用引用计数方式进行垃圾回收，这种方式没办法解决循环引用问题。</p></section></section><section><h2>变量提升<a href="#变量提升"><span>#</span></a></h2><p>仅针对使用<code>var</code>声明变量的情况，使用<code>let</code>声明不会提升</p><p>JavaScript 中，函数及变量的声明都将被提升到函数的最顶部，函数被提升到变量声明之上。</p><p>JavaScript 中，变量可以在使用后声明，也就是变量可以先使用再声明。</p><p>JavaScript 只有声明的变量会提升，初始化的不会。</p></section><section><h2>严格模式<a href="#严格模式"><span>#</span></a></h2><p>严格模式通过在脚本或函数的头部添加<code>"use strict";</code>表达式来声明。</p><p>严格模式下的限制：</p><ol>
<li>不允许使用未声明的变量</li>
<li>不允许删除变量或对象</li>
<li>不允许删除函数</li>
<li>不允许变量重名</li>
<li>不允许使用八进制</li>
<li>不允许使用转义字符</li>
<li>不允许对只读属性赋值</li>
<li>不允许对一个使用 getter 方法读取的属性进行赋值</li>
<li>不允许删除一个不允许删除的属性</li>
<li>变量名不能使用保留关键字</li>
<li>由于一些安全原因，在作用域<code>eval()</code>创建的变量不能被调用</li>
<li>禁止<code>this</code>关键字指向全局对象（因此，使用构造函数时，如果忘了加<code>new</code>，<code>this</code>不再指向全局对象，而是报错）</li>
</ol></section></section>
<section><h1>算法<a href="#算法"><span>#</span></a></h1><section><h2>快速排序<a href="#快速排序"><span>#</span></a></h2><p>假设要排序的数组是<code>A[0]</code>~<code>A[N-1]</code></p><ol>
<li>设置两个变量<code>i=0</code>，<code>j=N-1</code></li>
<li>取数组第一个元素作为枢轴量，<code>k=A[0]</code></li>
<li>从<code>j</code>开始向前搜索，找到第一个小于<code>k</code>的值<code>A[j]</code>；从<code>i</code>开始向后搜索，找到第一个大于<code>k</code>的值<code>A[i]</code></li>
<li>交换<code>A[i]</code>与<code>A[j]</code></li>
<li>重复3、4，直到<code>i==j</code></li>
<li>对<code>i</code>的左右部分进行同样的排序操作</li>
</ol><section><h3>时间复杂度<a href="#时间复杂度"><span>#</span></a></h3><ul>
<li>最坏情况<code>O(n²)</code>
每次划分过程产生的两个区间分别包含 n-1 个元素和 1 个元素</li>
<li>最好情况<code>O(nlogn)</code>
每次划分过程产生的两个区间大小都为 n/2</li>
<li>平均情况<code>O(nlogn)</code></li>
</ul></section></section></section>
<section><h1>参考资料<a href="#参考资料"><span>#</span></a></h1><p><a href="http://www.runoob.com" target="_blank">http://www.runoob.com</a>
<a href="https://juejin.im/entry/582f16fca22b9d006b7afd89" target="_blank">https://juejin.im/entry/582f16fca22b9d006b7afd89</a>
<a href="https://juejin.im/entry/58c0379e44d9040068dc952f" target="_blank">https://juejin.im/entry/58c0379e44d9040068dc952f</a>
<a href="https://segmentfault.com/a/1190000004865198" target="_blank">https://segmentfault.com/a/1190000004865198</a>
<a href="https://segmentfault.com/a/1190000011145364" target="_blank">https://segmentfault.com/a/1190000011145364</a>
<a href="https://www.cnblogs.com/jianghao233/p/8983176.html" target="_blank">https://www.cnblogs.com/jianghao233/p/8983176.html</a>
<a href="https://www.cnblogs.com/xuehaoyue/p/6639029.html" target="_blank">https://www.cnblogs.com/xuehaoyue/p/6639029.html</a>
<a href="http://uule.iteye.com/blog/2412003" target="_blank">http://uule.iteye.com/blog/2412003</a>
<a href="https://www.cnblogs.com/dolphinX/p/3348468.html" target="_blank">https://www.cnblogs.com/dolphinX/p/3348468.html</a>
<a href="https://www.cnblogs.com/cs_net/articles/1820653.html" target="_blank">https://www.cnblogs.com/cs_net/articles/1820653.html</a>
<a href="https://segmentfault.com/a/1190000011942746" target="_blank">https://segmentfault.com/a/1190000011942746</a>
<a href="http://www.cnblogs.com/chengzp/p/cssbox.html" target="_blank">http://www.cnblogs.com/chengzp/p/cssbox.html</a>
<a href="https://blog.csdn.net/qq_21794603/article/details/71698943" target="_blank">https://blog.csdn.net/qq_21794603/article/details/71698943</a>
<a href="http://www.ruanyifeng.com/blog/2014/10/event-loop.html" target="_blank">http://www.ruanyifeng.com/blog/2014/10/event-loop.html</a>
<a href="https://www.cnblogs.com/bfgis/p/5460191.html" target="_blank">https://www.cnblogs.com/bfgis/p/5460191.html</a>
<a href="http://jerryzou.com/posts/cookie-and-web-storage/" target="_blank">http://jerryzou.com/posts/cookie-and-web-storage/</a>
<a href="https://my.oschina.net/ioslighter/blog/359207" target="_blank">https://my.oschina.net/ioslighter/blog/359207</a>
<a href="https://www.jianshu.com/p/9535e7924dba" target="_blank">https://www.jianshu.com/p/9535e7924dba</a>
<a href="https://segmentfault.com/a/1190000016199807" target="_blank">https://segmentfault.com/a/1190000016199807</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/ode/</id>
      <title type="text">常微分复习提纲</title>
      <published>2019-01-21T05:24:00.000Z</published>
      <updated>2019-01-21T05:35:40.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/ode/"/>
      <summary type="text">去年刚挂的科，重修时为努力复习所写的提纲，不说了，大学数学一生黑</summary>
      <content type="html"><![CDATA[<p>去年刚挂的科，重修时为努力复习所写的提纲，不说了，大学数学一生黑</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=72713604" target="_blank">【Fate/GrandOrder】「何だかんだ仲がいい」/「翠月 琉」のイラスト [pixiv]</a></p>
<hr />
<section><h2>第一章 绪论<a href="#第一章-绪论"><span>#</span></a></h2><p><span><span>∫0dx=C∫1dx=x+C∫xadx=xa+1a+1+C (a≠−1,x&gt;0)∫1xdx=ln⁡∣x∣+C∫axdx=axln⁡a+C (a&gt;0,a≠1)∫cos⁡axdx=1asin⁡ax+C (a≠0)∫sin⁡axdx=−1acos⁡ax+C (a≠0)∫dx1−x2=arcsin⁡x+C=−arccos⁡x+C′∫dx1+x2=arctan⁡x+C=− arccot x+C′\displaystyle\large{
\int 0dx=C\\
\int 1dx=x+C\\
\int x^adx=\frac{x^{a+1}}{a+1}+C\ (a\ne-1,x&gt;0)\\
\int\frac1xdx=\ln|x|+C\\
\int a^xdx=\frac{a^x}{\ln a}+C\ (a&gt;0,a\ne1)\\
\int\cos axdx=\frac1a\sin ax+C\ (a\ne0)\\
\int\sin axdx=-\frac1a\cos ax+C\ (a\ne0)\\
\int\frac{dx}{\sqrt{1-x^2}}=\arcsin x+C=-\arccos x+C'\\
\int\frac{dx}{1+x^2}=\arctan x+C=-\mathrm{\,arccot\,}x+C'}</span><span><span><span></span><span><span>∫</span><span></span><span>0</span><span>d</span><span>x</span><span></span><span>=</span><span></span><span>C</span><span></span><span></span><span>∫</span><span></span><span>1</span><span>d</span><span>x</span><span></span><span>=</span><span></span><span>x</span><span></span><span>+</span><span></span><span>C</span><span></span><span></span><span>∫</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>a</span></span></span></span></span></span></span></span><span>d</span><span>x</span><span></span><span>=</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>a</span><span></span><span>+</span><span></span><span>1</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>a</span><span>+</span><span>1</span></span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>+</span><span></span><span>C</span><span> </span><span>(</span><span>a</span><span></span><span><span><span><span><span><span></span><span><span><span></span></span></span><span></span></span></span></span></span><span></span><span>=</span></span><span></span><span>−</span><span>1</span><span>,</span><span></span><span>x</span><span></span><span>&gt;</span><span></span><span>0</span><span>)</span><span></span><span></span><span>∫</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>d</span><span>x</span><span></span><span>=</span><span></span><span>ln</span><span></span><span>∣</span><span>x</span><span>∣</span><span></span><span>+</span><span></span><span>C</span><span></span><span></span><span>∫</span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>x</span></span></span></span></span></span></span></span><span>d</span><span>x</span><span></span><span>=</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>ln</span><span></span><span>a</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>a</span><span><span><span><span><span><span></span><span><span>x</span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>+</span><span></span><span>C</span><span> </span><span>(</span><span>a</span><span></span><span>&gt;</span><span></span><span>0</span><span>,</span><span></span><span>a</span><span></span><span><span><span><span><span><span></span><span><span><span></span></span></span><span></span></span></span></span></span><span></span><span>=</span></span><span></span><span>1</span><span>)</span><span></span><span></span><span>∫</span><span></span><span>cos</span><span></span><span>a</span><span>x</span><span>d</span><span>x</span><span></span><span>=</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>a</span></span></span><span><span></span><span></span></span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>sin</span><span></span><span>a</span><span>x</span><span></span><span>+</span><span></span><span>C</span><span> </span><span>(</span><span>a</span><span></span><span><span><span><span><span><span></span><span><span><span></span></span></span><span></span></span></span></span></span><span></span><span>=</span></span><span></span><span>0</span><span>)</span><span></span><span></span><span>∫</span><span></span><span>sin</span><span></span><span>a</span><span>x</span><span>d</span><span>x</span><span></span><span>=</span><span></span><span>−</span><span><span></span><span><span><span><span><span><span></span><span><span>a</span></span></span><span><span></span><span></span></span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>cos</span><span></span><span>a</span><span>x</span><span></span><span>+</span><span></span><span>C</span><span> </span><span>(</span><span>a</span><span></span><span><span><span><span><span><span></span><span><span><span></span></span></span><span></span></span></span></span></span><span></span><span>=</span></span><span></span><span>0</span><span>)</span><span></span><span></span><span>∫</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span><span><span><span><span></span><span><span>1</span><span></span><span>−</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>x</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span><span>arcsin</span><span></span><span>x</span><span></span><span>+</span><span></span><span>C</span><span></span><span>=</span><span></span><span>−</span><span></span><span>arccos</span><span></span><span>x</span><span></span><span>+</span><span></span><span><span>C</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span></span><span>∫</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>1</span><span></span><span>+</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>x</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span><span>arctan</span><span></span><span>x</span><span></span><span>+</span><span></span><span>C</span><span></span><span>=</span><span></span><span>−</span><span><span></span><span>arccot</span><span></span></span><span>x</span><span></span><span>+</span><span></span><span><span>C</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span></span></span></span></span></p></section>
<section><h2>第二章 一阶微分方程的初等解法<a href="#第二章-一阶微分方程的初等解法"><span>#</span></a></h2><section><h3>2.1 变量分离方程与变量变换<a href="#21-变量分离方程与变量变换"><span>#</span></a></h3><ol>
<li>
<p>可以直接<strong>变量分离</strong>的 <span><span>dydx=f(x)g(y)\displaystyle\frac{dy}{dx}=f(x)g(y)</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>f</span><span>(</span><span>x</span><span>)</span><span>g</span><span>(</span><span>y</span><span>)</span></span></span></span></p>
</li>
<li>
<p><strong>齐次方程</strong> <span><span>dydx=g(yx)\displaystyle\frac{dy}{dx}=g(\frac{y}{x})</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>g</span><span>(</span><span><span></span><span><span><span><span><span><span></span><span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span></span></span></span>，用变量代换将其转变为变量分离方程</p>
</li>
<li>
<p><strong>分式线性方程</strong> <span><span>dydx=a1x+b1y+c1a2x+b2y+c2\displaystyle\frac{dy}{dx}=\frac{a_1x+b_1y+c_1}{a_2x+b_2y+c_2}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>a</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>x</span><span></span><span>+</span><span></span><span><span>b</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>y</span><span></span><span>+</span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>a</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>x</span><span></span><span>+</span><span></span><span><span>b</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>y</span><span></span><span>+</span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></p>
<ul>
<li>
<p>如果 <span><span>a1a2=b1b2=k\displaystyle\frac{a_1}{a_2}=\frac{b_1}{b_2}=k</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>a</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>a</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>b</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>b</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>k</span></span></span></span>，则用变量代换转变为变量分离方程</p>
</li>
<li>
<p>否则先联立求解 <span><span>{a1x+b1y+c1=0a2x+b2y+c2=0\begin{cases}a_1x+b_1y+c_1=0\\a_2x+b_2y+c_2=0\end{cases}</span><span><span><span></span><span><span><span>{</span></span><span><span><span><span><span><span><span><span></span><span><span><span>a</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>x</span><span></span><span>+</span><span></span><span><span>b</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>y</span><span></span><span>+</span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span><span>0</span></span></span><span><span></span><span><span><span>a</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>x</span><span></span><span>+</span><span></span><span><span>b</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>y</span><span></span><span>+</span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span></span></span></span></span></span>，再代换 <span><span>{X=x−αY=y−β\begin{cases}X=x-\alpha\\Y=y-\beta\end{cases}</span><span><span><span></span><span><span><span>{</span></span><span><span><span><span><span><span><span><span></span><span><span>X</span><span></span><span>=</span><span></span><span>x</span><span></span><span>−</span><span></span><span>α</span></span></span><span><span></span><span><span>Y</span><span></span><span>=</span><span></span><span>y</span><span></span><span>−</span><span></span><span>β</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span></span></span></span></span></span>，即可化为齐次方程</p>
</li>
</ul>
</li>
</ol></section><section><h3>2.2 线性方程与常数变易法<a href="#22-线性方程与常数变易法"><span>#</span></a></h3><ol>
<li>
<p><strong>齐次线性方程</strong> <span><span>dydx=P(x)y\displaystyle\frac{dy}{dx}=P(x)y</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span>x</span><span>)</span><span>y</span></span></span></span> 直接变量分离得通解 <span><span>y=ce∫P(x)dx\large{y=ce^{\int{P(x)dx}}}</span><span><span><span></span><span><span>y</span><span></span><span>=</span><span></span><span>c</span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>∫</span><span></span><span><span>P</span><span>(</span><span>x</span><span>)</span><span>d</span><span>x</span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
</li>
<li>
<p><strong>非齐次线性方程</strong> <span><span>dydx=P(x)y+Q(x)\displaystyle\frac{dy}{dx}=P(x)y+Q(x)</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span>x</span><span>)</span><span>y</span><span></span><span>+</span><span></span></span><span><span></span><span>Q</span><span>(</span><span>x</span><span>)</span></span></span></span></p>
<ul>
<li>
<p>先求得齐次解 <span><span>y=ce∫P(x)dx\large{y=ce^{\int{P(x)dx}}}</span><span><span><span></span><span><span>y</span><span></span><span>=</span><span></span><span>c</span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>∫</span><span></span><span><span>P</span><span>(</span><span>x</span><span>)</span><span>d</span><span>x</span></span></span></span></span></span></span></span></span></span></span></span></span></span>，然后假设有形式解 <span><span>y=c(x)e∫P(x)dx\large{y=c(x)e^{\int{P(x)dx}}}</span><span><span><span></span><span><span>y</span><span></span><span>=</span><span></span><span>c</span><span>(</span><span>x</span><span>)</span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>∫</span><span></span><span><span>P</span><span>(</span><span>x</span><span>)</span><span>d</span><span>x</span></span></span></span></span></span></span></span></span></span></span></span></span></span>，并带回原式解出 <span><span>c(x)c(x)</span><span><span><span></span><span>c</span><span>(</span><span>x</span><span>)</span></span></span></span></p>
</li>
<li>
<p>直接通解公式 <span><span>y=e∫P(x)dx(∫Q(x)e−∫P(x)dxdx+c~)\large{y=e^{\int{P(x)dx}}(\int{Q(x)e^{-\int{P(x)dx}}dx+\widetilde{c}})}</span><span><span><span></span><span><span>y</span><span></span><span>=</span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>∫</span><span></span><span><span>P</span><span>(</span><span>x</span><span>)</span><span>d</span><span>x</span></span></span></span></span></span></span></span></span></span><span>(</span><span>∫</span><span></span><span><span>Q</span><span>(</span><span>x</span><span>)</span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>−</span><span></span><span>∫</span><span></span><span><span>P</span><span>(</span><span>x</span><span>)</span><span>d</span><span>x</span></span></span></span></span></span></span></span></span></span><span>d</span><span>x</span><span></span><span>+</span><span></span><span><span><span><span><span><span></span><span>c</span></span><span><span></span><span></span></span></span></span></span></span></span><span>)</span></span></span></span></span></p>
</li>
</ul>
</li>
<li>
<p><strong>伯努利方程</strong> <span><span>dydx=P(x)y+Q(x)yn (n≠0,1)\displaystyle\frac{dy}{dx}=P(x)y+Q(x)y^n\ (n\ne0,1)</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>P</span><span>(</span><span>x</span><span>)</span><span>y</span><span></span><span>+</span><span></span></span><span><span></span><span>Q</span><span>(</span><span>x</span><span>)</span><span><span>y</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span></span></span></span></span><span> </span><span>(</span><span>n</span><span></span><span><span><span><span><span><span></span><span><span><span></span></span></span><span></span></span></span></span></span><span></span><span>=</span></span><span></span></span><span><span></span><span>0</span><span>,</span><span></span><span>1</span><span>)</span></span></span></span></p>
<ul>
<li>将方程各项乘以 <span><span>y−ny^{-n}</span><span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>−</span><span>n</span></span></span></span></span></span></span></span></span></span></span></span>，然后令 <span><span>z=y1−nz=y^{1-n}</span><span><span><span></span><span>z</span><span></span><span>=</span><span></span></span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>1</span><span>−</span><span>n</span></span></span></span></span></span></span></span></span></span></span></span>，则 <span><span>dzdx=(1−n)P(x)z+(1−n)Q(x)\displaystyle\frac{dz}{dx}=(1-n)P(x)z+(1-n)Q(x)</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>z</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>(</span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span>n</span><span>)</span><span>P</span><span>(</span><span>x</span><span>)</span><span>z</span><span></span><span>+</span><span></span></span><span><span></span><span>(</span><span>1</span><span></span><span>−</span><span></span></span><span><span></span><span>n</span><span>)</span><span>Q</span><span>(</span><span>x</span><span>)</span></span></span></span></li>
<li>直接通解公式 <span><span>y1−n=e∫(1−n)P(x)dx(∫(1−n)Q(x)e−∫(1−n)P(x)dxdx+c~)\large{y^{1-n}=e^{\int{(1-n)P(x)dx}}(\int{(1-n)Q(x)e^{-\int{(1-n)P(x)dx}}dx+\widetilde{c}})}</span><span><span><span></span><span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>1</span><span>−</span><span>n</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>∫</span><span></span><span><span>(</span><span>1</span><span>−</span><span>n</span><span>)</span><span>P</span><span>(</span><span>x</span><span>)</span><span>d</span><span>x</span></span></span></span></span></span></span></span></span></span><span>(</span><span>∫</span><span></span><span><span>(</span><span>1</span><span></span><span>−</span><span></span><span>n</span><span>)</span><span>Q</span><span>(</span><span>x</span><span>)</span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>−</span><span></span><span>∫</span><span></span><span><span>(</span><span>1</span><span>−</span><span>n</span><span>)</span><span>P</span><span>(</span><span>x</span><span>)</span><span>d</span><span>x</span></span></span></span></span></span></span></span></span></span><span>d</span><span>x</span><span></span><span>+</span><span></span><span><span><span><span><span><span></span><span>c</span></span><span><span></span><span></span></span></span></span></span></span></span><span>)</span></span></span></span></span></li>
</ul>
</li>
</ol></section><section><h3>2.3 恰当方程与积分因子<a href="#23-恰当方程与积分因子"><span>#</span></a></h3><section><h4>恰当方程<a href="#恰当方程"><span>#</span></a></h4><p>将一阶微分方程写成对称形式 <span><span>M(x,y)dx+N(x,y)dy=0M(x,y)dx+N(x,y)dy=0</span><span><span><span></span><span>M</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span>d</span><span>x</span><span></span><span>+</span><span></span></span><span><span></span><span>N</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span>d</span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span></p><p>如果此时有 <span><span>∂M∂y=∂N∂x\displaystyle\frac{\partial{M}}{\partial{y}}=\frac{\partial{N}}{\partial{x}}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>y</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span><span>M</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>x</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span><span>N</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span>，则该方程为<strong>恰当方程</strong>，并且可以表示为某函数 <span><span>u(x,y)u(x,y)</span><span><span><span></span><span>u</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span></span></span></span> 的全微分 <span><span>M(x,y)dx+N(x,y)dy≡du(x,y)M(x,y)dx+N(x,y)dy \equiv du(x,y)</span><span><span><span></span><span>M</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span>d</span><span>x</span><span></span><span>+</span><span></span></span><span><span></span><span>N</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span>d</span><span>y</span><span></span><span>≡</span><span></span></span><span><span></span><span>d</span><span>u</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span></span></span></span>，通解为 <span><span>u(x,y)=cu(x,y)=c</span><span><span><span></span><span>u</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>c</span></span></span></span></p><p>通解公式 <span><span>u=∫M(x,y)∂x+∫[N(x,y)−∂∂y∫M(x,y)∂x]dy\displaystyle u=\int{M(x,y)\partial{x}}+\int{[N(x,y)-\frac{\partial}{\partial{y}}\int{M(x,y)\partial{x}}]dy}</span><span><span><span></span><span>u</span><span></span><span>=</span><span></span></span><span><span></span><span>∫</span><span></span><span><span>M</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span>∂</span><span><span>x</span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>∫</span><span></span><span><span>[</span><span>N</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span></span><span>−</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>y</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>∫</span><span></span><span><span>M</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span>∂</span><span><span>x</span></span></span><span>]</span><span>d</span><span>y</span></span></span></span></span></p></section><section><h4>积分因子<a href="#积分因子"><span>#</span></a></h4><p>如果存在非零连续可微函数 <span><span>μ(x,y)\mu(x,y)</span><span><span><span></span><span>μ</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span></span></span></span> 使得 <span><span>μ(x,y)M(x,y)dx+μ(x,y)N(x,y)dy=0\mu(x,y)M(x,y)dx+\mu(x,y)N(x,y)dy=0</span><span><span><span></span><span>μ</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span>M</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span>d</span><span>x</span><span></span><span>+</span><span></span></span><span><span></span><span>μ</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span>N</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span>d</span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span> 为恰当方程，则称 <span><span>μ(x,y)\mu(x,y)</span><span><span><span></span><span>μ</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span></span></span></span> 是方程的一个<strong>积分因子</strong>，此时可按照恰当方程来求解</p><ol>
<li><strong>观察法</strong>：利用已知的或熟悉的微分式的原函数求积分因子</li>
<li><strong>公式法</strong>：积分因子必定满足 <span><span>∂(μM)∂y=∂(μN)∂x\displaystyle\frac{\partial(\mu M)}{\partial{y}}=\frac{\partial(\mu N)}{\partial{x}}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>y</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span>(</span><span>μ</span><span>M</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>x</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span>(</span><span>μ</span><span>N</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span>
<ol>
<li>如果积分因子只与 <span><span>xx</span><span><span><span></span><span>x</span></span></span></span> 有关 <span><span>1N(∂M∂y−∂N∂x)=φ(x)\displaystyle\frac{1}{N}(\frac{\partial{M}}{\partial{y}}-\frac{\partial{N}}{\partial{x}})=\varphi(x)</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>N</span></span></span><span><span></span><span></span></span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>(</span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>y</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span><span>M</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>−</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>x</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span><span>N</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>φ</span><span>(</span><span>x</span><span>)</span></span></span></span>，此时 <span><span>μ(x,y)=e∫φ(x)dx\large\mu(x,y)=e^{\int{\varphi(x)dx}}</span><span><span><span></span><span>μ</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>∫</span><span></span><span><span>φ</span><span>(</span><span>x</span><span>)</span><span>d</span><span>x</span></span></span></span></span></span></span></span></span></span></span></span></span></li>
<li>如果积分因子只与 <span><span>yy</span><span><span><span></span><span>y</span></span></span></span> 有关 <span><span>−1M(∂M∂y−∂N∂x)=ψ(y)\displaystyle-\frac{1}{M}(\frac{\partial{M}}{\partial{y}}-\frac{\partial{N}}{\partial{x}})=\psi(y)</span><span><span><span></span><span>−</span><span><span></span><span><span><span><span><span><span></span><span><span>M</span></span></span><span><span></span><span></span></span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>(</span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>y</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span><span>M</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>−</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>x</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span><span>N</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>ψ</span><span>(</span><span>y</span><span>)</span></span></span></span>，此时 <span><span>μ(x,y)=e∫ψ(y)dy\large\mu(x,y)=e^{\int{\psi(y)dy}}</span><span><span><span></span><span>μ</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>∫</span><span></span><span><span>ψ</span><span>(</span><span>y</span><span>)</span><span>d</span><span>y</span></span></span></span></span></span></span></span></span></span></span></span></span></li>
</ol>
</li>
<li><strong>分组组合法</strong></li>
</ol></section></section><section><h3>2.4 一阶隐式微分方程及其参数表示<a href="#24-一阶隐式微分方程及其参数表示"><span>#</span></a></h3><section><h4>能解出 y 或 x 的方程<a href="#能解出-y-或-x-的方程"><span>#</span></a></h4><ol>
<li>
<p><span><span>y=f(x,dydx)\displaystyle y=f(x,\frac{dy}{dx})</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span></span></span></span></p>
<p>令 <span><span>dydx=p\displaystyle\frac{dy}{dx}=p</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>p</span></span></span></span>，则方程可参数化 <span><span>{x=xy′=py=f(x,p)\begin{cases}x=x\\y'=p\\y=f(x,p)\end{cases}</span><span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>⎩</span></span></span><span><span></span><span></span></span><span><span></span><span><span>⎨</span></span></span><span><span></span><span></span></span><span><span></span><span><span>⎧</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span><span><span><span><span></span><span><span>x</span><span></span><span>=</span><span></span><span>x</span></span></span><span><span></span><span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span><span>p</span></span></span><span><span></span><span><span>y</span><span></span><span>=</span><span></span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span>p</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span></span></span></span></span></span></p>
<p>把 <span><span>y=f(x,p)y=f(x,p)</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span>p</span><span>)</span></span></span></span> 代入到 <span><span>dy=pdxdy=pdx</span><span><span><span></span><span>d</span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>p</span><span>d</span><span>x</span></span></span></span>，得 <span><span>∂f∂xdx+∂f∂pdp=pdx\displaystyle\frac{\partial{f}}{\partial{x}}dx+\frac{\partial{f}}{\partial{p}}dp=pdx</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>x</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span><span>f</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>d</span><span>x</span><span></span><span>+</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>p</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span><span>f</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>d</span><span>p</span><span></span><span>=</span><span></span></span><span><span></span><span>p</span><span>d</span><span>x</span></span></span></span>，求解之</p>
<ul>
<li>若得到 <span><span>p=φ(x,c)p=\varphi(x,c)</span><span><span><span></span><span>p</span><span></span><span>=</span><span></span></span><span><span></span><span>φ</span><span>(</span><span>x</span><span>,</span><span></span><span>c</span><span>)</span></span></span></span>，则代回 <span><span>y=f(x,p)y=f(x,p)</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span>p</span><span>)</span></span></span></span> 即得通解</li>
<li>若得到 <span><span>x=ψ(p,c)x=\psi(p,c)</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span>ψ</span><span>(</span><span>p</span><span>,</span><span></span><span>c</span><span>)</span></span></span></span>，则通解 <span><span>{x=ψ(p,c)y=f(ψ(p,c),p)\begin{cases}x=\psi(p,c)\\y=f(\psi(p,c),p)\end{cases}</span><span><span><span></span><span><span><span>{</span></span><span><span><span><span><span><span><span><span></span><span><span>x</span><span></span><span>=</span><span></span><span>ψ</span><span>(</span><span>p</span><span>,</span><span></span><span>c</span><span>)</span></span></span><span><span></span><span><span>y</span><span></span><span>=</span><span></span><span>f</span><span>(</span><span>ψ</span><span>(</span><span>p</span><span>,</span><span></span><span>c</span><span>)</span><span>,</span><span></span><span>p</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span></span></span></span></span></span></li>
<li>若得到 <span><span>ϕ(x,p,c)=0\phi(x,p,c)=0</span><span><span><span></span><span>ϕ</span><span>(</span><span>x</span><span>,</span><span></span><span>p</span><span>,</span><span></span><span>c</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span>，则通解 <span><span>{ϕ(x,p,c)=0y=f(x,p)\begin{cases}\phi(x,p,c)=0\\y=f(x,p)\end{cases}</span><span><span><span></span><span><span><span>{</span></span><span><span><span><span><span><span><span><span></span><span><span>ϕ</span><span>(</span><span>x</span><span>,</span><span></span><span>p</span><span>,</span><span></span><span>c</span><span>)</span><span></span><span>=</span><span></span><span>0</span></span></span><span><span></span><span><span>y</span><span></span><span>=</span><span></span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span>p</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span></span></span></span></span></span></li>
</ul>
</li>
<li>
<p><span><span>x=f(y,dydx)\displaystyle x=f(y,\frac{dy}{dx})</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span>f</span><span>(</span><span>y</span><span>,</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span></span></span></span></p>
<p>令 <span><span>dydx=p\displaystyle\frac{dy}{dx}=p</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>p</span></span></span></span>，然后两边同时对 <span><span>yy</span><span><span><span></span><span>y</span></span></span></span> 求导 <span><span>1p=∂f∂y+∂f∂pdpdy\displaystyle\frac{1}{p}=\frac{\partial{f}}{\partial{y}}+\frac{\partial{f}}{\partial{p}}\frac{dp}{dy}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>p</span></span></span><span><span></span><span></span></span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>y</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span><span>f</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span>p</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span><span><span>f</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>y</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>p</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></p>
<ul>
<li>若得到 <span><span>p=φ(y,c)p=\varphi(y,c)</span><span><span><span></span><span>p</span><span></span><span>=</span><span></span></span><span><span></span><span>φ</span><span>(</span><span>y</span><span>,</span><span></span><span>c</span><span>)</span></span></span></span>，则代回 <span><span>x=f(y,p)x=f(y,p)</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span>f</span><span>(</span><span>y</span><span>,</span><span></span><span>p</span><span>)</span></span></span></span> 即得通解</li>
<li>若得到 <span><span>ϕ(y,p,c)=0\phi(y,p,c)=0</span><span><span><span></span><span>ϕ</span><span>(</span><span>y</span><span>,</span><span></span><span>p</span><span>,</span><span></span><span>c</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span>，则通解 <span><span>{x=f(y,p)ϕ(y,p,c)=0\begin{cases}x=f(y,p)\\\phi(y,p,c)=0\end{cases}</span><span><span><span></span><span><span><span>{</span></span><span><span><span><span><span><span><span><span></span><span><span>x</span><span></span><span>=</span><span></span><span>f</span><span>(</span><span>y</span><span>,</span><span></span><span>p</span><span>)</span></span></span><span><span></span><span><span>ϕ</span><span>(</span><span>y</span><span>,</span><span></span><span>p</span><span>,</span><span></span><span>c</span><span>)</span><span></span><span>=</span><span></span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span></span></span></span></span></span></li>
</ul>
</li>
</ol></section><section><h4>不显含 y 或 x 的方程<a href="#不显含-y-或-x-的方程"><span>#</span></a></h4><ol>
<li>
<p><span><span>F(x,y′)=0F(x,y')=0</span><span><span><span></span><span>F</span><span>(</span><span>x</span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span></p>
<p>引入变换 <span><span>x=φ(t)x=\varphi(t)</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span>φ</span><span>(</span><span>t</span><span>)</span></span></span></span>（或 <span><span>y′=ψ(t)y'=\psi(t)</span><span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>ψ</span><span>(</span><span>t</span><span>)</span></span></span></span>），带入原方程可以得到 <span><span>y′=ψ(t)y'=\psi(t)</span><span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>ψ</span><span>(</span><span>t</span><span>)</span></span></span></span>（或 <span><span>x=φ(t)x=\varphi(t)</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span>φ</span><span>(</span><span>t</span><span>)</span></span></span></span>）</p>
<p><span><span>y′=dydx⇒dy=ψ(t)dx=ψ(t)dφ(t)=ψ(t)φ′(t)dt\displaystyle y'=\frac{dy}{dx}\Rightarrow dy=\psi(t)dx=\psi(t)d\varphi(t)=\psi(t)\varphi'(t)dt</span><span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>⇒</span><span></span></span><span><span></span><span>d</span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>ψ</span><span>(</span><span>t</span><span>)</span><span>d</span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span>ψ</span><span>(</span><span>t</span><span>)</span><span>d</span><span>φ</span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>ψ</span><span>(</span><span>t</span><span>)</span><span><span>φ</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>d</span><span>t</span></span></span></span></p>
<p>积分之，得到通解 <span><span>{x=φ(t)y=∫ψ(t)φ′(t)dt+c\begin{cases}x=\varphi(t)\\y=\int\psi(t)\varphi'(t)dt+c\end{cases}</span><span><span><span></span><span><span><span>{</span></span><span><span><span><span><span><span><span><span></span><span><span>x</span><span></span><span>=</span><span></span><span>φ</span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span><span>y</span><span></span><span>=</span><span></span><span>∫</span><span></span><span>ψ</span><span>(</span><span>t</span><span>)</span><span><span>φ</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>d</span><span>t</span><span></span><span>+</span><span></span><span>c</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span></span></span></span></span></span></p>
</li>
<li>
<p><span><span>F(y,y′)=0F(y,y')=0</span><span><span><span></span><span>F</span><span>(</span><span>y</span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span></p>
<p>引入变换 <span><span>y=φ(t)y=\varphi(t)</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>φ</span><span>(</span><span>t</span><span>)</span></span></span></span>（或 <span><span>y′=ψ(t)y'=\psi(t)</span><span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>ψ</span><span>(</span><span>t</span><span>)</span></span></span></span>），带入原方程可以得到 <span><span>y′=ψ(t)y'=\psi(t)</span><span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>ψ</span><span>(</span><span>t</span><span>)</span></span></span></span>（或 <span><span>y=φ(t)y=\varphi(t)</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>φ</span><span>(</span><span>t</span><span>)</span></span></span></span>）</p>
<p><span><span>y′=dydx⇒dx=dyψ(t)=dφ(t)ψ(t)=φ′(t)ψ(t)dt\displaystyle y'=\frac{dy}{dx}\Rightarrow dx=\frac{dy}{\psi(t)}=\frac{d\varphi(t)}{\psi(t)}=\frac{\varphi'(t)}{\psi(t)}dt</span><span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>⇒</span><span></span></span><span><span></span><span>d</span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>ψ</span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>ψ</span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>φ</span><span>(</span><span>t</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>ψ</span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>φ</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>d</span><span>t</span></span></span></span></p>
<p>积分之，得到通解 <span><span>{x=∫φ′(t)ψ(t)dt+cy=φ(t)\begin{cases}x=\displaystyle\int\frac{\varphi'(t)}{\psi(t)}dt+c\\y=\varphi(t)\end{cases}</span><span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>⎩</span></span></span><span><span></span><span></span></span><span><span></span><span><span>⎨</span></span></span><span><span></span><span></span></span><span><span></span><span><span>⎧</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span><span><span><span><span></span><span><span>x</span><span></span><span>=</span><span></span><span>∫</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>ψ</span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>φ</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>d</span><span>t</span><span></span><span>+</span><span></span><span>c</span></span></span><span><span></span><span><span>y</span><span></span><span>=</span><span></span><span>φ</span><span>(</span><span>t</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span></span></span></span></span></span></p>
<p>若 <span><span>F(y,0)=0F(y,0)=0</span><span><span><span></span><span>F</span><span>(</span><span>y</span><span>,</span><span></span><span>0</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span> 有实根 <span><span>y=ky=k</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>k</span></span></span></span>，则 <span><span>y=ky=k</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>k</span></span></span></span> 也是方程的解</p>
</li>
</ol></section></section></section>
<section><h2>第三章 一阶微分方程的解的存在定理<a href="#第三章-一阶微分方程的解的存在定理"><span>#</span></a></h2><section><h3>3.1 解的存在唯一性定理与逐步逼近法<a href="#31-解的存在唯一性定理与逐步逼近法"><span>#</span></a></h3><section><h4>利普希茨条件<a href="#利普希茨条件"><span>#</span></a></h4><p>微分方程 <span><span>dydx=f(x,y) ,R:∣x−x0∣≤a ,∣y−y0∣≤b\displaystyle\frac{dy}{dx}=f(x,y)\ ,R:|x-x_0|\le a\ ,|y-y_0|\le b</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span> </span><span>,</span><span></span><span>R</span><span></span><span>:</span><span></span></span><span><span></span><span>∣</span><span>x</span><span></span><span>−</span><span></span></span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>∣</span><span></span><span>≤</span><span></span></span><span><span></span><span>a</span><span> </span><span>,</span><span></span><span>∣</span><span>y</span><span></span><span>−</span><span></span></span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>∣</span><span></span><span>≤</span><span></span></span><span><span></span><span>b</span></span></span></span></p><p>若存在常数 <span><span>L&gt;0L&gt;0</span><span><span><span></span><span>L</span><span></span><span>&gt;</span><span></span></span><span><span></span><span>0</span></span></span></span> 满足 <span><span>∣f(x,y1)−f(x,y2)∣≤L∣y1−y2∣ ,(x,y1) ,(x,y2)∈R|f(x,y_1)-f(x,y_2)|\le L|y_1-y_2|\ ,(x,y_1)\ ,(x,y_2)\in R</span><span><span><span></span><span>∣</span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span></span><span>−</span><span></span></span><span><span></span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span>∣</span><span></span><span>≤</span><span></span></span><span><span></span><span>L</span><span>∣</span><span><span>y</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>−</span><span></span></span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>∣</span><span> </span><span>,</span><span></span><span>(</span><span>x</span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span> </span><span>,</span><span></span><span>(</span><span>x</span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span></span><span>∈</span><span></span></span><span><span></span><span>R</span></span></span></span></p><p>则称 <span><span>f(x,y)f(x,y)</span><span><span><span></span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span></span></span></span> 在 <span><span>RR</span><span><span><span></span><span>R</span></span></span></span> 上关于 <span><span>yy</span><span><span><span></span><span>y</span></span></span></span> 满足利普希茨条件，<span><span>LL</span><span><span><span></span><span>L</span></span></span></span> 称为<strong>利普希茨常数</strong></p></section><section><h4>存在唯一性定理 1<a href="#存在唯一性定理-1"><span>#</span></a></h4><p>若 <span><span>f(x,y)f(x,y)</span><span><span><span></span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span></span></span></span> 在 <span><span>RR</span><span><span><span></span><span>R</span></span></span></span> 上连续且关于 <span><span>yy</span><span><span><span></span><span>y</span></span></span></span> 满足利普希茨条件</p><p>则方程 <span><span>dydx=f(x,y)\displaystyle\frac{dy}{dx}=f(x,y)</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>x</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span></span></span></span> 在区间 <span><span>∣x−x0∣≤h|x-x_0|\le h</span><span><span><span></span><span>∣</span><span>x</span><span></span><span>−</span><span></span></span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>∣</span><span></span><span>≤</span><span></span></span><span><span></span><span>h</span></span></span></span> 上存在唯一解 <span><span>y=φ(x) ,φ(x0)=y0y=\varphi(x)\ ,\varphi(x_0)=y_0</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>φ</span><span>(</span><span>x</span><span>)</span><span> </span><span>,</span><span></span><span>φ</span><span>(</span><span><span>x</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></p><p>其中 <span><span>h=min⁡(a,bM) ,M=max⁡(x,y)∈R∣f(x,y)∣\displaystyle h=\min(a,\frac{b}{M})\ ,M=\max_{(x,y)\in R}|f(x,y)|</span><span><span><span></span><span>h</span><span></span><span>=</span><span></span></span><span><span></span><span>min</span><span>(</span><span>a</span><span>,</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>M</span></span></span><span><span></span><span></span></span><span><span></span><span><span>b</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>)</span><span> </span><span>,</span><span></span><span>M</span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>(</span><span>x</span><span>,</span><span>y</span><span>)</span><span>∈</span><span>R</span></span></span></span><span><span></span><span><span>max</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span>∣</span><span>f</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>)</span><span>∣</span></span></span></span></p></section><section><h4>存在唯一性定理 2<a href="#存在唯一性定理-2"><span>#</span></a></h4><p>若 <span><span>F(x,y,y′)F(x,y,y')</span><span><span><span></span><span>F</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>)</span></span></span></span> 在 <span><span>(x0,y0,y0′)(x_0,y_0,y_0')</span><span><span><span></span><span>(</span><span><span>x</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>0</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span></span></span></span> 的某邻域中对 <span><span>(x,y,y′)(x,y,y')</span><span><span><span></span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>)</span></span></span></span> 连续且存在连续偏导数，同时 <span><span>F(x0,y0,y0′)=0 ,∂∂y′F(x0,y0,y0′)≠0\displaystyle F(x_0,y_0,y_0')=0\ ,\frac{\partial}{\partial{y'}}F(x_0,y_0,y_0')\ne0</span><span><span><span></span><span>F</span><span>(</span><span><span>x</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>0</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span><span> </span><span>,</span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>∂</span><span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>∂</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>F</span><span>(</span><span><span>x</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>0</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span></span><span><span><span><span><span><span></span><span><span><span></span></span></span><span></span></span></span></span></span><span></span><span>=</span></span><span></span></span><span><span></span><span>0</span></span></span></span></p><p>则方程 <span><span>F(x,y,y′)F(x,y,y')</span><span><span><span></span><span>F</span><span>(</span><span>x</span><span>,</span><span></span><span>y</span><span>,</span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>)</span></span></span></span> 存在唯一解 <span><span>y=φ(x) ,φ(x0)=y0 ,φ′(x0)=y0′y=\varphi(x)\ ,\varphi(x_0)=y_0\ ,\varphi'(x_0)=y_0'</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>φ</span><span>(</span><span>x</span><span>)</span><span> </span><span>,</span><span></span><span>φ</span><span>(</span><span><span>x</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span> </span><span>,</span><span></span><span><span>φ</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>(</span><span><span>x</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span>0</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></p></section></section><section><h3>3.2 解的延拓<a href="#32-解的延拓"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2019/01/2510660222.png" alt="1547131382285.png" /><figcaption>1547131382285.png</figcaption></figure><p></p><p></p><figure><img src="/usr/uploads/2019/01/3782947898.png" alt="1547131404598.png" /><figcaption>1547131404598.png</figcaption></figure><p></p></section></section>
<section><h2>第四章 高阶微分方程<a href="#第四章-高阶微分方程"><span>#</span></a></h2><section><h3>4.1 线性微分方程的一般理论<a href="#41-线性微分方程的一般理论"><span>#</span></a></h3><section><h4>基本概念<a href="#基本概念"><span>#</span></a></h4><ol>
<li>
<p><span><span>nn</span><span><span><span></span><span>n</span></span></span></span> 阶线性微分方程</p>
<ul>
<li>（非齐次）<span><span>x(n)+a1(t)x(n−1)+⋯+an−1(t)x′+an(t)x=f(t)x^{(n)}+a_1(t)x^{(n-1)}+\cdots+a_{n-1}(t)x'+a_n(t)x=f(t)</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>−</span><span>1</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span>f</span><span>(</span><span>t</span><span>)</span></span></span></span></li>
<li>（齐次）<span><span>x(n)+a1(t)x(n−1)+⋯+an−1(t)x′+an(t)x=0x^{(n)}+a_1(t)x^{(n-1)}+\cdots+a_{n-1}(t)x'+a_n(t)x=0</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>−</span><span>1</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span></li>
</ul>
</li>
<li>
<p><strong>朗斯基行列式</strong>（函数 <span><span>xi(t) (i=1,⋯ ,k)x_i(t)\ (i=1,\cdots,k)</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>i</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span> </span><span>(</span><span>i</span><span></span><span>=</span><span></span></span><span><span></span><span>1</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span>k</span><span>)</span></span></span></span> 在区间 <span><span>a≤t≤ba\le{t}\le{b}</span><span><span><span></span><span>a</span><span></span><span>≤</span><span></span></span><span><span></span><span><span>t</span></span><span></span><span>≤</span><span></span></span><span><span></span><span><span>b</span></span></span></span></span> 可微 <span><span>k−1k-1</span><span><span><span></span><span>k</span><span></span><span>−</span><span></span></span><span><span></span><span>1</span></span></span></span> 次）</p>
<p><span><span>W(t)=W[x1(t),x2(t),⋯ ,xk(t)]=∣x1(t)x2(t)⋯xk(t)x1′(t)x2′(t)⋯xk′(t)⋮⋮⋮x1(k−1)(t)x2(k−1)(t)⋯xk(k−1)(t)∣W(t)=W[x_1(t),x_2(t),\cdots,x_k(t)]=\left|\begin{array}{cccc}x_1(t)&amp;x_2(t)&amp;\cdots&amp;x_k(t)\\x_1'(t)&amp;x_2'(t)&amp;\cdots&amp;x_k'(t)\\\vdots&amp;\vdots&amp; &amp;\vdots\\x_1^{(k-1)}(t)&amp;x_2^{(k-1)}(t)&amp;\cdots&amp;x_k^{(k-1)}(t)\end{array}\right|</span><span><span><span></span><span>W</span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>W</span><span>[</span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)]</span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span><span><span>⋮</span><span></span></span></span></span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span><span><span></span><span><span><span>(</span><span>k</span><span>−</span><span>1</span><span>)</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span></span><span><span><span><span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span><span><span>⋮</span><span></span></span></span></span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span><span><span>(</span><span>k</span><span>−</span><span>1</span><span>)</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span></span><span><span><span><span><span><span></span><span><span>⋯</span></span></span><span><span></span><span><span>⋯</span></span></span><span><span></span><span></span></span><span><span></span><span><span>⋯</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span></span><span><span><span><span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>k</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span><span><span>⋮</span><span></span></span></span></span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>k</span></span></span><span><span></span><span><span><span>(</span><span>k</span><span>−</span><span>1</span><span>)</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span><span><span><span><span><span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></span></p>
</li>
<li>
<p><strong>线性相关</strong></p>
<p><span><span>c1x1(t)+c2x2(t)+⋯+ckxk(t)≡0c_1x_1(t)+c_2x_2(t)+\cdots+c_kx_k(t)\equiv0</span><span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>≡</span><span></span></span><span><span></span><span>0</span></span></span></span>（<span><span>cic_i</span><span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>i</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 不全为零）</p>
<p>否则称为线性无关</p>
</li>
<li>
<p><strong>基本解组</strong></p>
<p><span><span>nn</span><span><span><span></span><span>n</span></span></span></span> 阶齐次线性方程组的一组 <span><span>nn</span><span><span><span></span><span>n</span></span></span></span> 个线性无关解</p>
</li>
</ol></section><section><h4>齐次线性方程<a href="#齐次线性方程"><span>#</span></a></h4><ol>
<li>
<p>存在唯一性</p>
</li>
<li>
<p><strong>叠加原理</strong>：方程的 <span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 个解的线性组合 <span><span>c1x1(t)+c2x2(t)+⋯+ckxk(t)c_1x_1(t)+c_2x_2(t)+\cdots+c_kx_k(t)</span><span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 也是方程的解</p>
</li>
<li>
<p><strong>定理</strong>：若函数 <span><span>x1(t),x2(t),⋯ ,xn(t)x_1(t),x_2(t),\cdots,x_n(t)</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 在区间 <span><span>a≤t≤ba\le{t}\le{b}</span><span><span><span></span><span>a</span><span></span><span>≤</span><span></span></span><span><span></span><span><span>t</span></span><span></span><span>≤</span><span></span></span><span><span></span><span><span>b</span></span></span></span></span> 上线性相关（或无关），则该区间上他们的<strong>朗斯基行列式</strong>恒等于零（或恒不为零）</p>
</li>
<li>
<p>齐次线性方程的<strong>基本解组</strong>的<strong>朗斯基行列式</strong>恒不为零</p>
</li>
<li>
<p><strong>通解结构</strong></p>
<p>设齐次线性方程有基本解组 <span><span>x1(t),x2(t),⋯ ,xn(t)x_1(t),x_2(t),\cdots,x_n(t)</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span></p>
<p>则通解可表示为 <span><span>x=c1x1(t)+c2x2(t)+⋯+cnxn(t)x=c_1x_1(t)+c_2x_2(t)+\cdots+c_nx_n(t)</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span></p>
</li>
</ol></section><section><h4>非齐次线性方程<a href="#非齐次线性方程"><span>#</span></a></h4><ol>
<li>
<p>存在唯一性</p>
</li>
<li>
<p>若 <span><span>x(t) ,x‾(t)x(t)\ ,\overline{x}(t)</span><span><span><span></span><span>x</span><span>(</span><span>t</span><span>)</span><span> </span><span>,</span><span></span><span><span><span><span><span><span></span><span><span>x</span></span></span><span><span></span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 分别为“非齐次”与“齐次”的解，则 <span><span>x(t)+x‾(t)x(t)+\overline{x}(t)</span><span><span><span></span><span>x</span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>x</span></span></span><span><span></span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 也是“非齐次”的解</p>
<p>若 <span><span>x1(t) ,x2(t)x_1(t)\ ,x_2(t)</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span> </span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 均为“非齐次”的解，则 <span><span>x1(t)−x2(t)x_1(t)-x_2(t)</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>−</span><span></span></span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 是“齐次”的解</p>
</li>
<li>
<p><strong>通解结构</strong></p>
<p>设 <span><span>x1(t),x2(t),⋯ ,xn(t)x_1(t),x_2(t),\cdots,x_n(t)</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 是“齐次”的一个基本解组，<span><span>x‾(t)\overline{x}(t)</span><span><span><span></span><span><span><span><span><span><span></span><span><span>x</span></span></span><span><span></span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 是“非齐次”的一个特解</p>
<p>则通解 <span><span>x=c1x1(t)+c2x2(t)+⋯+cnxn(t)+x‾(t)x=c_1x_1(t)+c_2x_2(t)+\cdots+c_nx_n(t)+\overline{x}(t)</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>x</span></span></span><span><span></span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span></p>
</li>
<li>
<p><strong>常数变易法</strong></p>
<p>已知“齐次”的一个基本解组 <span><span>x1(t),x2(t),⋯ ,xn(t)x_1(t),x_2(t),\cdots,x_n(t)</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 时</p>
<p><span><span>{x1(t)c1′(t)+x2(t)c2′(t)+⋯+xn(t)cn′(t)=0x1′(t)c1′(t)+x2′(t)c2′(t)+⋯+xn′(t)cn′(t)=0⋮x1(n−1)(t)c1′(t)+x2(n−1)(t)c2′(t)+⋯+xn(n−1)(t)cn′(t)=0\begin{cases}x_1(t)c_1'(t)+x_2(t)c_2'(t)+\cdots+x_n(t)c_n'(t)=0\\x_1'(t)c_1'(t)+x_2'(t)c_2'(t)+\cdots+x_n'(t)c_n'(t)=0\\\quad\vdots\\x_1^{(n-1)}(t)c_1'(t)+x_2^{(n-1)}(t)c_2'(t)+\cdots+x_n^{(n-1)}(t)c_n'(t)=0\end{cases}</span><span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>⎩</span></span></span><span><span></span><span></span></span><span><span></span><span><span>⎨</span></span></span><span><span></span><span></span></span><span><span></span><span><span>⎧</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span><span><span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span><span>⋯</span><span></span><span>+</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>c</span><span><span><span><span><span><span></span><span><span>n</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span><span>0</span></span></span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span><span>⋯</span><span></span><span>+</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>c</span><span><span><span><span><span><span></span><span><span>n</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span><span>0</span></span></span><span><span></span><span><span></span><span><span>⋮</span><span></span></span></span></span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span><span><span></span><span><span><span>(</span><span>n</span><span>−</span><span>1</span><span>)</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span><span><span>(</span><span>n</span><span>−</span><span>1</span><span>)</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span><span>⋯</span><span></span><span>+</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span><span><span></span><span><span><span>(</span><span>n</span><span>−</span><span>1</span><span>)</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>c</span><span><span><span><span><span><span></span><span><span>n</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span></span></span></span></span></span></p>
<p>解出所有 <span><span>ci′(t)c_i'(t)</span><span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>i</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 并得到 <span><span>ci(t)c_i(t)</span><span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>i</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 后可得解 <span><span>x=∑i=1nγixi(t)+∑i=1nxi(t)ci(t)\displaystyle x=\sum\limits_{i=1}^n\gamma_ix_i(t)+\sum\limits_{i=1}^nx_i(t)c_i(t)</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>i</span><span>=</span><span>1</span></span></span></span><span><span></span><span><span>∑</span></span></span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span><span>γ</span><span><span><span><span><span><span></span><span><span>i</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>i</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>i</span><span>=</span><span>1</span></span></span></span><span><span></span><span><span>∑</span></span></span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>i</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>c</span><span><span><span><span><span><span></span><span><span>i</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span></p>
</li>
</ol></section></section><section><h3>4.2 常系数线性微分方程<a href="#42-常系数线性微分方程"><span>#</span></a></h3><section><h4>复值函数和复值解<a href="#复值函数和复值解"><span>#</span></a></h4><p>设 <span><span>α,β\alpha,\beta</span><span><span><span></span><span>α</span><span>,</span><span></span><span>β</span></span></span></span> 为实数，<span><span>tt</span><span><span><span></span><span>t</span></span></span></span> 为实变量，则 <span><span>K=α+iβK=\alpha+i\beta</span><span><span><span></span><span>K</span><span></span><span>=</span><span></span></span><span><span></span><span>α</span><span></span><span>+</span><span></span></span><span><span></span><span>i</span><span>β</span></span></span></span> 为复数</p><p>复指数函数定义为 <span><span>eKt=e(α+iβ)t=eαt(cos⁡βt+isin⁡βt)e^{Kt}=e^{(\alpha+i\beta)t}=e^{\alpha t}(\cos\beta t+i\sin\beta t)</span><span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>K</span><span>t</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>(</span><span>α</span><span>+</span><span>i</span><span>β</span><span>)</span><span>t</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>α</span><span>t</span></span></span></span></span></span></span></span></span><span>(</span><span>cos</span><span></span><span>β</span><span>t</span><span></span><span>+</span><span></span></span><span><span></span><span>i</span><span></span><span>sin</span><span></span><span>β</span><span>t</span><span>)</span></span></span></span></p><p><span><span>K‾=α−iβ\overline{K}=\alpha-i\beta</span><span><span><span></span><span><span><span><span><span><span></span><span><span>K</span></span></span><span><span></span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>α</span><span></span><span>−</span><span></span></span><span><span></span><span>i</span><span>β</span></span></span></span> 为 <span><span>KK</span><span><span><span></span><span>K</span></span></span></span> 的共轭复数，有 <span><span>eKt‾=eKt‾e^{\overline{Kt}}=\overline{e^{Kt}}</span><span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>K</span><span>t</span></span></span><span><span></span><span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>K</span><span>t</span></span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span></span></span></span></span></span></span></span></p><p></p><figure><img src="/usr/uploads/2019/01/2851487450.png" alt="1547270678309.png" /><figcaption>1547270678309.png</figcaption></figure><p></p></section><section><h4>常系数齐次线性方程的特征方程<a href="#常系数齐次线性方程的特征方程"><span>#</span></a></h4><p><span><span>L[x]≡x(n)+a1x(n−1)+⋯+an−1x′+anx=0L[x]\equiv x^{(n)}+a_1x^{(n-1)}+\cdots+a_{n-1}x'+a_nx=0</span><span><span><span></span><span>L</span><span>[</span><span>x</span><span>]</span><span></span><span>≡</span><span></span></span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>−</span><span>1</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span> 用 <span><span>x=eλtx=e^{\lambda t}</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>λ</span><span>t</span></span></span></span></span></span></span></span></span></span></span></span> 带入</p><p>可得到特征方程 <span><span>F(λ)≡λn+a1λn−1+⋯+an−1λ+an=0F(\lambda)\equiv\lambda^n+a_1\lambda^{n-1}+\cdots+a_{n-1}\lambda+a_n=0</span><span><span><span></span><span>F</span><span>(</span><span>λ</span><span>)</span><span></span><span>≡</span><span></span></span><span><span></span><span><span>λ</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>λ</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>λ</span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span></p><ol>
<li>
<p><span><span>λ\lambda</span><span><span><span></span><span>λ</span></span></span></span> 为 <span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 重实根时，方程有 <span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 个解 <span><span>tjeλt (j=0,1,2,⋯ ,k−1)t^je^{\lambda t}\ (j=0,1,2,\cdots,k-1)</span><span><span><span></span><span><span>t</span><span><span><span><span><span><span></span><span><span>j</span></span></span></span></span></span></span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>λ</span><span>t</span></span></span></span></span></span></span></span></span><span> </span><span>(</span><span>j</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span><span>,</span><span></span><span>1</span><span>,</span><span></span><span>2</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span>k</span><span></span><span>−</span><span></span></span><span><span></span><span>1</span><span>)</span></span></span></span></p>
<p><span><span>eλt,teλt,t2eλt,⋯ ,tk−1eλte^{\lambda t},te^{\lambda t},t^2e^{\lambda t},\cdots,t^{k-1}e^{\lambda t}</span><span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>λ</span><span>t</span></span></span></span></span></span></span></span></span><span>,</span><span></span><span>t</span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>λ</span><span>t</span></span></span></span></span></span></span></span></span><span>,</span><span></span><span><span>t</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>λ</span><span>t</span></span></span></span></span></span></span></span></span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>t</span><span><span><span><span><span><span></span><span><span><span>k</span><span>−</span><span>1</span></span></span></span></span></span></span></span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>λ</span><span>t</span></span></span></span></span></span></span></span></span></span></span></span></p>
</li>
<li>
<p><span><span>λ=α±iβ\lambda=\alpha\pm i\beta</span><span><span><span></span><span>λ</span><span></span><span>=</span><span></span></span><span><span></span><span>α</span><span></span><span>±</span><span></span></span><span><span></span><span>i</span><span>β</span></span></span></span> 为 <span><span>k/2k/2</span><span><span><span></span><span>k</span><span>/2</span></span></span></span> 重共轭复根时，方程有 <span><span>k/2k/2</span><span><span><span></span><span>k</span><span>/2</span></span></span></span> 对共轭复值解，也就是一共 <span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 个复值解</p>
<p>每对为 <span><span>tjeαtcos⁡βt,tjeαtsin⁡βt (j=0,1,2,⋯ ,k/2−1)t^je^{\alpha t}\cos\beta t,t^je^{\alpha t}\sin\beta t\ (j=0,1,2,\cdots,k/2-1)</span><span><span><span></span><span><span>t</span><span><span><span><span><span><span></span><span><span>j</span></span></span></span></span></span></span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>α</span><span>t</span></span></span></span></span></span></span></span></span><span></span><span>cos</span><span></span><span>β</span><span>t</span><span>,</span><span></span><span><span>t</span><span><span><span><span><span><span></span><span><span>j</span></span></span></span></span></span></span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>α</span><span>t</span></span></span></span></span></span></span></span></span><span></span><span>sin</span><span></span><span>β</span><span>t</span><span> </span><span>(</span><span>j</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span><span>,</span><span></span><span>1</span><span>,</span><span></span><span>2</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span>k</span><span>/2</span><span></span><span>−</span><span></span></span><span><span></span><span>1</span><span>)</span></span></span></span></p>
</li>
</ol><p>得到基本解组 <span><span>x1,x2,⋯ ,xkx_1,x_2,\cdots,x_k</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 后，可写出通解 <span><span>x(t)=c1x1+c2x2+⋯+ckxkx(t)=c_1x_1+c_2x_2+\cdots+c_kx_k</span><span><span><span></span><span>x</span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></p></section><section><h4>欧拉方程<a href="#欧拉方程"><span>#</span></a></h4><p>对于欧拉方程 <span><span>xny(n)+a1xn−1y(n−1)+⋯+an−1xy′+any=0x^ny^{(n)}+a_1x^{n-1}y^{(n-1)}+\cdots+a_{n-1}xy'+a_ny=0</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span></span></span></span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span></span></span></span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>−</span><span>1</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>x</span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span></p><p><strong>核心思想</strong>：引进自变量变换 <span><span>x=etx=e^t</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span><span>e</span><span><span><span><span><span><span></span><span><span>t</span></span></span></span></span></span></span></span></span></span></span> 或 <span><span>t=ln⁡∣x∣t=\ln|x|</span><span><span><span></span><span>t</span><span></span><span>=</span><span></span></span><span><span></span><span>ln</span><span></span><span>∣</span><span>x</span><span>∣</span></span></span></span> 可化为常系数齐次线性微分方程 <span><span>y(n)+b1y(n−1)+⋯+bn−1y′+bny=0y^{(n)}+b_1y^{(n-1)}+\cdots+b_{n-1}y'+b_ny=0</span><span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>b</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>−</span><span>1</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>b</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>b</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span></p><p><strong>解法</strong>：</p><ol>
<li>
<p>求特征方程 <span><span>F(k)F(k)</span><span><span><span></span><span>F</span><span>(</span><span>k</span><span>)</span></span></span></span> 的特征根</p>
<p><span><span>F(k)=k(k−1)⋯(k−n+1)+a1k(k−1)⋯(k−n+2)+⋯+an−1k+anF(k)=k(k-1)\cdots(k-n+1)+a_1k(k-1)\cdots(k-n+2)+\cdots+a_{n-1}k+a_n</span><span><span><span></span><span>F</span><span>(</span><span>k</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>k</span><span>(</span><span>k</span><span></span><span>−</span><span></span></span><span><span></span><span>1</span><span>)</span><span></span><span>⋯</span><span></span><span>(</span><span>k</span><span></span><span>−</span><span></span></span><span><span></span><span>n</span><span></span><span>+</span><span></span></span><span><span></span><span>1</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>k</span><span>(</span><span>k</span><span></span><span>−</span><span></span></span><span><span></span><span>1</span><span>)</span><span></span><span>⋯</span><span></span><span>(</span><span>k</span><span></span><span>−</span><span></span></span><span><span></span><span>n</span><span></span><span>+</span><span></span></span><span><span></span><span>2</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>k</span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></p>
</li>
<li>
<p>得到基本解组，然后使用 <span><span>t=ln⁡∣x∣t=\ln|x|</span><span><span><span></span><span>t</span><span></span><span>=</span><span></span></span><span><span></span><span>ln</span><span></span><span>∣</span><span>x</span><span>∣</span></span></span></span> 变换得到原方程的基本解组</p>
</li>
<li>
<p>得到原方程通解</p>
</li>
</ol></section><section><h4>常系数非齐次线性方程的比较系数法<a href="#常系数非齐次线性方程的比较系数法"><span>#</span></a></h4><p></p><figure><img src="/usr/uploads/2019/01/2484492918.png" alt="1547278161194.png" /><figcaption>1547278161194.png</figcaption></figure><p></p><p></p><figure><img src="/usr/uploads/2019/01/1627044198.png" alt="1547278172896.png" /><figcaption>1547278172896.png</figcaption></figure><p></p></section></section><section><h3>4.3 高阶方程降阶法<a href="#43-高阶方程降阶法"><span>#</span></a></h3><section><h4>可降阶<a href="#可降阶"><span>#</span></a></h4><ol>
<li>
<p>方程不含未知函数 <span><span>xx</span><span><span><span></span><span>x</span></span></span></span>，形如 <span><span>F(t,x(k),x(k+1),⋯ ,x(n))=0 (1≤k≤n)F(t,x^{(k)},x^{(k+1)},\cdots,x^{(n)})=0\ (1\le k\le n)</span><span><span><span></span><span>F</span><span>(</span><span>t</span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>k</span><span>)</span></span></span></span></span></span></span></span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>k</span><span>+</span><span>1</span><span>)</span></span></span></span></span></span></span></span></span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>)</span></span></span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span><span> </span><span>(</span><span>1</span><span></span><span>≤</span><span></span></span><span><span></span><span>k</span><span></span><span>≤</span><span></span></span><span><span></span><span>n</span><span>)</span></span></span></span>，则令 <span><span>y=x(k)y=x^{(k)}</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>k</span><span>)</span></span></span></span></span></span></span></span></span></span></span></span>，可降 <span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 阶</p>
<p>求得降阶后方程的通解后，逐次积分 <span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 次即可得到原方程通解</p>
</li>
<li>
<p>方程不含自变量 <span><span>tt</span><span><span><span></span><span>t</span></span></span></span>，形如 <span><span>F(x,x′,⋯ ,x(n))=0F(x,x',\cdots,x^{(n)})=0</span><span><span><span></span><span>F</span><span>(</span><span>x</span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>)</span></span></span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span>，令 <span><span>y=x′y=x'</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span></span></span></span>，可降低1阶</p>
<p><span><span>x(n)=yn−1dn−1ydxn−1\displaystyle x^{(n)}=y^{n-1}\frac{d^{n-1}y}{dx^{n-1}}</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span>y</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span></span></span></span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>d</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span></span></span></span></span><span>y</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span> 全部带入原方程，分离变量，可得原方程解</p>
</li>
<li>
<p>齐次线性方程已知 <span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 个线性无关的非零特解 <span><span>x1,x2,⋯ ,xkx_1,x_2,\cdots,x_k</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span>，可降低 <span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 阶</p>
<ul>
<li>
<p>特别地，对于二阶齐次线性方程 <span><span>x′′+p(t)x′+q(t)x=0x''+p(t)x'+q(t)x=0</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>′′</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>p</span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>q</span><span>(</span><span>t</span><span>)</span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span>0</span></span></span></span>，已知非零特解 <span><span>x1x_1</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></p>
<p>通解为 <span><span>x=x1[c1+c2∫1x12e−∫p(t)dtdt]\displaystyle x=x_1[c_1+c_2\int{\frac{1}{x_1^2}e^{-\int{p(t)}dt}}dt]</span><span><span><span></span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>[</span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>∫</span><span></span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>−</span><span></span><span>∫</span><span></span><span><span>p</span><span>(</span><span>t</span><span>)</span></span><span>d</span><span>t</span></span></span></span></span></span></span></span></span></span><span>d</span><span>t</span><span>]</span></span></span></span></p>
</li>
</ul>
</li>
</ol></section><section><h4>二阶线性方程的幂级数解（求特解）<a href="#二阶线性方程的幂级数解求特解"><span>#</span></a></h4><p>看不懂，这分我不要了（</p></section></section></section>
<section><h2>第五章 线性微分方程组<a href="#第五章-线性微分方程组"><span>#</span></a></h2><section><h3>5.1 存在唯一性定理<a href="#51-存在唯一性定理"><span>#</span></a></h3><p><span><span>{x1′=a11(t)x1+a12(t)x2+⋯+a1n(t)xn+f1(t)x2′=a21(t)x1+a22(t)x2+⋯+a2n(t)xn+f2(t)⋮xn′=an1(t)x1+an2(t)x2+⋯+ann(t)xn+fn(t)\begin{cases}x_1'=a_{11}(t)x_1+a_{12}(t)x_2+\cdots+a_{1n}(t)x_n+f_1(t)\\x_2'=a_{21}(t)x_1+a_{22}(t)x_2+\cdots+a_{2n}(t)x_n+f_2(t)\\\quad\vdots\\x_n'=a_{n1}(t)x_1+a_{n2}(t)x_2+\cdots+a_{nn}(t)x_n+f_n(t)\end{cases}</span><span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>⎩</span></span></span><span><span></span><span></span></span><span><span></span><span><span>⎨</span></span></span><span><span></span><span></span></span><span><span></span><span><span>⎧</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span><span><span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>11</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>12</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span><span>⋯</span><span></span><span>+</span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>1</span><span>n</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span><span><span>f</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>21</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>22</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span><span>⋯</span><span></span><span>+</span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>2</span><span>n</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span><span><span>f</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span><span><span></span><span><span></span><span><span>⋮</span><span></span></span></span></span><span><span></span><span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span><span><span></span><span><span><span>′</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>=</span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>n</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>n</span><span>2</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span><span>⋯</span><span></span><span>+</span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>nn</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span></span><span>+</span><span></span><span><span>f</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span><span></span></span></span></span></span></p><p><span><span>nn</span><span><span><span></span><span>n</span></span></span></span> 阶线性微分方程组：<span><span>x′=A(t)x+f(t)\boldsymbol{x}'=\boldsymbol{A}(t)\boldsymbol{x}+\boldsymbol{f}(t)</span><span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>A</span></span></span><span>(</span><span>t</span><span>)</span><span><span><span>x</span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span><span>f</span></span></span><span>(</span><span>t</span><span>)</span></span></span></span></p><p><span><span>x=(x1,x2,⋯ ,xn)T ,A(t)=[aij(t)] ,f(t)=(f1(t),f2(t),⋯ ,fn(t))T\boldsymbol{x}=(x_1,x_2,\cdots,x_n)^T\ ,\boldsymbol{A}(t)=[a_{ij}(t)]\ ,\boldsymbol{f}(t)=(f_1(t),f_2(t),\cdots,f_n(t))^T</span><span><span><span></span><span><span><span>x</span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>(</span><span><span>x</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>)</span><span><span><span><span><span><span></span><span><span>T</span></span></span></span></span></span></span></span><span> </span><span>,</span><span></span><span><span><span>A</span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>[</span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>ij</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)]</span><span> </span><span>,</span><span></span><span><span><span>f</span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>(</span><span><span>f</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span><span>f</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>f</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>)</span><span><span><span><span><span><span></span><span><span>T</span></span></span></span></span></span></span></span></span></span></span></p><p>初值问题：<span><span>x(t0)=η\boldsymbol{x}(t_0)=\boldsymbol{\eta}</span><span><span><span></span><span><span><span>x</span></span></span><span>(</span><span><span>t</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>η</span></span></span></span></span></span></p><p><span><span>x(n)+a1(t)x(n−1)+⋯+an−1x′+an(t)x=f(t)x^{(n)}+a_1(t)x^{(n-1)}+\cdots+a_{n-1}x'+a_n(t)x=f(t)</span><span><span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>−</span><span>1</span><span>)</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span><span>n</span><span>−</span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span>a</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>x</span><span></span><span>=</span><span></span></span><span><span></span><span>f</span><span>(</span><span>t</span><span>)</span></span></span></span></p><p><span><span>x(t0)=η1,x′(t0)=η2,⋯ ,x(n−1)(t0)=ηnx(t_0)=\eta_1,x'(t_0)=\eta_2,\cdots,x^{(n-1)}(t_0)=\eta_n</span><span><span><span></span><span>x</span><span>(</span><span><span>t</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span>η</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span>(</span><span><span>t</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span>η</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>x</span><span><span><span><span><span><span></span><span><span><span>(</span><span>n</span><span>−</span><span>1</span><span>)</span></span></span></span></span></span></span></span></span><span>(</span><span><span>t</span><span><span><span><span><span><span></span><span><span>0</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span>η</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span></p></section><section><h3>5.2 一般理论<a href="#52-一般理论"><span>#</span></a></h3><section><h4>基本概念<a href="#基本概念-1"><span>#</span></a></h4><p><span><span>dxdt=x′=A(t)x+f(t)\displaystyle\frac{d\boldsymbol{x}}{dt}=\boldsymbol{x}'=\boldsymbol{A}(t)\boldsymbol{x}+\boldsymbol{f}(t)</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span>d</span><span>t</span></span></span><span><span></span><span></span></span><span><span></span><span><span>d</span><span><span><span>x</span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>A</span></span></span><span>(</span><span>t</span><span>)</span><span><span><span>x</span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span><span>f</span></span></span><span>(</span><span>t</span><span>)</span></span></span></span></p><ol>
<li>
<p>如果 <span><span>f(t)≠0\boldsymbol{f}(t)\ne0</span><span><span><span></span><span><span><span>f</span></span></span><span>(</span><span>t</span><span>)</span><span></span><span><span><span><span><span><span></span><span><span><span></span></span></span><span></span></span></span></span></span><span></span><span>=</span></span><span></span></span><span><span></span><span>0</span></span></span></span> 则为<strong>非齐次线性</strong>的，<span><span>f(t)≡0\boldsymbol{f}(t)\equiv0</span><span><span><span></span><span><span><span>f</span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>≡</span><span></span></span><span><span></span><span>0</span></span></span></span> 则为<strong>齐次线性</strong>的</p>
<p>若 <span><span>A(t)\boldsymbol{A}(t)</span><span><span><span></span><span><span><span>A</span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 为常数矩阵，则称为<strong>常系数线性方程组</strong></p>
<p><span><span>x′=A(t)x ⇒ x′=Ax\boldsymbol{x}'=\boldsymbol{A}(t)\boldsymbol{x}\ \Rightarrow\ \boldsymbol{x}'=\boldsymbol{A}\boldsymbol{x}</span><span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>A</span></span></span><span>(</span><span>t</span><span>)</span><span><span><span>x</span></span></span><span> </span><span></span><span>⇒</span><span> </span><span></span></span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>A</span></span></span><span><span><span>x</span></span></span></span></span></span></p>
</li>
<li>
<p><strong>线性相关</strong></p>
<p><span><span>c1x1(t)+c2x2(t)+⋯+cmxm(t)≡0c_1\boldsymbol x_1(t)+c_2\boldsymbol x_2(t)+\cdots+c_m\boldsymbol x_m(t)\equiv0</span><span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>m</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>m</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>≡</span><span></span></span><span><span></span><span>0</span></span></span></span>（<span><span>cmc_m</span><span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>m</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 不全为零）</p>
<p>否则它们（向量函数）线性无关</p>
</li>
<li>
<p><strong>基本解组</strong></p>
<p><span><span>nn</span><span><span><span></span><span>n</span></span></span></span> 维一阶齐次线性方程组的一组 <span><span>nn</span><span><span><span></span><span>n</span></span></span></span> 个线性无关解 <span><span>x1(t),x2(t),⋯ ,xn(t)\boldsymbol x_1(t),\boldsymbol x_2(t),\cdots,\boldsymbol x_n(t)</span><span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 组成的矩阵 <span><span>ϕ(t)\boldsymbol\phi(t)</span><span><span><span></span><span><span><span>ϕ</span></span></span><span>(</span><span>t</span><span>)</span></span></span></span></p>
<p>当 <span><span>ϕ(0)=E\boldsymbol\phi(0)=\boldsymbol E</span><span><span><span></span><span><span><span>ϕ</span></span></span><span>(</span><span>0</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>E</span></span></span></span></span></span>（单位矩阵）时称基本解组为标准的</p>
</li>
</ol></section><section><h4>齐次线性方程组<a href="#齐次线性方程组"><span>#</span></a></h4><p><span><span>x′=A(t)x\boldsymbol{x}'=\boldsymbol{A}(t)\boldsymbol{x}</span><span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span><span>′</span></span></span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>A</span></span></span><span>(</span><span>t</span><span>)</span><span><span><span>x</span></span></span></span></span></span></p><ol>
<li>
<p>存在唯一性</p>
</li>
<li>
<p><strong>叠加原理</strong></p>
<p>方程组的 <span><span>kk</span><span><span><span></span><span>k</span></span></span></span> 个解 <span><span>x1(t),x2(t),⋯ ,xk(t)\boldsymbol x_1(t),\boldsymbol x_2(t),\cdots,\boldsymbol x_k(t)</span><span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 的线性组合 <span><span>c1x1(t)+c2x2(t)+⋯+ckxk(t)c_1\boldsymbol x_1(t)+c_2\boldsymbol x_2(t)+\cdots+c_k\boldsymbol x_k(t)</span><span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>k</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 也是方程的解，其中 <span><span>cic_i</span><span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>i</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span></span> 为任意常数</p>
</li>
<li>
<p>如果向量函数 <span><span>x1(t),x2(t),⋯ ,xn(t)\boldsymbol x_1(t),\boldsymbol x_2(t),\cdots,\boldsymbol x_n(t)</span><span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 在某区间上线性相关（或无关），则他们的<strong>朗斯基行列式</strong>恒为零（或恒不为零）</p>
<p>齐次线性方程组的基本解组的朗斯基行列式恒不为零</p>
</li>
<li>
<p><strong>通解结构</strong></p>
<p>设 <span><span>ϕ(t)\boldsymbol\phi(t)</span><span><span><span></span><span><span><span>ϕ</span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 是齐次线性方程组的一个基本解组，则通解可以表示为</p>
<p><span><span>x=ϕ(t)c≡c1x1(t)+c2x2(t)+⋯+cnxn(t)\boldsymbol{x}=\boldsymbol{\phi}(t)\boldsymbol{c}\equiv c_1\boldsymbol x_1(t)+c_2\boldsymbol x_2(t)+\cdots+c_n\boldsymbol x_n(t)</span><span><span><span></span><span><span><span>x</span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>ϕ</span></span></span><span>(</span><span>t</span><span>)</span><span><span><span>c</span></span></span><span></span><span>≡</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>⋯</span><span></span><span>+</span><span></span></span><span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span></p>
<p>其中 <span><span>c=(c1,c2,⋯ ,cn)T\boldsymbol{c}=(c_1,c_2,\cdots,c_n)^T</span><span><span><span></span><span><span><span>c</span></span></span><span></span><span>=</span><span></span></span><span><span></span><span>(</span><span><span>c</span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span>c</span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span><span>)</span><span><span><span><span><span><span></span><span><span>T</span></span></span></span></span></span></span></span></span></span></span> 为任意常向量</p>
</li>
<li>
<p>齐次线性方程组的 <span><span>nn</span><span><span><span></span><span>n</span></span></span></span> 个解 <span><span>x1(t),x2(t),⋯ ,xn(t)\boldsymbol x_1(t),\boldsymbol x_2(t),\cdots,\boldsymbol x_n(t)</span><span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span>⋯</span><span></span><span></span><span>,</span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>n</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 组成基本解组 <span><span>ϕ(t)\boldsymbol\phi(t)</span><span><span><span></span><span><span><span>ϕ</span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 的充要条件为 <span><span>det⁡ϕ(t)≠0\det\boldsymbol\phi(t)\ne0</span><span><span><span></span><span>det</span><span></span><span><span><span>ϕ</span></span></span><span>(</span><span>t</span><span>)</span><span></span><span><span><span><span><span><span></span><span><span><span></span></span></span><span></span></span></span></span></span><span></span><span>=</span></span><span></span></span><span><span></span><span>0</span></span></span></span></p>
<p>齐次线性方程组的两个基本解组 <span><span>ϕ(t),ψ(t)\boldsymbol\phi(t),\boldsymbol\psi(t)</span><span><span><span></span><span><span><span>ϕ</span></span></span><span>(</span><span>t</span><span>)</span><span>,</span><span></span><span><span><span>ψ</span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 必有关系</p>
<p><span><span>ϕ(t)=ψ(t)C (a≤t≤b) ,det⁡C≠0\boldsymbol\phi(t)=\boldsymbol\psi(t)\boldsymbol C\ (a\le t\le b)\ ,\det\boldsymbol C\ne0</span><span><span><span></span><span><span><span>ϕ</span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>ψ</span></span></span><span>(</span><span>t</span><span>)</span><span><span><span>C</span></span></span><span> </span><span>(</span><span>a</span><span></span><span>≤</span><span></span></span><span><span></span><span>t</span><span></span><span>≤</span><span></span></span><span><span></span><span>b</span><span>)</span><span> </span><span>,</span><span></span><span>det</span><span></span><span><span><span>C</span></span></span><span></span><span><span><span><span><span><span></span><span><span><span></span></span></span><span></span></span></span></span></span><span></span><span>=</span></span><span></span></span><span><span></span><span>0</span></span></span></span></p>
</li>
</ol></section><section><h4>非齐次线性方程组<a href="#非齐次线性方程组"><span>#</span></a></h4><ol>
<li>
<p>存在唯一性</p>
</li>
<li>
<p>若 <span><span>x(t) ,x~(t)\boldsymbol x(t)\ ,\widetilde{\boldsymbol x}(t)</span><span><span><span></span><span><span><span>x</span></span></span><span>(</span><span>t</span><span>)</span><span> </span><span>,</span><span></span><span><span><span><span><span><span></span><span><span><span>x</span></span></span></span><span><span></span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 分别为“非齐次”与“齐次”的解，则 <span><span>x(t)+x~(t)\boldsymbol x(t)+\widetilde{\boldsymbol x}(t)</span><span><span><span></span><span><span><span>x</span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>x</span></span></span></span><span><span></span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 也是“非齐次”的解</p>
<p>若 <span><span>x1(t) ,x2(t)\boldsymbol x_1(t)\ ,\boldsymbol x_2(t)</span><span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span> </span><span>,</span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 均为“非齐次”的解，则 <span><span>x1(t)−x2(t)\boldsymbol x_1(t)-\boldsymbol x_2(t)</span><span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>1</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span><span></span><span>−</span><span></span></span><span><span></span><span><span><span><span>x</span></span></span><span><span><span><span><span><span></span><span><span>2</span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 是“齐次”的解</p>
</li>
<li>
<p><strong>通解结构</strong></p>
<p>设 <span><span>ϕ(t)\boldsymbol{\phi}(t)</span><span><span><span></span><span><span><span>ϕ</span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 是“齐次”的一个基本解组，<span><span>x~(t)\widetilde{\boldsymbol x}(t)</span><span><span><span></span><span><span><span><span><span><span></span><span><span><span>x</span></span></span></span><span><span></span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 是“非齐次”的某一特解，则通解可表示为</p>
<p><span><span>x=ϕ(t)c+x~(t)\boldsymbol{x}=\boldsymbol{\phi}(t)\boldsymbol{c}+\widetilde{\boldsymbol x}(t)</span><span><span><span></span><span><span><span>x</span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>ϕ</span></span></span><span>(</span><span>t</span><span>)</span><span><span><span>c</span></span></span><span></span><span>+</span><span></span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>x</span></span></span></span><span><span></span><span></span></span></span></span></span></span><span>(</span><span>t</span><span>)</span></span></span></span> 其中 <span><span>c\boldsymbol{c}</span><span><span><span></span><span><span><span>c</span></span></span></span></span></span> 为任意 <span><span>nn</span><span><span><span></span><span>n</span></span></span></span> 维向量</p>
</li>
<li>
<p>常数变易法</p>
</li>
</ol></section></section><section><h3>5.3 常系数线性微分方程组<a href="#53-常系数线性微分方程组"><span>#</span></a></h3><p>看不懂，这分我不要了 QAQ</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/zerotier-ipv6/</id>
      <title type="text">[ZeroTier] 组建虚拟局域网，建立 IPv6 隧道</title>
      <published>2018-12-29T09:37:09.000Z</published>
      <updated>2018-12-29T09:37:09.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/zerotier-ipv6/"/>
      <summary type="text">近日受夜空推荐发现了 ZeroTier 这个可以组建虚拟局域网的工具，由于利用的是类似 P2P 的原理因此可以用来进行内网穿透，在家中无公网 IP 的情况下建立 IPv6 隧道</summary>
      <content type="html"><![CDATA[<p>近日受夜空推荐发现了 ZeroTier 这个可以组建虚拟局域网的工具，由于利用的是类似 P2P 的原理因此可以用来进行内网穿透，在家中无公网 IP 的情况下建立 IPv6 隧道</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=72338743" target="_blank">「WS.QE Xmas.ver★」/「ねめ猫⑥」のイラスト [pixiv]</a></p>
<hr />
<p>首先，你需要一台 VPS，并注册一个 ZeroTier 帐号：<a href="https://my.zerotier.com" target="_blank">https://my.zerotier.com</a></p>
<section><h2>VPS 上的准备工作<a href="#vps-上的准备工作"><span>#</span></a></h2><section><h3>系统配置<a href="#系统配置"><span>#</span></a></h3><p>编辑<code>/etc/sysctl.conf</code>，加入</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>net.ipv4.conf.all.forwarding = 1</span></div></div><div><div><div>2</div></div><div><span>net.ipv6.conf.all.disable_ipv6 = 0</span></div></div><div><div><div>3</div></div><div><span>net.ipv6.conf.default.disable_ipv6 = 0</span></div></div><div><div><div>4</div></div><div><span>net.ipv6.conf.lo.disable_ipv6 = 0</span></div></div><div><div><div>5</div></div><div><span>net.ipv6.conf.default.forwarding = 1</span></div></div><div><div><div>6</div></div><div><span>net.ipv6.conf.all.forwarding = 1</span></div></div><div><div><div>7</div></div><div><span>net.ipv6.conf.all.proxy_ndp = 1</span></div></div><div><div><div>8</div></div><div><span>net.ipv6.conf.all.accept_ra = 2</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后执行<code>sysctl -p</code>更新系统配置</p></section><section><h3>IPv6 环境<a href="#ipv6-环境"><span>#</span></a></h3><p>机器需要有<code>/48</code>的地址块，否则后续无法成功打通隧道（我也并不是很明白具体缘由）</p><p>最简单的方法是将 VPS 接入 HE 的 IPv6 Tunnel Broker
<a href="https://tunnelbroker.net/" target="_blank">https://tunnelbroker.net/</a></p><p>注册帐号后点击左侧“User Functions”中的“Create Regular Tunnel”，在“IPv4 Endpoint”中填入你 VPS 的 IP 地址，“Available Tunnel Servers”是自行选择一个隧道入口，就近选择即可，然后点最下方”Create Tunnel“，耐心等待</p><p>创建成功后你会来到隧道详情页面，你会看到”Routed /48“右侧有个”Assign /48“，点一下，申请<code>/48</code>地址块，<strong>并记录下这个地址块①</strong></p><p>接着点击上方”Example Configurations“，选择你 VPS 的系统</p><ul>
<li>如果是 Debian 或者 Ubuntu 就直接将展示的配置内容追加到<code>/etc/network/interfaces</code>文件中，然后执行<code>/etc/init.d/networking restart</code>重载网络配置</li>
<li>如果是 CentOS，选择”Linux-route2“，直接执行配置中的命令，不过需要注意的是执行命令所建立的隧道是临时的，你可能需要把这些命令也添加到<code>/etc/rc.local</code>中</li>
</ul><p>之后执行<code>ifconfig</code>或者<code>ip addr</code>，此时你应该可以看到多了一个叫 he-ipv6 的 interface，尝试<code>ping6 google.com</code>可以确认是否成功接入HE的v6隧道</p></section><section><h3>安装 ZeroTier<a href="#安装-zerotier"><span>#</span></a></h3><p>直接在 VPS 上执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>-s</span><span> </span><span>https://install.zerotier.com/</span><span> | </span><span>sudo</span><span> </span><span>bash</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>安装完成后会显示一个 10 位的网络ID，请记下来②</strong></p></section></section>
<section><h2>ZeroTier 上的实际操作<a href="#zerotier-上的实际操作"><span>#</span></a></h2><p>在注册了 ZeroTier 帐号后，创建一个网络</p><p><img src="/usr/uploads/2018/12/1285928143.png" alt="" /></p><ol>
<li>
<p>进入这个网络的详情界面后，首先看到“Settings“，<strong>记下左上角的 Network ID ③</strong>；找到右侧的“IPv6 Auto-Assign”，勾选“ZeroTier RFC4193”，取消勾选“ZeroTier 6PLANE”</p>
</li>
<li>
<p>接着往下找到“Members”，在最下方“Manually Add Member”处输入我们之前记下的 ②，然后“+ Add New Member”，这时你会看到你的 VPS 出现在了网络成员列表中，并<strong>记下灰色的 fd35 开头的 IPv6 地址④</strong></p>
</li>
<li>
<p>回到 VPS，执行此命令，用③替换<code>&lt;NetworkID&gt;</code></p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>zerotier-cli set &lt;NetworkID&gt; allowGlobal=true</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>回到网页上的“Settings“，在”Managed Routes“中添加两条路由</p>
<ol>
<li>第一个空填①，第二个空不填</li>
<li>第一个空填<code>::0/0</code>，第二个空填④</li>
</ol>
<p>然后在”IPv6 Auto-Assign“处勾选”Auto-Assign from Range“，第一个空填①，然后别动，等待一会，会自动帮你填写好 v6 地址范围</p>
</li>
</ol></section>
<section><h2>将设备接入虚拟局域网以获取 IPv6<a href="#将设备接入虚拟局域网以获取-ipv6"><span>#</span></a></h2><p>以 Windows 为例：</p><p>前往 <a href="http://www.zerotier.com/download.shtml" target="_blank">http://www.zerotier.com/download.shtml</a> 下载客户端，安装</p><p>首次运行会让你登录 ZeroTier，登陆完后应该会自动帮你加入你在前面建立的那个虚拟局域网（Win10会提示发现新网络之类的），然后右击托盘图标，”Show Networks“，<strong>将”Allow Global IP“、”Allow Managed IP“、”Allow Default Route“这三个全部打勾</strong></p><p>如果”Show Networks“中什么也没有，就右击托盘图标退出程序，再重开一次，这是 ZeroTier Windows 客户端的问题，重启才会更新网络信息</p><p>如果没有自动加入，就右击托盘图标，”Join Network“，输入框中填写③，<strong>并打勾所有勾</strong>，然后”Join“</p><p>接着我们需要设置 IPv6 DNS，打开 控制面板-&gt;所有控制面板项-&gt;网络和共享中心，点击”ZeroTier One [xxxxxxx]“的连接，属性，Internet 协议版本 6，设置 DNS 为谷歌 IPv6 DNS<code>2001:4860:4860::8888</code>和<code>2001:4860:4860::8844</code>，一路确定保存</p><p>尝试在命令提示符中<code>ping -6 google.com</code>，Ping 通就说明成功接入 IPv6 了</p><p><img src="/usr/uploads/2018/12/2535520488.png" alt="" /></p></section>
<section><h2>参考教程<a href="#参考教程"><span>#</span></a></h2><p><a href="https://lantian.pub/article/modify-computer/zerotier-one-own-ipv6-tunnel.lantian" target="_blank">https://lantian.pub/article/modify-computer/zerotier-one-own-ipv6-tunnel.lantian</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/onedrive-5t-storage/</id>
      <title type="text">[OneDrive] E3 订阅无法设置默认5T储存空间的临时解决方法</title>
      <published>2018-12-04T08:35:00.000Z</published>
      <updated>2018-12-04T10:39:15.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/onedrive-5t-storage/"/>
      <summary type="text">近日和好友py到一个E3管理员，但在和他研究设置默认 OneDrive 空间为 5T 的时候遇到了无法设置的问题，后来经过实验可以通过 SharePoint Online Management Shell 临时解决</summary>
      <content type="html"><![CDATA[<p>近日和好友py到一个E3管理员，但在和他研究设置默认 OneDrive 空间为 5T 的时候遇到了无法设置的问题，后来经过实验可以通过 SharePoint Online Management Shell 临时解决</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=71951991" target="_blank">「キララチノちゃん」/「Mocha*」のイラスト [pixiv]</a>
智乃生快w</p>
<hr />
<p>首先你必须拥有 Win 10 及以上系统，因为需要使用 PowerShell</p>
<section><h2>步骤<a href="#步骤"><span>#</span></a></h2><section><h3>1. 下载安装 SharePoint Online Management Shell<a href="#1-下载安装-sharepoint-online-management-shell"><span>#</span></a></h3><ul>
<li>如果你是用的是 PowerShell 5 或更高版本，可以直接执行以下命令安装</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Install-Module</span><span> </span><span>-Name</span><span> </span><span>Microsoft.Online.SharePoint.PowerShell</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>你也可以从微软官网下载安装包
<a href="https://www.microsoft.com/zh-cn/download/details.aspx?id=35588" target="_blank">https://www.microsoft.com/zh-cn/download/details.aspx?id=35588</a></li>
</ul></section><section><h3>2. 运行命令<a href="#2-运行命令"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>$adminUPN</span><span>=</span><span>"xxx@yyy.onmicrosoft.com"</span></div></div><div><div><div>2</div></div><div><span>$orgName</span><span>=</span><span>"yyy"</span></div></div><div><div><div>3</div></div><div><span>$sharepointURL</span><span>=</span><span>"https://yyy.sharepoint.com/personal/xxx_yyy_onmicrosoft_com"</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>$userCredential</span><span> = Get-Credential -UserName </span><span>$adminUPN</span><span> -Message </span><span>"Type the password."</span></div></div><div><div><div>6</div></div><div><span>Connect-SPOService</span><span> </span><span>-Url</span><span> </span><span>https://</span><span>$orgName</span><span>-admin.sharepoint.com</span><span> </span><span>-Credential</span><span> </span><span>$userCredential</span></div></div><div><div><div>7</div></div><div><span>Set-SPOTenant</span><span> </span><span>-OneDriveStorageQuota</span><span> </span><span>5242880</span></div></div><div><div><div>8</div></div><div><span>Set-SPOSite</span><span> </span><span>-Identity</span><span> </span><span>$sharepointURL</span><span> </span><span>-StorageQuota</span><span> </span><span>5242880</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>一切的前提：你使用的必须是组织中的管理员账户</p><p>中途会弹出一个窗口，输入登录密码即可</p><p>并修改命令开头的一些参数，示例中以<code>xxx</code>代表了用户显示名、<code>yyy</code>代表组织名</p><ul>
<li><code>$adminUPN</code>为帐号邮箱</li>
<li><code>$adminUPN</code>为组织名</li>
<li><code>$sharepointURL</code>为用户URL，大概格式就像上面示例的那样，就是你打开 OneDrive 网页时的 URL 前面部分，<strong>并且末尾一定不能加上斜杠<code>/</code></strong></li>
</ul></section><section><h3>3. 完成<a href="#3-完成"><span>#</span></a></h3><p>如果没有报什么错的话，这时候看自己的 OneDrive 空间应该有 5T 了</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/github-css/</id>
      <title type="text">[CSS] Github Markdown Style for Handsome</title>
      <published>2018-11-30T18:57:00.000Z</published>
      <updated>2019-03-31T04:54:34.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/github-css/"/>
      <summary type="text">一直很喜欢 Github 的 Markdown 样式，简洁赏心悦目，因此拿过来并做了些调整以适合博客主题</summary>
      <content type="html"><![CDATA[<p>一直很喜欢 Github 的 Markdown 样式，简洁赏心悦目，因此拿过来并做了些调整以适合博客主题</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=61424301" target="_blank">「しろいいぬ＆マロンちゃん」/「unwitherer」のイラスト [pixiv]</a></p>
<hr />
<p>初始样式来源于：</p>
<a href="https://github.com/sindresorhus/github-markdown-css" target="_blank"><div><div><div><div></div><div>sindresorhus</div></div><div>/</div><div>github-markdown-css</div></div><div></div></div><div>The minimal amount of CSS to replicate the GitHub Markdown style</div><div><div>—</div><div>—</div><div>MIT</div><span>CSS</span></div></a>
<p>以下是经过修改与调整的样式，去除了部分博客用不到的样式，以及按照个人喜好做了调整（字体大小等）</p>
<p><a href="https://gist.github.com/Tsuk1ko/a83589f6371561b0b681f606ef37b2e6" target="_blank">Tsuk1ko/github-markdown-css-for-blog.css</a></p>
<p>目前本博客使用的就是该样式，效果可自由翻阅各文章查看（以及，当然，给出的样式中不含本博客使用的代码块样式）</p>
<p>需要自行给模版文章正文元素加上<code>markdown-body</code>类，或批量替换范围</p>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/pixiv-proxy/</id>
      <title type="text">[Pixiv] Nginx 真·反代P站</title>
      <published>2018-11-08T05:17:00.000Z</published>
      <updated>2023-03-05T05:11:11.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/pixiv-proxy/"/>
      <summary type="text">解决了一年前的我无法解决的世纪难题（x 深刻意识到，很多以前自己认为无解的问题并不是真的无解，只是自己的知识面不够而无法意识到问题的核心所在罢了。 总结起来就一个字：菜</summary>
      <content type="html"><![CDATA[<p>解决了一年前的我无法解决的世纪难题（x</p>
<p>深刻意识到，很多以前自己认为无解的问题并不是真的无解，只是自己的知识面不够而无法意识到问题的核心所在罢了。</p>
<p>总结起来就一个字：菜</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=71361930" target="_blank">「Halloween」/「鳥成」のイラスト [pixiv]</a></p>
<section><h2>前言<a href="#前言"><span>#</span></a></h2><p><strong>本文所述的所有内容仅供交流学习，请勿实际做出任何违反国家法律的行为！</strong></p><p>此方案为真的反代，而不是在本地反代以绕过 SNI 审查的方法（<a href="https://2heng.xin/2017/09/19/pixiv/" target="_blank">Mashiro - PIXIV网页版及客户端访问恢复指南</a>）</p><div><div><div></div><div>Warning</div></div><div><p>请不要在互联网上公开自己搭建的反代站，P 站可能会发邮件到您的主机商投诉。如果您因为此种原因导致 VPS 服务等被终止，本人不负任何责任。</p></div></div></section>
<section><h2>准备工作<a href="#准备工作"><span>#</span></a></h2><ol>
<li>一台没被P站屏蔽的主机
众所周知 Vultr 大部分IP段都被P站屏蔽</li>
<li>一个船新的域名
其实随意啦，用自己域名的二级来弄也可，只是域名会变得比较长
<strong>后续均以<code>example.com</code>来指代我们使用的域名，请灵性代换</strong></li>
<li>因为反代域名较多，最好使用支持泛域名的 SSL 证书，这里我们自然首推 Let’s Encrypt</li>
</ol></section>
<section><h2>域名及证书<a href="#域名及证书"><span>#</span></a></h2><section><h3>需要使用哪些域？<a href="#需要使用哪些域"><span>#</span></a></h3><p>在反代时我们需要用到以下几个域</p><p>如果你愿意使用一个船新域名专门反代：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>example.com</span></div></div><div><div><div>2</div></div><div><span>*.example.com</span></div></div><div><div><div>3</div></div><div><span>*.pximg.example.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li><strong>example.com</strong>
随意，你可以放点自己的东西做一些伪装或者说明，或者直接 301 到<code>www.example.com</code></li>
<li><strong>*.example.com</strong>
用于反代对齐<code>*.pixiv.net</code></li>
<li><strong>*.pximg.example.com</strong>
用于反代对齐<code>*.pximg.net</code>，其实该域名中的<code>pximg</code>也可以替换成其他的字符串，<strong>只要不与P站的二级域名服务产生冲突即可</strong></li>
</ul><p>如果你想用一个自己正在使用的域名反代并且不想影响该域名的其他服务：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>pixiv.example.com</span></div></div><div><div><div>2</div></div><div><span>*.pixiv.example.com</span></div></div><div><div><div>3</div></div><div><span>*.pximg.example.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>各自作用同上，在后续配置上灵性修改即可</p></section><section><h3>获取证书<a href="#获取证书"><span>#</span></a></h3><p>如果你愿意套 CloudFlare，你可以跳过这一节</p><p>使用 acme 的 DNS API 方式进行挑战验证来签发证书是最方便的</p><p>参考以下文章</p><a href="/posts/acme-le-wc/"><div><div>使用 acme.sh 申请 Let's Encrypt 泛域名SSL证书详细教程</div><div>Let's Encrypt 泛域名SSL已经出来挺长一段时间了，昨天才有需要，因此尝试了一下部署。 一开始看的是 Leonn 的教程，但不是很详细，自己弄懂了流程之后决定写一篇详细一点的教程（使用 CloudXNS 的 API 添加记录进行验证）。</div><div><span>2018-04-01</span><span>教程</span><span><span>#acme.sh</span><span>#证书</span><span>#泛域名</span><span>#dns</span></span></div></div><div><img src="/usr/uploads/2018/04/1493091948.jpg" alt="" loading="lazy" /></div></a><p>在配置好 API 之后我们使用这样的命令即可签发一个我们想要的三域名合一的证书了，并且还能自动续签，岂不美哉</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>~/.acme.sh/acme.sh --issue --dns dns_cx -d example.com -d </span><span>'*.example.com'</span><span> -d </span><span>'*.pximg.example.com'</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>Nginx<a href="#nginx"><span>#</span></a></h2><div><div><div></div><div>Warning</div></div><div><p>不要使用 Tengine 等 Nginx 分支版本，在某些模块上可能会有一些奇怪的差异与问题</p></div></div><section><h3>基础配置<a href="#基础配置"><span>#</span></a></h3><p>这里仅列出关键配置，通常配置例如<code>listen</code>、<code>expires</code>、<code>cache</code>以及 SSL 之类的不会写出，自行添加</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># *.example.com</span></div></div><div><div><div>2</div></div><div><span>server</span></div></div><div><div><div>3</div></div><div><span>{</span></div></div><div><div><div>4</div></div><div><span><span>  </span></span><span>server_name ~^([^.]+)\.example\.com$;</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>set $domain $1;</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>resolver 8.8.8.8;</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>location ~ .*</span></div></div><div><div><div>10</div></div><div><span><span>  </span></span><span>{</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>proxy_set_header Host $domain.pixiv.net;</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>proxy_set_header Referer "https://www.pixiv.net";</span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>proxy_cookie_domain pixiv.net example.com;</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>proxy_pass https://$domain.pixiv.net;</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>proxy_ssl_server_name on;</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>proxy_set_header Accept-Encoding "";</span></div></div><div><div><div>17</div></div><div><span><span>    </span></span><span>proxy_redirect https://accounts.pixiv.net/ https://accounts.example.com/;</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span><span>    </span></span><span>sub_filter "i-cf.pximg.net" "i.example.com";</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>sub_filter "pixiv.net" "example.com";</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>sub_filter "pximg.net" "pximg.example.com";</span></div></div><div><div><div>22</div></div><div><span><span>    </span></span><span># 防止错误上报暴露站点</span></div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>sub_filter "js_error.php" "block_js_error";</span></div></div><div><div><div>24</div></div><div><span><span>    </span></span><span># 防止谷歌服务暴露站点，同时也可以加快网站加载</span></div></div><div><div><div>25</div></div><div><span><span>    </span></span><span>sub_filter "www.google" "block_google";</span></div></div><div><div><div>26</div></div><div><span><span>    </span></span><span>sub_filter_once off;</span></div></div><div><div><div>27</div></div><div><span><span>    </span></span><span>sub_filter_types *;</span></div></div><div><div><div>28</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>29</div></div><div><span>}</span></div></div><div><div><div>30</div></div><div>
</div></div><div><div><div>31</div></div><div><span># *.pximg.example.com</span></div></div><div><div><div>32</div></div><div><span>server</span></div></div><div><div><div>33</div></div><div><span>{</span></div></div><div><div><div>34</div></div><div><span><span>  </span></span><span>server_name ~^([^.]+)\.pximg\.example\.com$;</span></div></div><div><div><div>35</div></div><div><span><span>  </span></span><span>set $domain $1;</span></div></div><div><div><div>36</div></div><div>
</div></div><div><div><div>37</div></div><div><span><span>  </span></span><span>resolver 8.8.8.8;</span></div></div><div><div><div>38</div></div><div>
</div></div><div><div><div>39</div></div><div><span><span>  </span></span><span>location ~ .*</span></div></div><div><div><div>40</div></div><div><span><span>  </span></span><span>{</span></div></div><div><div><div>41</div></div><div><span><span>    </span></span><span>proxy_set_header Host $domain.pximg.net;</span></div></div><div><div><div>42</div></div><div><span><span>    </span></span><span>proxy_set_header Referer "https://www.pixiv.net";</span></div></div><div><div><div>43</div></div><div><span><span>    </span></span><span>proxy_pass https://$domain.pximg.net;</span></div></div><div><div><div>44</div></div><div><span><span>    </span></span><span>proxy_ssl_server_name on;</span></div></div><div><div><div>45</div></div><div><span><span>    </span></span><span>proxy_set_header Accept-Encoding "";</span></div></div><div><div><div>46</div></div><div>
</div></div><div><div><div>47</div></div><div><span><span>    </span></span><span>sub_filter "i-cf.pximg.net" "i.example.com";</span></div></div><div><div><div>48</div></div><div><span><span>    </span></span><span>sub_filter "pixiv.net" "example.com";</span></div></div><div><div><div>49</div></div><div><span><span>    </span></span><span>sub_filter "pximg.net" "pximg.example.com";</span></div></div><div><div><div>50</div></div><div><span><span>    </span></span><span># 防止错误上报暴露站点</span></div></div><div><div><div>51</div></div><div><span><span>    </span></span><span>sub_filter "js_error.php" "block_js_error";</span></div></div><div><div><div>52</div></div><div><span><span>    </span></span><span># 防止谷歌服务暴露站点，同时也可以加快网站加载</span></div></div><div><div><div>53</div></div><div><span><span>    </span></span><span>sub_filter "www.google" "block_google";</span></div></div><div><div><div>54</div></div><div><span><span>    </span></span><span>sub_filter_once off;</span></div></div><div><div><div>55</div></div><div><span><span>    </span></span><span>sub_filter_types *;</span></div></div><div><div><div>56</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>57</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>详解<a href="#详解"><span>#</span></a></h3><ul>
<li><strong>server_name</strong> 与 <strong>set</strong>
使用正则表达式匹配以方便直接提取出我们要反代的二级域名</li>
<li><strong>resolver</strong>
必要，指定域名解析所用 DNS，因为在后续<code>proxy_pass</code>中我们要反代的域名是由<code>$domain</code>决定，本身是不定的，Nginx 必须被指定 DNS 才能处理域名解析</li>
<li><strong>proxy_cookie_domain</strong>
改变反代后返回的 header 中 set-cookie 里 cookie 对应的域名，只在<code>*.example.com</code>中需要，是解决登陆问题的关键，如想了解后续文章会解释</li>
<li><strong>proxy_ssl_server_name</strong>
由于 P 站开始上 CF 了，其 TLS 启用了 SNI，因此必须指定此项为<code>on</code>，否则会握手失败</li>
<li><strong>proxy_set_header Referer</strong>
设置 header 中的 Referer，主要目的是解决<code>i.pximg.net</code>的防盗链问题，以及<code>www.pixiv.net</code>的部分 API 的 Referer 验证问题</li>
<li><strong>proxy_set_header Accept-Encoding</strong>
将接受的压缩编码设为空，即不接受压缩，因为<code>sub_filter</code>无法对压缩过的内容起效</li>
<li><strong>proxy_redirect</strong>
将返回原站 302 的请求进行重定向</li>
<li><strong>sub_filter</strong>
将反代后得到的内容进行字符串替换，以保证链接域名等与反代域名一致</li>
<li><strong>sub_filter_types</strong>
必须设置为<code>*</code>，否则默认对于 API 返回的 json 内容等不会进行替换，会导致依靠 ajax 运作的一些功能的异常</li>
</ul></section></section>
<section><h2>增强隐蔽性（建议）<a href="#增强隐蔽性建议"><span>#</span></a></h2><section><h3>防止被搜索引擎收录<a href="#防止被搜索引擎收录"><span>#</span></a></h3><p>在 Nginx 配置中向每个 server 添加此句</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>  </span></span><span>if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|^$") {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>return 403;</span></div></div><div><div><div>3</div></div><div><span><span>  </span></span><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>请加到<code>set $domain $1;</code>这句之后，因为该配置也使用了正则表达式，会导致<code>$1</code>改变</p></section><section><h3>禁止大陆外IP访问<a href="#禁止大陆外ip访问"><span>#</span></a></h3><p>由于反代P站的受众只可能为大陆内用户，因此我们完全可以禁止大陆外IP访问反代站，同时还能防止P站检测投诉</p><p>但请注意，这个方案是对整台 VPS 的<code>80</code>与<code>443</code>端口生效，这意味着你如果同时在 VPS 上布置了其他站点，他们也将无法被大陆外用户访问</p><p>如果需要仅对反代站点生效，请自行百度参考“nginx geoip”，或者使用后面所述的套 CloudFlare 的方式</p><p>参考步骤：</p><ol>
<li>安装 ipset</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Debian / Ubuntu</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>-y</span><span> </span><span>install</span><span> </span><span>ipset</span></div></div><div><div><div>3</div></div><div><span># CentOS</span></div></div><div><div><div>4</div></div><div><span>yum</span><span> </span><span>-y</span><span> </span><span>install</span><span> </span><span>ipset</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>创建一个 ipset 并添加大陆IP作为白名单</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ipset</span><span> </span><span>-N</span><span> </span><span>cnip</span><span> </span><span>hash:net</span></div></div><div><div><div>2</div></div><div><span>for</span><span> </span><span>i</span><span> </span><span>in</span><span> $(</span><span>curl</span><span> </span><span>https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt</span><span>); </span><span>do</span><span> </span><span>ipset</span><span> </span><span>-A</span><span> </span><span>cnip</span><span> </span><span>$i</span><span>; </span><span>done</span></div></div><div><div><div>3</div></div><div><span># 如果你想要添加单个IP x.x.x.x 进此白名单</span></div></div><div><div><div>4</div></div><div><span>ipset</span><span> </span><span>-A</span><span> </span><span>cnip</span><span> </span><span>x.x.x.x/32</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>写入防火墙规则（顺序十分重要，请不要改变执行顺序）</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>iptables</span><span> </span><span>-I</span><span> </span><span>INPUT</span><span> </span><span>-p</span><span> </span><span>tcp</span><span> </span><span>--dport</span><span> </span><span>443</span><span> </span><span>-j</span><span> </span><span>DROP</span></div></div><div><div><div>2</div></div><div><span>iptables</span><span> </span><span>-I</span><span> </span><span>INPUT</span><span> </span><span>-p</span><span> </span><span>tcp</span><span> </span><span>--dport</span><span> </span><span>80</span><span> </span><span>-j</span><span> </span><span>DROP</span></div></div><div><div><div>3</div></div><div><span>iptables</span><span> </span><span>-I</span><span> </span><span>INPUT</span><span> </span><span>-p</span><span> </span><span>tcp</span><span> </span><span>-m</span><span> </span><span>set</span><span> </span><span>--match-set</span><span> </span><span>cnip</span><span> </span><span>src</span><span> </span><span>-j</span><span> </span><span>ACCEPT</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>套 CloudFlare<a href="#套-cloudflare"><span>#</span></a></h3><p>除了上述方案外，我自己是套了层 CloudFlare，并设置了防火墙规则来阻止非国内以及搜索引擎爬虫访问</p><p>这样有个优点，一是 SSL 证书都是 Cloudflare 自动签发和续期的，因此使用 Flexible SSL 选项，然后源反代站就不需要操心证书的事了，直接使用 HTTP；二是 Cloudflare 的防火墙可以实现上面提到的屏蔽国内 IP 以及搜索引擎的功能，不需要自己去维护</p><p>当然这样是有缺点的，就是设置 DNS 记录</p><p>Cloudflare <strong>CDN</strong> 是<strong>不支持设置泛域名记录</strong>的</p><p>因此我们只能一条一条记录加，首次部署简直是要了命，以下列出主站功能相关域名：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>www.pixiv.net</span></div></div><div><div><div>2</div></div><div><span>accounts.pixiv.net</span></div></div><div><div><div>3</div></div><div><span>source.pixiv.net</span></div></div><div><div><div>4</div></div><div><span>imp.pixiv.net</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>i.pximg.net</span></div></div><div><div><div>7</div></div><div><span>s.pximg.net</span></div></div><div><div><div>8</div></div><div><span>pixiv.pximg.net</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>其他的例如小说、直播等等我个人使用频率很低所以我就不考虑了，当然如果你有需求就自己找域名吧（</p></section></section>
<section><h2>局限性<a href="#局限性"><span>#</span></a></h2><p>不能使用绑定的社交账号的登录方式</p><p>帐号可能会出现需要 reCAPTCHA 验证导致无法登录，无解，只能自己将原站已登录的 cookie 导出，替换域名，然后导入反代站来进行登录</p><p>可能存在尚未发现的问题</p></section>
<section><h2>解决登陆问题的关键<a href="#解决登陆问题的关键"><span>#</span></a></h2><p>这个问题困扰我一年了，以前我尝试反代的时候，<strong>登录会提示“无效的服务器”而无法登陆</strong>，直到最近才发现真正原因</p><p>我通过搜索引擎查找了很多文章，直到遇见了这篇
<a href="https://kotori.love/archives/curl-login-pixiv-next.html" target="_blank">模拟登录pixiv.net后续 - ことりのおやつにしてやるぞー！</a></p><p>之前我认为，登录时唯一要注意的只有<code>postKey</code>，而代码中的获取 cookie 的操作提醒了我，我的直觉告诉我登录失败是跟 cookie 有关</p><p>于是我又翻看了一下 GET 登陆页面时的 header，原来是有 set-cookie 的，而我之前一直从登录相关 js 的操作入手因此没有注意到这个细节</p><p>根据这个思路我试着自己用 Nodejs 写了个模拟登录来尝试</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> </span><span>Axios</span><span> </span><span>=</span><span> </span><span>require</span><span>(</span><span>"axios"</span><span>);</span></div></div><div><div><div>2</div></div><div><span>const</span><span> </span><span>Qs</span><span> </span><span>=</span><span> </span><span>require</span><span>(</span><span>"qs"</span><span>);</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>async</span><span> </span><span>function</span><span> </span><span>test</span><span>() {</span></div></div><div><div><div>5</div></div><div><span>  </span><span>let</span><span><span> </span><span>postKey</span><span>,</span></span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>cookie</span><span> </span><span>=</span><span> </span><span>""</span><span>;</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>  </span><span>//访问登录页</span></div></div><div><div><div>9</div></div><div><span>  </span><span>await</span><span><span> </span><span>Axios</span><span>.</span></span><span>get</span><span>(</span></div></div><div><div><div>10</div></div><div><span>    </span><span>"https://accounts.pixiv.net/login?lang=zh&amp;source=pc&amp;view_type=page&amp;ref=wwwtop_accounts_index"</span><span>,</span></div></div><div><div><div>11</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>12</div></div><div><span>      </span><span>headers</span><span>:</span><span> {</span></div></div><div><div><div>13</div></div><div><span>        </span><span>"user-agent"</span><span>:</span></div></div><div><div><div>14</div></div><div><span>          </span><span>"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"</span><span>,</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>17</div></div><div><span><span>  </span></span><span>).</span><span>then</span><span><span>((</span><span>res</span><span>) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>18</div></div><div><span>    </span><span>//获取登录页 cookie 和 postKey</span></div></div><div><div><div>19</div></div><div><span>    </span><span>for</span><span> (</span><span>let</span><span><span> </span><span>set</span><span> </span></span><span>of</span><span><span> </span><span>res</span><span>.</span></span><span>headers</span><span>[</span><span>"set-cookie"</span><span>]) {</span></div></div><div><div><div>20</div></div><div><span><span>      </span></span><span>cookie</span><span> </span><span>+=</span><span> </span><span>"; "</span><span> </span><span>+</span><span><span> </span><span>set</span><span>.</span></span><span>split</span><span>(</span><span>";"</span><span>)[</span><span>0</span><span>];</span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>22</div></div><div><span><span>    </span></span><span>cookie</span><span> </span><span>=</span><span><span> </span><span>cookie</span><span>.</span></span><span>substr</span><span>(</span><span>2</span><span>);</span></div></div><div><div><div>23</div></div><div><span><span>    </span></span><span>postKey</span><span> </span><span>=</span><span><span> /"pixivAccount</span><span>\.</span><span>postKey":"(</span></span><span>[0-9a-z]</span><span><span>+</span><span>)"/</span></span><span>.</span><span>exec</span><span><span>(</span><span>res</span><span>.</span></span><span>data</span><span>)[</span><span>1</span><span>];</span></div></div><div><div><div>24</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span>  </span><span>//向登录 API 发送 POST</span></div></div><div><div><div>27</div></div><div><span>  </span><span>await</span><span><span> </span><span>Axios</span><span>.</span></span><span>post</span><span>(</span></div></div><div><div><div>28</div></div><div><span>    </span><span>"https://accounts.pixiv.net/api/login?lang=zh"</span><span>,</span></div></div><div><div><div>29</div></div><div><span><span>    </span></span><span>Qs</span><span>.</span><span>stringify</span><span>({</span></div></div><div><div><div>30</div></div><div><span>      </span><span>pixiv_id</span><span>:</span><span> </span><span>"邮箱"</span><span>,</span></div></div><div><div><div>31</div></div><div><span>      </span><span>password</span><span>:</span><span> </span><span>"密码"</span><span>,</span></div></div><div><div><div>32</div></div><div><span>      </span><span>captcha</span><span>:</span><span> </span><span>""</span><span>,</span></div></div><div><div><div>33</div></div><div><span>      </span><span>g_recaptcha_response</span><span>:</span><span> </span><span>""</span><span>,</span></div></div><div><div><div>34</div></div><div><span>      </span><span>post_key</span><span>:</span><span><span> </span><span>postKey</span><span>,</span></span></div></div><div><div><div>35</div></div><div><span>      </span><span>source</span><span>:</span><span> </span><span>"pc"</span><span>,</span></div></div><div><div><div>36</div></div><div><span>      </span><span>ref</span><span>:</span><span> </span><span>"wwwtop_accounts_index"</span><span>,</span></div></div><div><div><div>37</div></div><div><span>      </span><span>return_to</span><span>:</span><span> </span><span>"https://www.pixiv.net/"</span><span>,</span></div></div><div><div><div>38</div></div><div><span><span>    </span></span><span>}),</span></div></div><div><div><div>39</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>40</div></div><div><span>      </span><span>headers</span><span>:</span><span> {</span></div></div><div><div><div>41</div></div><div><span>        </span><span>"user-agent"</span><span>:</span></div></div><div><div><div>42</div></div><div><span>          </span><span>"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"</span><span>,</span></div></div><div><div><div>43</div></div><div><span>        </span><span>"content-type"</span><span>:</span><span> </span><span>"application/x-www-form-urlencoded"</span><span>,</span></div></div><div><div><div>44</div></div><div><span>        </span><span>accept</span><span>:</span><span> </span><span>"application/json"</span><span>,</span></div></div><div><div><div>45</div></div><div><span>        </span><span>cookie</span><span>:</span><span><span> </span><span>cookie</span><span>,</span></span></div></div><div><div><div>46</div></div><div><span><span>      </span></span><span>},</span></div></div><div><div><div>47</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>48</div></div><div><span><span>  </span></span><span>).</span><span>then</span><span><span>((</span><span>res</span><span>) </span></span><span>=&gt;</span><span> {</span></div></div><div><div><div>49</div></div><div><span><span>    </span></span><span>console</span><span>.</span><span>log</span><span><span>(</span><span>res</span><span>.</span></span><span>data</span><span>);</span></div></div><div><div><div>50</div></div><div><span><span>    </span></span><span>console</span><span>.</span><span>log</span><span><span>(</span><span>res</span><span>.</span></span><span>headers</span><span>[</span><span>"set-cookie"</span><span>]);</span></div></div><div><div><div>51</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>52</div></div><div><span>}</span></div></div><div><div><div>53</div></div><div>
</div></div><div><div><div>54</div></div><div><span>test</span><span>();</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>返回内容与返回 header 中的 set-cookie：
<img src="/usr/uploads/2018/11/1564315779.png" alt="" /></p><p>可喜可贺，也就是说确实是 cookie 的锅</p><p>准确地说是因为 sub_filter 只能替换 response 中的内容，我没有想到 set-cookie 的 domain 由于是 <code>.pixiv.net</code>，不会被任何机制自动替换，与反代域名不同，没有 set 上，因此导致发出登录 POST 的时候没有携带上这个 cookie</p><p>知道了问题核心所在，那么解决方案自然也就不难想到了，经过搜索我找到了 Nginx 官方文档中有提到 <a href="http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain" target="_blank">proxy_cookie_domain</a></p><blockquote><p><strong>Syntax:</strong> &gt; <strong>proxy_cookie_domain</strong> off;
<strong>proxy_cookie_domain</strong> domain replacement;</p><p><strong>Default:</strong>
<strong>proxy_cookie_domain</strong> off;</p><p><strong>Context:</strong> http, server, location</p><p>This directive appeared in version 1.1.15.</p><p>Sets a text that should be changed in the domain attribute of the “Set-Cookie” header fields of a proxied server response.</p></blockquote><p>问题解决√</p><p>而且没想到解决方式竟如此简单，只不过是加一行配置的事</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/uooconline-assistant/</id>
      <title type="text">[UoocOnline] 优课在线辅助</title>
      <published>2018-11-03T05:16:00.000Z</published>
      <updated>2020-05-30T03:46:26.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/uooconline-assistant/"/>
      <summary type="text">通过模拟正常视频观看进度刷课，Nodejs 编写</summary>
      <content type="html"><![CDATA[<p>通过模拟正常视频观看进度刷课，Nodejs 编写</p>
<p>Head Pic from (C91) [予備学科 (米白粕)] ふりふりりぼん</p>
<hr />
<a href="https://github.com/Tsuk1ko/uooconline-learner" target="_blank"><div><div><div><div></div><div>Tsuk1ko</div></div><div>/</div><div>uooconline-learner</div></div><div></div></div><div>替你学习</div><div><div>—</div><div>—</div><div>GPL-3.0</div><span>JavaScript</span></div></a>
<p><strong>使用方法一并在内，如果不会使用则说明您不适合使用本程序</strong></p>
<p>运行后会每隔1分钟提交一次视频进度并有当前进度输出，请耐心等待</p>
<section><h2>需知<a href="#需知"><span>#</span></a></h2><p>这一项目是我自用顺带开源，目的更多是为了提供一个简单的思路与框架，我并不会对其长期维护，况且我已经毕业了</p><p><strong>由于不同人的课程系统与结构之间存在差异，我没法做到可以让所有人都部署即用，对于“运行之后怎么没有反应”、“为什么显示完课程目录就直接退出了”等问题恕我无法解决，有能力可自行 debug 修改</strong></p></section>
<section><h2>忠告<a href="#忠告"><span>#</span></a></h2><p>为了自己着想，与专业有关的慕课请自己认真看</p><p>这程序也只是我为了应付一些为了刷学分的慕课选修而写的而已</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/overture/</id>
      <title type="text">[overture] 无污染的智能 DNS 折腾记 #4</title>
      <published>2018-10-22T11:29:00.000Z</published>
      <updated>2020-07-30T17:10:11.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/overture/"/>
      <summary type="text">我是在大概三个月前得知了 overture 并开始使用，其相对 ChinaDNS 的优点是设置更丰富、使用国内外 DNS 的判断逻辑更完善、支持 ECS (edns-client-subnet)，并且设置比 Pcap DNSProxy 简单很多。 本文会介绍在 PC 及 openwrt 路由器上部署 overture 的方法和要点。</summary>
      <content type="html"><![CDATA[<p>我是在大概三个月前得知了 overture 并开始使用，其相对 ChinaDNS 的优点是设置更丰富、使用国内外 DNS 的判断逻辑更完善、支持 ECS (edns-client-subnet)，并且设置比 Pcap DNSProxy 简单很多。</p>
<p>本文会介绍在 PC 及 openwrt 路由器上部署 overture 的方法和要点。</p>
<p>即便现在由于 SNI 阻断，无污染 DNS 的作用越来越小，但这还是我此生不变的信仰（x</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=69860434" target="_blank">「雨上がり」/「Mauve」のイラスト [pixiv]</a></p>
<hr />
<p>这是 Go 语言编写的一个 DNS 服务端</p>
<p>你可以直接在 <a href="https://github.com/shawn1m/overture/releases" target="_blank">Releases</a> 页面下载到编译好的可执行文件</p>
<p>Windows 请下载<code>overture-windows-386.zip</code>（32位）或<code>overture-windows-amd64.zip</code>（64位）
Linux 请根据架构下载对应版本，常见的<code>x86_64</code>请下载<code>overture-linux-amd64.zip</code>
Openwrt 路由器一般是 mipsle，至于是不是 64 以及 softfloat / hardfloat 不清楚的话就自己试吧</p>
<section><h2>配置<a href="#配置"><span>#</span></a></h2><p>此处稍微解释下配置内容，过于简单的部分就不赘述了
你也可以在项目 README 看到完整的英文说明</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"BindAddress"</span><span>: </span><span>":53"</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>"PrimaryDNS"</span><span>: [</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>5</div></div><div><span>      </span><span>//主DNS：一般使用国内DNS</span></div></div><div><div><div>6</div></div><div><span>      </span><span>"Name"</span><span>: </span><span>"DNSPod"</span><span>,</span></div></div><div><div><div>7</div></div><div><span>      </span><span>"Address"</span><span>: </span><span>"119.29.29.29:53"</span><span>,</span></div></div><div><div><div>8</div></div><div><span>      </span><span>"Protocol"</span><span>: </span><span>"udp"</span><span>,</span></div></div><div><div><div>9</div></div><div><span>      </span><span>"SOCKS5Address"</span><span>: </span><span>""</span><span>,</span></div></div><div><div><div>10</div></div><div><span>      </span><span>"Timeout"</span><span>: </span><span>6</span><span>,</span></div></div><div><div><div>11</div></div><div><span>      </span><span>"EDNSClientSubnet"</span><span>: {</span></div></div><div><div><div>12</div></div><div><span>        </span><span>//ECS设置，在后文详述</span></div></div><div><div><div>13</div></div><div><span>        </span><span>"Policy"</span><span>: </span><span>"auto"</span><span>,</span></div></div><div><div><div>14</div></div><div><span>        </span><span>"ExternalIP"</span><span>: </span><span>""</span></div></div><div><div><div>15</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>17</div></div><div><span><span>  </span></span><span>],</span></div></div><div><div><div>18</div></div><div><span>  </span><span>"AlternativeDNS"</span><span>: [</span></div></div><div><div><div>19</div></div><div><span><span>    </span></span><span>{</span></div></div><div><div><div>20</div></div><div><span>      </span><span>//备DNS：一般使用支持非53端口的国外DNS</span></div></div><div><div><div>21</div></div><div><span>      </span><span>"Name"</span><span>: </span><span>"OpenDNS"</span><span>,</span></div></div><div><div><div>22</div></div><div><span>      </span><span>"Address"</span><span>: </span><span>"208.67.222.222:443"</span><span>,</span></div></div><div><div><div>23</div></div><div><span>      </span><span>"Protocol"</span><span>: </span><span>"tcp"</span><span>,</span></div></div><div><div><div>24</div></div><div><span>      </span><span>"SOCKS5Address"</span><span>: </span><span>""</span><span>,</span></div></div><div><div><div>25</div></div><div><span>      </span><span>"Timeout"</span><span>: </span><span>6</span><span>,</span></div></div><div><div><div>26</div></div><div><span>      </span><span>"EDNSClientSubnet"</span><span>: {</span></div></div><div><div><div>27</div></div><div><span>        </span><span>"Policy"</span><span>: </span><span>"disable"</span><span>,</span></div></div><div><div><div>28</div></div><div><span>        </span><span>"ExternalIP"</span><span>: </span><span>""</span></div></div><div><div><div>29</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>30</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>31</div></div><div><span><span>  </span></span><span>],</span></div></div><div><div><div>32</div></div><div><span>  </span><span>"OnlyPrimaryDNS"</span><span>: </span><span>false</span><span>,</span></div></div><div><div><div>33</div></div><div><span>  </span><span>"IPv6UseAlternativeDNS"</span><span>: </span><span>false</span><span>, </span><span>//对于IPv6是否仅使用备DNS查询的作为结果</span></div></div><div><div><div>34</div></div><div><span>  </span><span>"IPNetworkFile"</span><span>: {</span></div></div><div><div><div>35</div></div><div><span>    </span><span>//IP黑白名单配置，在后文详述</span></div></div><div><div><div>36</div></div><div><span>    </span><span>"Primary"</span><span>: </span><span>"./ip_network_primary_sample"</span><span>,</span></div></div><div><div><div>37</div></div><div><span>    </span><span>"Alternative"</span><span>: </span><span>"./ip_network_alternative_sample"</span></div></div><div><div><div>38</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>39</div></div><div><span>  </span><span>"DomainFile"</span><span>: {</span></div></div><div><div><div>40</div></div><div><span>    </span><span>//域名黑白名单配置，在后文详述</span></div></div><div><div><div>41</div></div><div><span>    </span><span>"Primary"</span><span>: </span><span>"./domain_primary_sample"</span><span>,</span></div></div><div><div><div>42</div></div><div><span>    </span><span>"Alternative"</span><span>: </span><span>"./domain_alternative_sample"</span><span>,</span></div></div><div><div><div>43</div></div><div><span>    </span><span>"Matcher"</span><span>: </span><span>"suffix-tree"</span><span> </span><span>// 无特殊需求请用这个</span></div></div><div><div><div>44</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>45</div></div><div><span>  </span><span>"HostsFile"</span><span>: </span><span>"./hosts_sample"</span><span>, </span><span>//指定Hosts</span></div></div><div><div><div>46</div></div><div><span>  </span><span>"MinimumTTL"</span><span>: </span><span>0</span><span>, </span><span>//解析记录最小缓存时间（秒），0则不使用</span></div></div><div><div><div>47</div></div><div><span>  </span><span>"CacheSize"</span><span>: </span><span>0</span><span>, </span><span>//缓存条数，0则不使用</span></div></div><div><div><div>48</div></div><div><span>  </span><span>"RejectQtype"</span><span>: [</span><span>255</span><span>]</span></div></div><div><div><div>49</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><section><h3>ECS<a href="#ecs"><span>#</span></a></h3><p>不清楚 edns-client-subnet 可先百度了解</p><p>国内的话目前 DNSPod 有 EDNS 支持
国外的话谷歌支持，CloudFlare 为了保持匿名性而不会支持</p><ul>
<li><strong>Policy</strong> 可填以下几种</li>
<li><code>auto</code>：如果客户端IP不是保留IP（你可以简单的将保留IP理解成 内网IP + localhost），则使用客户端IP，否则使用 ExternalIP</li>
<li><code>manual</code>：如果 ExternalIP 不为空则使用，否则当客户端IP不是保留IP的时候使用客户端IP</li>
<li><code>disable</code>：关闭该功能</li>
<li><strong>ExternalIP</strong>（外部IP）
如果该项为空并且发起查询请求的IP不是外部IP，则该功能会被禁用</li>
</ul><p>也就是说，如果想启用该功能，则 Policy 填<code>auto</code>
如果你是在自己的 PC 上运行 overture，则 ExternalIP 填你当前网络环境的公网IP
如果你是用你自己的 VPS 搭建 DNS，则 ExternalIP 可以留空</p></section><section><h3>xxxxxFile<a href="#xxxxxfile"><span>#</span></a></h3><p>这些文件的指定是用于筛选主备DNS返回的结果，并将“合格”的作为最终结果，作用有点像黑白名单</p><p>填写路径的时候注意<strong>绝对/相对路径</strong>之间的区别，建议填写绝对路径
以及，<strong>Windows 路径的反斜杠需要转义</strong>，即使用<code>\\</code></p><p>（我有点担心所以还是说一下）：不支持直接使用在线 URL，所以后续提到的文件请下载到本地后使用</p><div><div><div></div><div>Note</div></div><div><p>如果你想在路由器上使用，并且用的是H大的老毛子固件，后续有使用 overture 代替固件中自带的 ChinaDNS 的配置方法详述，不需要下载下面提到的文件</p></div></div><section><h4>IPNetworkFile<a href="#ipnetworkfile"><span>#</span></a></h4><p>文件内容为一行一个 CIDR</p><p>Primary 可使用 chnrouter，Alternative 不需要理会</p><p>这样的作用是当主DNS查询结果是国内 IP 的时候则立即采用，抛弃备DNS的结果，以加快查询速度和防止将国内服务解析到国外服务器</p><p>推荐 IPIP 维护的 <a href="https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt" target="_blank">chnrouter</a></p></section><section><h4>DomainFile<a href="#domainfile"><span>#</span></a></h4><p>文件内容为一行一个域名</p><p>Primary 不需要理会（可以使用国内常见域名列表，但没必要），Alternative 可使用 gfwlist 域名列表</p><p>Matcher 是匹配方式，说明详见 <a href="https://github.com/shawn1m/overture/issues/180" target="_blank">issue#180</a></p><p>你可以使用以下 Linux 命令生成一个可使用的域名列表（其中包含 gfwlist + Koolshare 列表）（来自H大的老毛子固件）</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt</span><span> | </span><span>base64</span><span> </span><span>-d</span><span> | </span><span>sort</span><span> </span><span>-u</span><span> | </span><span>sed</span><span> </span><span>'/^$\|@@/d'</span><span>| </span><span>sed</span><span> </span><span>'s#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;'</span><span> | </span><span>sed</span><span> </span><span>'/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /qq\.com/d'</span><span> | </span><span>sed</span><span> </span><span>'/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d'</span><span> | </span><span>grep</span><span> </span><span>'^[0-9a-zA-Z\.-]\+$'</span><span> | </span><span>grep</span><span> </span><span>'\.'</span><span> | </span><span>sed</span><span> </span><span>'s#^\.\+##'</span><span> | </span><span>sort</span><span> </span><span>-u</span><span> &gt; </span><span>/tmp/temp_gfwlist.txt</span></div></div><div><div><div>2</div></div><div><span>curl</span><span> </span><span>https://raw.githubusercontent.com/hq450/fancyss/master/rules/gfwlist.conf</span><span> | </span><span>sed</span><span> </span><span>'s/ipset=\/\.//g; s/\/gfwlist//g; /^server/d'</span><span> &gt; </span><span>/tmp/temp_koolshare.txt</span></div></div><div><div><div>3</div></div><div><span>cat</span><span> </span><span>/tmp/temp_gfwlist.txt</span><span> </span><span>/tmp/temp_koolshare.txt</span><span> | </span><span>sort</span><span> </span><span>-u</span><span> &gt; </span><span>gfw_all_domain.txt</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果你没有 Linux，你可以开一个虚拟机或者 Windows 下的 Linux 子系统或者使用 Cmder/MinGW</p></section></section><section><h3>HostsFile<a href="#hostsfile"><span>#</span></a></h3><p>如果是在本机搭建并使用，建议修改</p><p>Windows 使用<code>C:\\Windows\\System32\\drivers\\etc\\hosts</code></p><p>Linux / Openwrt 使用<code>/etc/hosts</code></p></section></section>
<section><h2>运行<a href="#运行"><span>#</span></a></h2><section><h3>Windows<a href="#windows"><span>#</span></a></h3><p>直接运行 .exe 文件即可，但这样会一直存在一个命令提示符窗口，想必会很难受</p><p>因此你可以将以下代码保存为一个 VBS 脚本，例如<code>overture.vbs</code>，用来运行或直接添加到开机启动中，可以不显示窗口</p><div><div><div></div><div>Note</div></div><div><p>建议直接将脚本放在和可执行文件同目录下，并且添加开机启动时使用脚本的快捷方式，这样不需要额外写路径</p></div></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>CreateObject(</span><span>"WScript.Shell"</span><span>).Run </span><span>"overture-windows-amd64.exe"</span><span>,0</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Linux / Openwrt<a href="#linux--openwrt"><span>#</span></a></h3><p>在 Linux 中运行时推荐手动使用<code>-c</code>参数指定配置文件路径，并且推荐使用绝对路径，特别是你写入<code>/etc/rc.local</code>中的时候</p></section><section><h3>H大的老毛子固件<a href="#h大的老毛子固件"><span>#</span></a></h3><section><h4>有 ss_tproxy 的新版固件<a href="#有-ss_tproxy-的新版固件"><span>#</span></a></h4><p>我只大概说一下我的改法，不详细解释了，具体作用自行领会，不懂别问我</p><ol>
<li><code>Sh15_ss.sh</code>中<code>nvram set app_112="0"</code>改为<code>nvram set app_112="1"</code>，否则如果开启 ss_tproxy 的话你在 web 中设置“跳过自动开启第三方 DNS”是无效的</li>
<li><code>sh_ss_tproxy.sh</code>中在<code>update_wanlanlist_ipset</code>函数的末尾<code>restart_dhcpd</code>之前插一句<code>sed -i '/^server=/d' /opt/app/ss_tproxy/dnsmasq.d/*.conf</code></li>
<li><code>/opt/app/ss_tproxy/dnsmasq_conf_file.txt</code>中写上<code>no-resolv</code>和<code>server=127.0.0.1#8053</code>，假设你第三方 DNS 监听<code>8053</code>端口</li>
</ol></section><section><h4>无 ss_tproxy 的旧版固件<a href="#无-ss_tproxy-的旧版固件"><span>#</span></a></h4><p>可以使用 overture 代替 ChinaDNS</p><p>只建议可以使用内存卡或U盘的路由器来使用 overture，因为 overture 体积比较大无法保存在路由器闪存中</p><p>以下默认你已经将 overture 文件夹放置在<code>/media/AiCard_01/overture</code>，并且将可执行文件直接更名为<code>overture</code></p><p>注：<code>/media/AiCard_01</code>为外置储存路径</p></section><section><h4>1. 修改 overture 配置文件<a href="#1-修改-overture-配置文件"><span>#</span></a></h4><p>端口改为<code>8053</code>，和 ChinaDNS 的端口一致</p><p>IPNetworkFile 的 Primary 使用<code>/tmp/ss/chnroute.txt</code>
DomainFile 的 Alternative 使用<code>/tmp/ss/all_domain.txt</code></p><section><h5>2. 修改H大固件中的 ChinaDNS 脚本<a href="#2-修改h大固件中的-chinadns-脚本"><span>#</span></a></h5><p>脚本路径<code>/etc/storage/script/Sh19_chinadns.sh</code></p><div><div><div></div><div>Warning</div></div><div><p>请灵性修改，固件中的脚本在将来可能有变化因此我报的行数不一定是正确的，宗旨就是让 ChinaDNS 的启动和守护全换成 overture 的</p></div></div><p>找到 119 行的<code>chinadns_keep () {</code>，在后面插入新行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>chinadns_path</span><span>=</span><span>"/media/AiCard_01/overture/overture"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>找到 164 行，仿照这两句 killall，在后面加上两行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>killall</span><span> </span><span>overture</span></div></div><div><div><div>2</div></div><div><span>killall</span><span> </span><span>-9</span><span> </span><span>overture</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>将 198 行改为</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>chinadns_path</span><span>=</span><span>"/media/AiCard_01/overture/overture"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>将 221 行改为</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>eval</span><span> </span><span>"</span><span>$chinadns_path</span><span> -c /media/AiCard_01/overture/config.json"</span><span> &amp;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>改完记得<code>mtd_storage.sh save</code>，并且将修改后的脚本备份一份，以免更新固件后脚本被换回原版还得重改累得半死</p><p>接着就可以设置酸酸“DNS 服务模式选择”为<code>dnsmasq</code>了，固件会使用我们改好的 ChinaDNS 脚本启动 overture</p></section></section></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/dns-lock/</id>
      <title type="text">小众软件#8 [Dns Lock] ん？听说你这流氓软件要改我DNS？</title>
      <published>2018-10-15T07:48:00.000Z</published>
      <updated>2018-10-16T06:28:46.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/dns-lock/"/>
      <summary type="text">我校校园网用的是 Drcom 的认证系统，而学校提供的“专用”客户端会私自更改你的 DNS，真的是从未见过如此厚颜无耻之运营商 (╯°Д°)╯︵ ┻━┻</summary>
      <content type="html"><![CDATA[<p>我校校园网用的是 Drcom 的认证系统，而学校提供的“专用”客户端会私自更改你的 DNS，真的是从未见过如此厚颜无耻之运营商 (╯°Д°)╯︵ ┻━┻</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=71129109" target="_blank">「夏の日」/「雨雫@お仕事募集中」のイラスト [pixiv]</a></p>
<hr />
<p>直到写这篇文章以前，我都是拿哆点官方的客户端来认证校园网，结果现在学校流氓到只接受学校“专用”客户端的认证，无奈之下找来了这个软件</p>
<p></p><figure><img src="/usr/uploads/2018/10/58135091.png" alt="主界面" /><figcaption>主界面</figcaption></figure><p></p>
<p>这是一款以系统服务的方式来保护你的 DNS 不被其他应用篡改的轻巧软件，同时也支持 IPv6 的 DNS，支持从 Windows Xp 到 Windows 10 的所有32/64位系统</p>
<p><a href="https://www.sordum.org/9432/" target="_blank">Dns Lock</a></p>
<section><h2>使用<a href="#使用"><span>#</span></a></h2><p><img src="/usr/uploads/2018/10/267091273.png" alt="" /></p><p>只需要输入 DNS，多个以半角逗号隔开然后“Install Service”即可，想取消锁定就“Uninstall Service”</p><div><div><div></div><div>Warning</div></div><div><p>系统的 DNS 设置由于有主备两个，如果你在该程序中只填入一个 DNS，那么备 DNS 会自动被设置为该网卡的 IP（即本机）而不会留空，并且也不会锁定，这算是比较莫名其妙和沙雕的一点</p></div></div></section>
<section><h2>附言<a href="#附言"><span>#</span></a></h2><p>该软件的开发团队 <a href="https://www.sordum.org/" target="_blank">sordum</a> 十分有意思，有许许多多有用的小软件，感兴趣可以翻翻（</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/bilibili-orig-img/</id>
      <title type="text">[Bilibili] 使新版动态图片能够查看原图</title>
      <published>2018-09-18T05:02:00.000Z</published>
      <updated>2018-09-18T06:28:23.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/bilibili-orig-img/"/>
      <summary type="text">因为经常想跟小伙伴分享某些哔哩哔哩动态里的图片，但在查看大图中并不能右击复制，可每次都F12也十分麻烦，因此干脆写了个油猴脚本</summary>
      <content type="html"><![CDATA[<p>因为经常想跟小伙伴分享某些哔哩哔哩动态里的图片，但在查看大图中并不能右击复制，可每次都F12也十分麻烦，因此干脆写了个油猴脚本</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=70675670" target="_blank">「Rabit」/「ギザン@お仕事募集中」のイラスト [pixiv]</a></p>
<hr />
<p><a href="https://greasyfork.org/zh-CN/scripts/372289" target="_blank">Bilibili 哔哩哔哩动态查看原图</a></p>
<p><img src="https://i.loli.net/2018/09/18/5b9fd998094b0.png" alt="" /></p>
<section><h2>原理<a href="#原理"><span>#</span></a></h2><p>其实这部分就是原图</p><p><img src="/usr/uploads/2018/09/2689891326.png" alt="" /></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/emoji/</id>
      <title type="text">Emoji 的处理 - 使用正则表达式匹配所有 Emoji</title>
      <published>2018-09-14T06:43:00.000Z</published>
      <updated>2018-09-18T06:40:10.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/emoji/"/>
      <summary type="text">看来以后我还是把默认搜索引擎设成谷歌好了，百度根本没有前途，除了没被墙这个优点（</summary>
      <content type="html"><![CDATA[<p>看来以后我还是把默认搜索引擎设成谷歌好了，百度根本没有前途，除了没被墙这个优点（</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=70682785" target="_blank">「逆転の一撃」/「猫屋(NEKOYA)」のイラスト [pixiv]</a></p>
<hr />
<p>在写QQ机器人的时候遇到了 emoji 需要过滤的问题，而百度来百度去看到的文章基本都是老旧的，没有完整给出 emoji 的 Unicode 范围</p>
<p>今日才终于从 segmentfault 上找到了一篇专门讲解 emoji 的文章，学到了很多，也解决了问题</p>
<p><a href="https://segmentfault.com/a/1190000007594620" target="_blank">Emoji的编码以及常见问题处理</a></p>
<section><h2>正则表达式匹配<a href="#正则表达式匹配"><span>#</span></a></h2><p>如果需要用正则表达式匹配所有 emoji 的话，目前可以使用</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>/(</span><span>\ud83c[\udf00-\udfff]</span><span><span>)</span><span>|</span><span>(</span></span><span>\ud83d[\udc00-\ude4f\ude80-\udeff]</span><span><span>)</span><span>|</span></span><span>[\u2600-\u2B55]</span><span>/</span><span>g</span><span>;</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/vultr-vps/</id>
      <title type="text">[Vultr] 推出3.5刀有IPv4的套餐 支持支付宝Paypal IPv6 1Gbps 免费快照 小时计费 高性价比 日本/洛杉矶/新加坡</title>
      <published>2018-08-28T02:46:00.000Z</published>
      <updated>2023-12-13T16:10:16.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/vultr-vps/"/>
      <summary type="text">Vultr 应该算是比较著名的 VPS 主机供应商之一了，其特点之一就是注册无门槛，不要信用卡，价格低廉并且是按小时计费，想要服务器就加，不想要就直接删除，而且还支持支付宝付款，可以说是十分亲民了。</summary>
      <content type="html"><![CDATA[<p>Vultr 应该算是比较著名的 VPS 主机供应商之一了，其特点之一就是注册无门槛，不要信用卡，价格低廉并且是按小时计费，想要服务器就加，不想要就直接删除，而且还支持支付宝付款，可以说是十分亲民了。</p>
<hr />
<section><h2>活动<a href="#活动"><span>#</span></a></h2><p>目前有新用户通过<a href="https://www.vultr.com/?ref=9571970-8H" target="_blank">邀请链接</a>注册送$100的活动</p></section>
<section><h2>基本介绍<a href="#基本介绍"><span>#</span></a></h2><p>有 IPv4 的套餐最低配置$3.5/月
另有$2.5/月的 IPv6 Only（无 IPv4，如不清楚请不要购买）</p><p><a href="https://www.vultr.com/?ref=7200579" target="_blank">Vultr 官网</a></p></section>
<section><h2>服务器创建<a href="#服务器创建"><span>#</span></a></h2><section><h3>机房地址<a href="#机房地址"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/915131872.jpg" alt="Vultr机房地址" /><figcaption>Vultr机房地址</figcaption></figure>
目前一共有15个机房地址，看图一目了然。但是比较推荐的只有日本东京(Tokyo)、美国洛杉矶(Los Angeles)、美国西雅图(Seattle)，这三个机房线路对国内比较友好。首推还是日本。<p></p></section><section><h3>服务器系统<a href="#服务器系统"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/1173089616.jpg" alt="Vultr服务器系统" /><figcaption>Vultr服务器系统</figcaption></figure>
基本上目前有的服务器系统都能选，并且十分贴心的给出了所有系统的历史版本供你选择；你还可以上传自己的系统安装镜像，也可以从你已有的备份和快照中直接恢复。
顺带一提，Vultr拍摄快照是免费的！免费的！免费的！<p></p></section><section><h3>套餐<a href="#套餐"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/2884235515.jpg" alt="Vultr服务器套餐" /><figcaption>Vultr服务器套餐</figcaption></figure>
这个也不用多说，看图自知。最便宜的$2.5每月的套餐目前（2017-09-24）只有迈阿密和纽约才有。
另外，Vultr可以让你免费创建一个50GB的块储存空间，但是免费的储存空间仅限纽约机房使用。不推荐为了这50GB的空间而去购买纽约机房，在高峰期Ping实在是高的无法忍受。<p></p></section><section><h3>自定义设置<a href="#自定义设置"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/3868643560.jpg" alt="Vultr自定义设置" /><figcaption>Vultr自定义设置</figcaption></figure>
Vultr所有机房都是支持IPv6的，这点十分赞，不像某瓦工（逃）。你也可以增加私有IP，在VPS创建完毕后还可以添加公有IP，另外还提供定时备份以及防DDOS的服务，不过这些都需要额外的お金。
剩下的自定义安装脚本、SSH私匙等设置几乎是每个VPS商的标配设置了。<p></p></section></section>
<section><h2>服务器使用<a href="#服务器使用"><span>#</span></a></h2><section><h3>自带控制台<a href="#自带控制台"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/1751683365.jpg" alt="Vultr Console" /><figcaption>Vultr Console</figcaption></figure>
使用起来还是很方便的，响应速度要比自己用SSH连接要快，不过缺点是不能复制，所以我还是倾向于用自己的SSH客户端。<p></p></section><section><h3>自带监控<a href="#自带监控"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/414691326.jpg" alt="Vultr Usage Graphs" /><figcaption>Vultr Usage Graphs</figcaption></figure>
带有月流量使用监控十分赞，而且可以在Setting中设置流量预警。剩下的就是CPU使用情况、磁盘IO情况、网络使用情况。<p></p></section><section><h3>设置<a href="#设置"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/1335243786.jpg" alt="Vultr Setting" /><figcaption>Vultr Setting</figcaption></figure>
你可以管理公有/私有IP、定义防火墙规则、自定义系统安装镜像、更改主机名、更改服务器方案、更改系统。并且一些需要你在系统中手动设置的地方都会有教程以及配置示例。<p></p></section></section>
<section><h2>测速<a href="#测速"><span>#</span></a></h2><p><a href="https://www.vultr.com/faq/" target="_blank">这里是官方的机房测速地址</a>，打开以后拉到最下面就会有所有机房的测速文件以供下载测速，IPv4以及IPv6都有。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/pxder/</id>
      <title type="text">[Pxder] Pixiv 插画下载器</title>
      <published>2018-08-24T08:45:00.000Z</published>
      <updated>2021-02-12T09:31:46.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/pxder/"/>
      <summary type="text">可按根据指定画师 UID 解析并下载插画（包括动图）、一键下载所有你关注的画师的插画或收藏的插画、智能增量更新下载过的画师的插画。 多线程下载，并且支持使用 HTTP 与 SOCKS 代理。</summary>
      <content type="html"><![CDATA[<p>可按根据指定画师 UID 解析并下载插画（包括动图）、一键下载所有你关注的画师的插画或收藏的插画、智能增量更新下载过的画师的插画。</p>
<p>多线程下载，并且支持使用 HTTP 与 SOCKS 代理。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=70317711" target="_blank">「五河琴里」/「秋原ノゾミ Sheila」のイラスト [pixiv]</a></p>
<hr />
<blockquote><p>由于 Pixiv 已不再支持客户端的登录 API，请更新到 v2.12.0 及以后的版本以使用新的登录方式</p></blockquote>
<p></p><figure><img src="https://i.loli.net/2018/08/20/5b7aaccfb1c4a.gif" alt="运行示例" /><figcaption>运行示例</figcaption></figure><p></p>
<p>此项目基于 Node.js，姑且算自己学习的副产物~~（实际上是不务正业的产物~~</p>
<p>最大的缺点是没有 GUI，纯命令行操作，不过也并不难用~~（信我）~~</p>
<p>安装及使用等说明请直接看 Github 项目文档</p>
<a href="https://github.com/Tsuk1ko/pxder" target="_blank"><div><div><div><div></div><div>Tsuk1ko</div></div><div>/</div><div>pxder</div></div><div></div></div><div>🖼 Download illusts from pixiv.net P站插画批量下载器</div><div><div>—</div><div>—</div><div>GPL-3.0</div><span>JavaScript</span></div></a>
<section><h2>注意<a href="#注意"><span>#</span></a></h2><p>因P站域名遭到 GFW 的 SNI 阻断，这意味着只要你在大陆内，即便你改了 Hosts 也无法直接使用 pxder，<strong>请记得使用<code>pxder --setting</code>设置代理或启用直连模式</strong></p><p>从现在开始所有在评论中询问<strong>因未挂代理而产生的问题</strong>都将会被无视</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/pcap-dnsproxy-linux/</id>
      <title type="text">[Pcap DNSProxy] 无污染DNS搭建 linux下编译过程全记录</title>
      <published>2018-08-03T06:48:00.000Z</published>
      <updated>2019-11-02T15:09:34.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/pcap-dnsproxy-linux/"/>
      <summary type="text">Pcap DNSProxy 是一个基于 WinPcap/LibPcap 用于过滤 DNS 投毒污染的工具，提供便捷和强大的包含正则表达式的修改 Hosts 的方法，以及对 DNSCurve/DNSCrypt 协议、并行和 TCP 协议请求的支持。多服务器并行请求功能，更可提高在恶劣网络环境下域名解析的可靠性。</summary>
      <content type="html"><![CDATA[<p>Pcap DNSProxy 是一个基于 WinPcap/LibPcap 用于过滤 DNS 投毒污染的工具，提供便捷和强大的包含正则表达式的修改 Hosts 的方法，以及对 DNSCurve/DNSCrypt 协议、并行和 TCP 协议请求的支持。多服务器并行请求功能，更可提高在恶劣网络环境下域名解析的可靠性。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=69926395" target="_blank">「A sinner has no right of choice」/「Nahaki」のイラスト [pixiv]</a>
罪人没有选择的权利 #杀戮天使</p>
<hr />
<a href="https://github.com/Lyoko-Jeremie/Pcap_DNSProxy" target="_blank"><div><div><div><div></div><div>Lyoko-Jeremie</div></div><div>/</div><div>Pcap_DNSProxy</div></div><div></div></div><div>A Full Backup from https://github.com/chengr28/Pcap_DNSProxy</div><div><div>—</div><div>—</div><div>GPL-2.0</div><span>C++</span></div></a>
<p>(疑似原作者迫于某种压力删库，目前该链接为项目的备份)</p>
<p>本文主要记录下<strong>在 linux 上编译</strong> Pcap DNSProxy 的步骤和过程，以在国内 linux 服务器上搭建可用的无污染 DNS</p>
<p>注意，本文<strong>并非萌新向</strong>，并且对于这篇文章<strong>我不会回答任何与你编译时出错相关的问题</strong>（因为这程序编译要求真的很多，而且过程复杂，奇奇怪怪的问题也多），请自行运用百度谷歌解决，并且本文也包含了其中一些我遇到的问题的解决方法</p>
<p>如果你只想在自己的 Windows 电脑上使用 Pcap DNSProxy，那么无需阅读本文，直接查看 <a href="https://github.com/Lyoko-Jeremie/Pcap_DNSProxy/blob/master/Documents/ReadMe_Windows.zh-Hans.txt" target="_blank">作者给出的使用说明</a> 即可</p>
<p>MacOS 用户也需要自行编译，可以参考本文部分相关内容，以及 <a href="https://github.com/Lyoko-Jeremie/Pcap_DNSProxy/blob/master/Documents/ReadMe_macOS.zh-Hans.txt" target="_blank">作者给出的 MacOS 下的使用说明</a></p>
<section><h2>环境需求<a href="#环境需求"><span>#</span></a></h2><section><h3>源代码编译器<a href="#源代码编译器"><span>#</span></a></h3><p>必须完整支持 C++ 14 标准，可任选其一：</p><ul>
<li>GCC/g++ 最低版本要求为 5.0</li>
<li>Clang/LLVM 最低版本要求为 3.4</li>
</ul><p>此处以 GCC 举例</p><section><h4>GCC<a href="#gcc"><span>#</span></a></h4><p>使用<code>gcc -v</code>命令查看 gcc 版本，可到 <a href="http://ftp.gnu.org/gnu/gcc/" target="_blank">http://ftp.gnu.org/gnu/gcc/</a> 找到所有 gcc 对应版本的源码</p><div><div><div></div><div>Warning</div></div><div><p>编译需时超级久，可能要个把小时，建议使用<code>screen</code>以免中途断开 SSH 连接功亏一篑（。</p></div></div><p>安装示例：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr/src</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>http://ftp.gnu.org/gnu/gcc/gcc-8.2.0/gcc-8.2.0.tar.gz</span></div></div><div><div><div>3</div></div><div><span>tar</span><span> </span><span>zxvf</span><span> </span><span>gcc-8.2.0.tar.gz</span><span> &gt; </span><span>/dev/null</span></div></div><div><div><div>4</div></div><div><span>cd</span><span> </span><span>gcc-8.2.0</span></div></div><div><div><div>5</div></div><div><span>./configure</span><span> </span><span>--prefix=/usr</span><span> </span><span>--enable-checking=release</span><span> </span><span>--disable-multilib</span><span> (以及适当加上其他很多你使用 </span><span>gcc</span><span> </span><span>-v</span><span> </span><span>看到的编译选项</span><span>)</span></div></div><div><div><div>6</div></div><div><span>make</span><span> &amp;&amp; </span><span>make</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>GCC 依赖<a href="#gcc-依赖"><span>#</span></a></h4><p>configure 时可能会提示 GMP, MPFR, MPC 缺少或版本过低</p><p><strong>可以直接在 GCC 源码目录下执行<code>./contrib/download_prerequisites</code>来自动下载并解压依赖</strong>，不过因为我们搭建无污染 DNS 使用的是国内主机，下载通常十分龟速，因此你也可以在自己的电脑上使用代理或多线程下载工具之类的加速下载好依赖库源码然后放到<strong>源码根目录</strong>中再执行此命令，可直接跳过下载阶段</p><p>以下是所需四个依赖的下载地址：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>ftp://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2</span></div></div><div><div><div>2</div></div><div><span>ftp://gcc.gnu.org/pub/gcc/infrastructure/mpfr-3.1.4.tar.bz2</span></div></div><div><div><div>3</div></div><div><span>ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.0.3.tar.gz</span></div></div><div><div><div>4</div></div><div><span>ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.18.tar.bz2</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>CMake<a href="#cmake"><span>#</span></a></h3><p>使用<code>cmake --version</code>命令验证是否已安装，并且版本至少需要<code>3.1</code></p><p>可到 <a href="https://cmake.org" target="_blank">https://cmake.org</a> 查看最新版本下载地址</p><p>安装示例：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr/src</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>https://cmake.org/files/v3.12/cmake-3.12.0.tar.gz</span></div></div><div><div><div>3</div></div><div><span>tar</span><span> </span><span>zxvf</span><span> </span><span>cmake-3.12.0.tar.gz</span></div></div><div><div><div>4</div></div><div><span>cd</span><span> </span><span>cmake-3.12.0</span></div></div><div><div><div>5</div></div><div><span>./configure</span><span> </span><span>--prefix=/usr</span></div></div><div><div><div>6</div></div><div><span>gmake</span><span> &amp;&amp; </span><span>gmake</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>libevent<a href="#libevent"><span>#</span></a></h3><p>可到 <a href="http://libevent.org" target="_blank">http://libevent.org</a> 查看最新版本下载地址</p><p>安装示例：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr/src</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz</span></div></div><div><div><div>3</div></div><div><span>tar</span><span> </span><span>zxvf</span><span> </span><span>libevent-2.1.8-stable.tar.gz</span></div></div><div><div><div>4</div></div><div><span>cd</span><span> </span><span>libevent-2.1.8-stable</span></div></div><div><div><div>5</div></div><div><span>./configure</span><span> </span><span>--prefix=/usr</span></div></div><div><div><div>6</div></div><div><span>make</span><span> &amp;&amp; </span><span>make</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>libpcap<a href="#libpcap"><span>#</span></a></h3><p>可到 <a href="http://www.tcpdump.org/#latest-release" target="_blank">http://www.tcpdump.org/#latest-release</a> 查看最新版本下载地址</p><p>安装示例：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr/src</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>http://www.tcpdump.org/release/libpcap-1.9.0.tar.gz</span></div></div><div><div><div>3</div></div><div><span>tar</span><span> </span><span>zxvf</span><span> </span><span>libpcap-1.9.0.tar.gz</span></div></div><div><div><div>4</div></div><div><span>cd</span><span> </span><span>libpcap-1.9.0</span></div></div><div><div><div>5</div></div><div><span>./configure</span><span> </span><span>--prefix=/usr</span></div></div><div><div><div>6</div></div><div><span>make</span><span> &amp;&amp; </span><span>make</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果 configure 的时候提示<code>Neither flex nor lex was found.</code>错误，则</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Ubuntu / Debian</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>flex</span><span> </span><span>bison</span></div></div><div><div><div>3</div></div><div><span># CentOS</span></div></div><div><div><div>4</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>flex</span><span> </span><span>bison</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果遇到缺少<code>yacc</code>的错误，同上方一样安装<code>byacc</code>包即可</p></section><section><h3>libsodium<a href="#libsodium"><span>#</span></a></h3><p>可到 <a href="https://github.com/jedisct1/libsodium/releases" target="_blank">https://github.com/jedisct1/libsodium/releases</a> 查看最新版本下载地址</p><p>安装示例：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr/src</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>https://github.com/jedisct1/libsodium/releases/download/1.0.16/libsodium-1.0.16.tar.gz</span></div></div><div><div><div>3</div></div><div><span>tar</span><span> </span><span>zxvf</span><span> </span><span>libsodium-1.0.16.tar.gz</span></div></div><div><div><div>4</div></div><div><span>cd</span><span> </span><span>libsodium-1.0.16</span></div></div><div><div><div>5</div></div><div><span>./configure</span><span> </span><span>--prefix=/usr</span></div></div><div><div><div>6</div></div><div><span>make</span><span> &amp;&amp; </span><span>make</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>openssl<a href="#openssl"><span>#</span></a></h3><p>可用命令<code>openssl version -a</code>检查是否安装</p><div><div><div></div><div>Warning</div></div><div><p>如果出现已经安装了（系统本身自带）但是后续编译 DNSProxy 时有关于 openssl 的报错的话，你仍需要按照下方方法手动编译安装一次</p></div></div><p>安装示例：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr/src</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>https://www.openssl.org/source/openssl-1.1.0h.tar.gz</span></div></div><div><div><div>3</div></div><div><span>tar</span><span> </span><span>zxvf</span><span> </span><span>openssl-1.1.0h.tar.gz</span></div></div><div><div><div>4</div></div><div><span>cd</span><span> </span><span>openssl-1.1.0h</span></div></div><div><div><div>5</div></div><div><span>./config</span><span> </span><span>--prefix=/usr</span></div></div><div><div><div>6</div></div><div><span>make</span><span> &amp;&amp; </span><span>make</span><span> </span><span>install</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>部署 Pcap DNSProxy<a href="#部署-pcap-dnsproxy"><span>#</span></a></h2><section><h3>编译安装<a href="#编译安装"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr/src</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/Lyoko-Jeremie/Pcap_DNSProxy.git</span></div></div><div><div><div>3</div></div><div><span>cd</span><span> </span><span>Pcap_DNSProxy/Source/Auxiliary/Scripts</span></div></div><div><div><div>4</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>CMake_Build.sh</span></div></div><div><div><div>5</div></div><div><span>./CMake_Build.sh</span></div></div><div><div><div>6</div></div><div><span>cp</span><span> </span><span>-r</span><span> </span><span>/usr/src/Pcap_DNSProxy/Source/Release</span><span> </span><span>/usr/local/Pcap_DNSProxy</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这样 Pcap DNSProxy 将会位于<code>/usr/local/Pcap_DNSProxy</code></p></section><section><h3>修改配置<a href="#修改配置"><span>#</span></a></h3><p>首先进入 Pcap DNSProxy 软件目录</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr/local/Pcap_DNSProxy</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>编辑<code>Config.conf</code>，修改以下<strong>提到</strong>的<strong>部分</strong>配置内容
只是我个人推荐，你当然可以按照自己的意愿更改设置，请参考 <a href="https://github.com/Lyoko-Jeremie/Pcap_DNSProxy/blob/master/Documents/ReadMe.zh-Hans.txt" target="_blank">软件作者非常负责写的这个很长很长的配置文件说明文档</a></p><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>[Listen]</span></div></div><div><div><div>2</div></div><div><span>Operation</span><span> </span><span>Mode</span><span> </span><span>=</span><span> </span><span>Server</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>[DNS]</span></div></div><div><div><div>5</div></div><div><span>Outgoing</span><span> </span><span>Protocol</span><span> </span><span>=</span><span> </span><span>IPv4</span><span> </span><span>+</span><span> </span><span>TCP</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>[Addresses]</span></div></div><div><div><div>8</div></div><div><span>IPv4</span><span> </span><span>Main</span><span> </span><span>DNS</span><span> </span><span>Address</span><span> </span><span>=</span><span> </span><span>208.67.222.222:443</span></div></div><div><div><div>9</div></div><div><span>IPv4</span><span> </span><span>Alternate</span><span> </span><span>DNS</span><span> </span><span>Address</span><span> </span><span>=</span><span> </span><span>208.67.220.220:443</span><span>|</span><span>208.67.222.220:443</span><span>|</span><span>208.67.220.222:443</span></div></div><div><div><div>10</div></div><div><span>IPv4</span><span> </span><span>Local</span><span> </span><span>Main</span><span> </span><span>DNS</span><span> </span><span>Address</span><span> </span><span>=</span><span> </span><span>119.29.29.29:53</span></div></div><div><div><div>11</div></div><div><span>IPv4</span><span> </span><span>Local</span><span> </span><span>Alternate</span><span> </span><span>DNS</span><span> </span><span>Address</span><span> </span><span>=</span><span> </span><span>1.2.4.8:53</span><span>|</span><span>223.5.5.5:53</span><span>|</span><span>114.114.114.114:53</span></div></div><div><div><div>12</div></div><div><span>IPv6</span><span> </span><span>Main</span><span> </span><span>DNS</span><span> </span><span>Address</span><span> </span><span>=</span><span> [2620:0:CCC::2]:443</span></div></div><div><div><div>13</div></div><div><span>IPv6</span><span> </span><span>Alternate</span><span> </span><span>DNS</span><span> </span><span>Address</span><span> </span><span>=</span><span> [2620:0:CCD::2]:443</span></div></div><div><div><div>14</div></div><div><span>IPv6</span><span> </span><span>Local</span><span> </span><span>Main</span><span> </span><span>DNS</span><span> </span><span>Address</span><span> </span><span>=</span><span> [240c::6666]:53</span></div></div><div><div><div>15</div></div><div><span>IPv6</span><span> </span><span>Local</span><span> </span><span>Alternate</span><span> </span><span>DNS</span><span> </span><span>Address</span><span> </span><span>=</span><span> [240c::6644]:53</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>[Switches]</span></div></div><div><div><div>18</div></div><div><span>Domain</span><span> </span><span>Case</span><span> </span><span>Conversion</span><span> </span><span>=</span><span> </span><span>0</span></div></div><div><div><div>19</div></div><div><span>EDNS</span><span> </span><span>Label</span><span> </span><span>=</span><span> </span><span>1</span></div></div><div><div><div>20</div></div><div><span>EDNS</span><span> </span><span>Client</span><span> </span><span>Subnet</span><span> </span><span>Relay</span><span> </span><span>=</span><span> </span><span>1</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>部分解释：</p><ul>
<li>Listen
<ul>
<li>Operation Mode 为<code>Server</code>时才能允许外网设备</li>
</ul>
</li>
<li>DNS
<ul>
<li>通过 TCP 使用 OpenDNS 避免 UDP 有时因被 QoS 而无法查询</li>
</ul>
</li>
<li>Addresses
<ul>
<li>对于国外域名使用 OpenDNS</li>
<li>对于国内域名使用 DNSPod &gt; CNNIC | 阿里 | 114</li>
</ul>
</li>
<li>Switches
<ul>
<li>关闭域名随机大小写转换（因为目前实际上没什么必要</li>
<li>开启 EDNS</li>
</ul>
</li>
</ul></section><section><h3>注册系统服务<a href="#注册系统服务"><span>#</span></a></h3><section><h4>如果你的系统支持使用<code>systemctl</code>控制服务<a href="#如果你的系统支持使用systemctl控制服务"><span>#</span></a></h4><p>编辑<code>Pcap_DNSProxy.service</code>文件：
<code>ExecStart=</code>程序所在目录的绝对路径，并在最后加上程序的名称
<code>WorkingDirectory=</code>程序所在目录的绝对路径</p><p>例如：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ExecStart</span><span>=</span><span>/usr/local/Pcap_DNSProxy/Pcap_DNSProxy</span></div></div><div><div><div>2</div></div><div><span>WorkingDirectory</span><span>=</span><span>/usr/local/Pcap_DNSProxy</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后执行<code>./Linux_Install.Systemd.sh</code>即可安装服务，服务会自动启动</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 服务控制</span></div></div><div><div><div>2</div></div><div><span>systemctl</span><span> </span><span>start</span><span>|</span><span>stop</span><span>|</span><span>restart</span><span>|</span><span>status</span><span> </span><span>Pcap_DNSProxy.service</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>如果你的系统只支持使用<code>service</code>控制服务<a href="#如果你的系统只支持使用service控制服务"><span>#</span></a></h4><p>编辑<code>PcapDNSProxyService</code>文件：
<code>NAME=</code>程序的名称
<code>PATH=</code>程序的绝对路径</p><p>例如：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>NAME</span><span>=</span><span>Pcap_DNSProxy</span></div></div><div><div><div>2</div></div><div><span>PATH</span><span>=</span><span>/usr/local/Pcap_DNSProxy</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后执行<code>./Linux_Install.SysV.sh</code>即可安装服务，服务会自动启动</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 服务控制</span></div></div><div><div><div>2</div></div><div><span>service</span><span> </span><span>Pcap_DNSProxy</span><span> </span><span>start</span><span>|</span><span>stop</span><span>|</span><span>restart</span><span>|</span><span>status</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h2>Enjoy<a href="#enjoy"><span>#</span></a></h2><p>将你的计算机的 DNS 设置为你服务器的 DNS</p><p>服务器记得配置防火墙（或/且安全组）开放<code>53</code>端口，如果你不懂请自行百度</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/linux-reinstall-vicer/</id>
      <title type="text">[Linux] 网络脚本一键重装 Ubuntu/CentOS/Debian</title>
      <published>2018-07-31T07:16:00.000Z</published>
      <updated>2019-05-23T05:39:55.000Z</updated>
      <author><name>Vicer</name></author>
      <link rel="alternate" href="https://moe.best/posts/linux-reinstall-vicer/"/>
      <summary type="text">【更新：补充重装成 CentOS 7 的方法】 适用于由 GRUB 引导的系统，使用官方发行版去掉模板预装的软件，同时也可以解决内核版本与软件不兼容的问题。 只要有 root 权限，还您一个纯净的系统。</summary>
      <content type="html"><![CDATA[<p>【更新：补充重装成 CentOS 7 的方法】</p>
<p>适用于由 GRUB 引导的系统，使用官方发行版去掉模板预装的软件，同时也可以解决内核版本与软件不兼容的问题。
只要有 root 权限，还您一个纯净的系统。</p>
<p>转载自萌咖，原文在文章底部版权声明处</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=54793778" target="_blank">「★」/「しろゆき」のイラスト [pixiv]</a></p>
<section><h1>网络重装 Ubuntu/CentOS/Debian 一键脚本<a href="#网络重装-ubuntucentosdebian-一键脚本"><span>#</span></a></h1><ul>
<li>能够全自动重装 Debian/Ubuntu/CentOS 等系统</li>
<li>同时提供dd安装镜像功能，例如：全自动无救援dd安装windows系统</li>
<li>全自动安装 CentOS 时默认提供 VNC 功能，可使用 VNC Viewer 查看进度，VNC 端口为<code>1</code>或者<code>5901</code>，可自行尝试连接(成功后 VNC 功能会消失)</li>
<li>目前 CentOS 系统只支持任意版本重装为 CentOS 6.9 及以下版本（欲重装成 CentOS 7 请看后续补充内容）</li>
</ul><div><div><div></div><div>Warning</div></div><div><p>全自动安装模式的默认 root 密码为<code>MoeClub.org</code>，安装完成后请立即使用<code>passwd</code>命令更改密码。</p></div></div><div><div><div></div><div>Caution</div></div><div><p>此脚本<b>不能用于</b> OpenVZ 虚拟化的机子！</p></div></div><section><h2>准备<a href="#准备"><span>#</span></a></h2><section><h3>确保安装了脚本所需软件<a href="#确保安装了脚本所需软件"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#Debian/Ubuntu:</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>xz-utils</span><span> </span><span>openssl</span><span> </span><span>gawk</span><span> </span><span>file</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>#RedHat/CentOS:</span></div></div><div><div><div>5</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>xz</span><span> </span><span>openssl</span><span> </span><span>gawk</span><span> </span><span>file</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果报错，请运行下面的命令后再试</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#Debian/Ubuntu:</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>update</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>#RedHat/CentOS:</span></div></div><div><div><div>5</div></div><div><span>yum</span><span> </span><span>update</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>下载一键脚本<a href="#下载一键脚本"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>-qO</span><span> </span><span>InstallNET.sh</span><span> </span><span>'https://moeclub.org/attachment/LinuxShell/InstallNET.sh'</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>a+x</span><span> </span><span>InstallNET.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后根据你需要重装到的系统和下文给出的说明执行对应命令即可。</p><p>重装过程需要10~30分钟，请耐心等待。</p></section></section><section><h2>使用<a href="#使用"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>Usage:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>bash</span><span> </span><span>InstallNET.sh</span><span>    </span><span>-d/--debian</span><span> [dist-name]</span></div></div><div><div><div>3</div></div><div><span>              </span><span>-u/--ubuntu</span><span> [dist-name]</span></div></div><div><div><div>4</div></div><div><span>              </span><span>-c/--centos</span><span> [dist-version]</span></div></div><div><div><div>5</div></div><div><span>              </span><span>-v/--ver</span><span> [32/i386|</span><span>64/amd64]</span></div></div><div><div><div>6</div></div><div><span>              </span><span>--ip-addr/--ip-gate/--ip-mask</span></div></div><div><div><div>7</div></div><div><span>              </span><span>-apt/-yum/--mirror</span></div></div><div><div><div>8</div></div><div><span>              </span><span>-dd/--image</span></div></div><div><div><div>9</div></div><div><span>              </span><span>-a/-m</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># dist-name：发行版本代号</span></div></div><div><div><div>12</div></div><div><span># dist-version：发行版本号</span></div></div><div><div><div>13</div></div><div><span># -apt/-yum/--mirror：使用定义镜像</span></div></div><div><div><div>14</div></div><div><span># -a/-m：询问是否能进入VNC自行操作。-a 为不提示(一般用于全自动安装)，-m 为提示。</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h3>示例<a href="#示例"><span>#</span></a></h3><section><h4>一般<a href="#一般"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#使用默认镜像全自动安装 Debian 8 x64</span></div></div><div><div><div>2</div></div><div><span>bash</span><span> </span><span>InstallNET.sh</span><span> </span><span>-d</span><span> </span><span>8</span><span> </span><span>-v</span><span> </span><span>64</span><span> </span><span>-a</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>#使用自定义镜像全自动安装 CentOS 6.9 x64</span></div></div><div><div><div>5</div></div><div><span>bash</span><span> </span><span>InstallNET.sh</span><span> </span><span>-c</span><span> </span><span>6.9</span><span> </span><span>-v</span><span> </span><span>64</span><span> </span><span>-a</span><span> </span><span>--mirror</span><span> </span><span>'http://mirror.centos.org/centos'</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>进阶<a href="#进阶"><span>#</span></a></h4><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 以下示例中,将X.X.X.X替换为自己的网络参数.</span></div></div><div><div><div>2</div></div><div><span>--ip-addr</span><span> </span><span>x.x.x.x</span><span>  </span><span>#IP地址</span></div></div><div><div><div>3</div></div><div><span>--ip-gate</span><span> </span><span>x.x.x.x</span><span>  </span><span>#网关</span></div></div><div><div><div>4</div></div><div><span>--ip-mask</span><span> </span><span>x.x.x.x</span><span>  </span><span>#子网掩码</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>#使用自定义镜像自定义网络参数全自动安装</span></div></div><div><div><div>7</div></div><div><span>bash</span><span> </span><span>InstallNET.sh</span><span> </span><span>-u</span><span> </span><span>16.04</span><span> </span><span>-v</span><span> </span><span>64</span><span> </span><span>-a</span><span> </span><span>--ip-addr</span><span> </span><span>x.x.x.x</span><span> </span><span>--ip-gate</span><span> </span><span>x.x.x.x</span><span> </span><span>--ip-mask</span><span> </span><span>x.x.x.x</span><span> </span><span>--mirror</span><span> </span><span>'http://archive.ubuntu.com/ubuntu'</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>#使用自定义网络参数全自动dd方式安装</span></div></div><div><div><div>10</div></div><div><span>bash</span><span> </span><span>InstallNET.sh</span><span> </span><span>--ip-addr</span><span> </span><span>x.x.x.x</span><span> </span><span>--ip-gate</span><span> </span><span>x.x.x.x</span><span> </span><span>--ip-mask</span><span> </span><span>x.x.x.x</span><span> </span><span>-dd</span><span> </span><span>'https://moeclub.org/get-win7embx86-auto'</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>#使用自定义网络参数全自动dd方式安装存储在谷歌网盘中的镜像(调用文件ID的方式)</span></div></div><div><div><div>13</div></div><div><span>bash</span><span> </span><span>InstallNET.sh</span><span> </span><span>--ip-addr</span><span> </span><span>x.x.x.x</span><span> </span><span>--ip-gate</span><span> </span><span>x.x.x.x</span><span> </span><span>--ip-mask</span><span> </span><span>x.x.x.x</span><span> </span><span>-dd</span><span> </span><span>"$(</span><span>echo</span><span> "11fr_LcgY_qSEDbWvBel0S0fjYAX_lKL0" </span><span>|</span><span>xargs</span><span> </span><span>-n1</span><span> bash &lt;(</span><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>-qO-</span><span> 'https://moeclub.org/get-gdlink'))"</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>#使用自定义网络参数全自动dd方式安装存储在谷歌网盘中的镜像</span></div></div><div><div><div>16</div></div><div><span>bash</span><span> </span><span>InstallNET.sh</span><span> </span><span>--ip-addr</span><span> </span><span>x.x.x.x</span><span> </span><span>--ip-gate</span><span> </span><span>x.x.x.x</span><span> </span><span>--ip-mask</span><span> </span><span>x.x.x.x</span><span> </span><span>-dd</span><span> </span><span>"$(</span><span>echo</span><span> "https://drive.google.com/open?id=11fr_LcgY_qSEDbWvBel0S0fjYAX_lKL0" </span><span>|</span><span>xargs</span><span> </span><span>-n1</span><span> bash &lt;(</span><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>-qO-</span><span> 'https://moeclub.org/get-gdlink'))"</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section></section><section><h2>注意<a href="#注意"><span>#</span></a></h2><p><strong>在 VNC 手动安装 Ubuntu 时，可能会遇到:</strong>
<code>Getting the time form a network time server...</code>
界面进度条很长时间不会动，可以等待它超时或者更换别的版本
该问题是Ubuntu系统的问题</p><p><strong>在全自动安装CentOS时：</strong>
如果看到“Starting graphical installation”或者类似表达，则表示正在安装
正常情况下只需要耐心等待安装完成即可
如果需要查看进度，使用 VNC Viewer（或者其他 VNC 连接工具）
连接提示中的<code>IP地址:端口</code>进行连接（端口一般为<code>1</code>或者<code>5901</code>）</p></section></section>
<section><h1>【补充】如何重装成 CentOS 7<a href="#补充如何重装成-centos-7"><span>#</span></a></h1><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>-qO</span><span> </span><span>~/Network-Reinstall-System-Modify.sh</span><span> </span><span>'https://tech.cxthhhhh.com/tech-tools/Network-Reinstall-System-Modify/Network-Reinstall-System-Modify.sh'</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>a+x</span><span> </span><span>~/Network-Reinstall-System-Modify.sh</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>~/Network-Reinstall-System-Modify.sh</span><span> </span><span>-CentOS_7</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h2>使用此方法须知<a href="#使用此方法须知"><span>#</span></a></h2><ol>
<li>root 密码为<code>cxthhhhh.com</code></li>
<li>安装需耗时 15-45 分钟，并且系统首次启动后，请等待自动安装完成，系统将自动重启，然后才能使用（安装过程中的手动干预可能会导致错误）<strong>【一句话：耐心等就完事了（。】</strong></li>
<li>IPv4 和 IPv6 为 <strong>DHCP</strong> 获取 IP 的模式（如果用在必须手动指定 IP 信息的机器上，你也许需要使用 VNC 修改网络配置，或者使用 VPS 面板的“重置网络配置”，如果有的话）</li>
<li>系统 DNS 为<code>1.1.1.1</code>和<code>8.8.8.8</code></li>
<li>系统使用官方 CentOS 镜像</li>
<li>登录信息标准化，易于管理，您需要在登录后修改它</li>
<li>默认分配磁盘大小为 4.5G，你需要扩展磁盘（请看下方）</li>
</ol><p>方法来源：<a href="https://tech.cxthhhhh.com/linux/2018/07/31/original-network-one-click-reinstall-centos-7-official-pure-safe-efficient-cn.html" target="_blank">【Technical Blog | 技術博客】[原创] 一键网络重装CentOS 7 （官方，纯净，安全，高效）</a></p></section><section><h2>磁盘扩容<a href="#磁盘扩容"><span>#</span></a></h2><p>Vicer 的脚本声明不支持自动安装 CentOS 7 的原因是 7 只能使用<code>grub2</code>引导，与我们常见的其他系统的<code>grub</code>不同</p><p>而此方法是直接使用<code>dd</code>镜像的方式安装，即实际上是直接拿一个装有 CentOS 7 的磁盘镜像来覆写硬盘（与<code>dd</code>安装 Win 同理），解决了这个问题</p><p>由于分区表也会被覆写，因此安装完成后你会发现硬盘分区大小小于原本的大小，只需使用<code>fdisk</code>修改分区大小扩容即可</p><p>可以参考：<a href="https://tech.cxthhhhh.com/linux/2018/07/30/original-how-to-expand-linux-hard-disk-lvm-disk-en.html" target="_blank">如何扩展 Linux 硬盘</a>，或者自行百度<code>fdisk</code>的用法</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/bandzip/</id>
      <title type="text">小众软件#7 [Bandizip] 把2345卸了吧 试试这个 没有广告</title>
      <published>2018-07-16T13:18:00.000Z</published>
      <updated>2020-04-18T05:00:09.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/bandzip/"/>
      <summary type="text">超清爽的界面，没有烦人的广告，比起其它许多压缩软件他还有很多人性化的功能</summary>
      <content type="html"><![CDATA[<p>超清爽的界面，没有烦人的广告，比起其它许多压缩软件他还有很多人性化的功能</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=69688795" target="_blank">「「貴方と一緒に天の川を」」/「狐宮しろね」のイラスト [pixiv]</a></p>
<hr />
<p><a href="https://www.bandisoft.com/bandizip/" target="_blank">Bandizip 官网</a></p>
<p>不知道你看着这个软件名会不会有点亲切感（</p>
<p>开发这个软件的公司叫 Bandisoft，是一家挺低调的韩国软件公司，正是知名录屏软件 Bandicam 的初开发公司（后来由 Bandicam 公司接手开发）</p>
<p>注：Bandizip 7.0 开始有广告，请下载 <a href="https://www.bandisoft.com/bandizip/old/6/" target="_blank">6.x</a> 版本</p>
<section><h2>软件界面<a href="#软件界面"><span>#</span></a></h2><p>是真的很爽√</p><p><img src="/usr/uploads/2018/07/2737523312.png" alt="" /></p><p><img src="/usr/uploads/2018/07/193893565.png" alt="" /></p></section>
<section><h2>特色功能<a href="#特色功能"><span>#</span></a></h2><p>主要的功能该有的都有，你们可以在官网上看到简要的介绍，这里主要讲一些我很喜欢的，与其他常见压缩软件有别的人性化设计：</p><ol>
<li><strong>压缩文件内容预览</strong>
<img src="/usr/uploads/2018/07/2654171019.png" alt="" /></li>
<li><strong>自动解压</strong>
<img src="/usr/uploads/2018/07/2352897546.png" alt="" />
这里有叫“自动解压”或“智能解压”，解压单个或多个压缩包都能使用，其实是同一个效果功能，不必纠结。
其智能是智能在，如果压缩包根目录下里只有单个文件/文件夹，则直接解压到当前目录；而如果压缩包根目录下有多个文件/文件夹，则会将它们解压到一个单独的文件夹中。</li>
<li><strong>解压并删除原始文件</strong>
不解释，我这样的懒人是很中意这种功能的</li>
</ol></section>
<section><h2>友情提示<a href="#友情提示"><span>#</span></a></h2><p>根据我们平时的使用习惯，建议在设置中关闭“只压缩单个文件夹时不要创建根文件夹”</p><p><img src="/usr/uploads/2018/07/2902732154.png" alt="" /></p><p>是的，这个功能应该可以叫做“智能压缩”吧23333
不过并不符合我们的使用习惯（大概，至少我是</p></section>
<section><h2>另外推荐<a href="#另外推荐"><span>#</span></a></h2><p>Bandisoft 家的软件都挺不错的，清爽，人性化，功能全</p><p>同时也推荐他家的 Honeyview 图片查看器，装了他和 Bandizip 之后我就卸了2345好压和看图王，现在使用体验良好</p><p>P.S. 在我卸载2345看图王的时候，卸载程序居然有个选项是“我不弹广告了，不要卸载我好不好”，真是不见棺材不落泪的典范</p><p>然后我按下了卸载键</p><p><img src="/usr/uploads/2018/07/1198641720.gif" alt="" /></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/shuoshuo-auto-delete/</id>
      <title type="text">[QQ空间] 自动批量删除所有说说</title>
      <published>2018-07-05T08:59:00.000Z</published>
      <updated>2018-07-05T09:01:56.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/shuoshuo-auto-delete/"/>
      <summary type="text">rt，因为发现说说之前有很多自己的黑历史，而且QQ空间虽然有个封存功能但总归还是不放心，彻底删除是最放心的方法。 这个方法不需要第三方软件，仅仅依靠 F12 的 Console 执行 js 来循环实现删除。</summary>
      <content type="html"><![CDATA[<p>rt，因为发现说说之前有很多自己的黑历史，而且QQ空间虽然有个封存功能但总归还是不放心，彻底删除是最放心的方法。
这个方法不需要第三方软件，仅仅依靠 F12 的 Console 执行 js 来循环实现删除。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=69461006" target="_blank">「The Blue Crown」/「アシマ」のイラスト [pixiv]</a></p>
<hr />
<section><h2>方法<a href="#方法"><span>#</span></a></h2><p>首先打开说说页面，按下<code>F12</code>打开开发者工具，上方切换到 Console 选项卡，然后粘贴以下代码并回车执行</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>setInterval</span><span>(</span><span>function</span><span> () {</span></div></div><div><div><div>2</div></div><div><span>  </span><span>var</span><span><span> </span><span>childIframeArr</span><span> </span></span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>getElementsByTagName</span><span>(</span><span>"iframe"</span><span>);</span></div></div><div><div><div>3</div></div><div><span>  </span><span>var</span><span><span> </span><span>newDocument</span><span> </span></span><span>=</span><span><span> </span><span>childIframeArr</span><span>[</span></span><span>0</span><span>].</span><span>contentWindow</span><span>.</span><span>document</span><span>;</span></div></div><div><div><div>4</div></div><div><span>  </span><span>var</span><span><span> </span><span>del</span><span> </span></span><span>=</span><span><span> </span><span>newDocument</span><span>.</span></span><span>getElementsByClassName</span><span>(</span><span>"del del_btn author_display"</span><span>);</span></div></div><div><div><div>5</div></div><div><span>  </span><span>if</span><span><span> (</span><span>del</span><span>.</span></span><span>length</span><span> </span><span>&gt;</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>del</span><span>[</span><span>0</span><span>].</span><span>click</span><span>();</span></div></div><div><div><div>7</div></div><div><span>    </span><span>setTimeout</span><span>(</span><span>function</span><span> () {</span></div></div><div><div><div>8</div></div><div><span>      </span><span>var</span><span><span> </span><span>del_yes</span><span> </span></span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>getElementsByClassName</span><span>(</span></div></div><div><div><div>9</div></div><div><span>        </span><span>"qz_dialog_layer_btn qz_dialog_layer_sub"</span><span>,</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>);</span></div></div><div><div><div>11</div></div><div><span>      </span><span>if</span><span><span> (</span><span>del_yes</span><span>.</span></span><span>length</span><span> </span><span>&gt;</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>12</div></div><div><span><span>        </span></span><span>del_yes</span><span>[</span><span>0</span><span>].</span><span>click</span><span>();</span></div></div><div><div><div>13</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>}, </span><span>1000</span><span>);</span></div></div><div><div><div>15</div></div><div><span><span>  </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>16</div></div><div><span>    </span><span>var</span><span><span> </span><span>pages</span><span> </span></span><span>=</span><span><span> </span><span>newDocument</span><span>.</span></span><span>getElementsByClassName</span><span>(</span><span>"mod_pagenav_main"</span><span>)[</span><span>0</span><span>];</span></div></div><div><div><div>17</div></div><div><span>    </span><span>var</span><span><span> </span><span>nextId</span><span> </span></span><span>=</span><span><span> </span><span>pages</span><span>.</span></span><span>lastChild</span><span>.</span><span>id</span><span>;</span></div></div><div><div><div>18</div></div><div><span><span>    </span></span><span>newDocument</span><span>.</span><span>getElementById</span><span><span>(</span><span>nextId</span><span>).</span></span><span>click</span><span>();</span></div></div><div><div><div>19</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>20</div></div><div><span>}, </span><span>5000</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>接着你的说说就会以5秒钟一条的速度被删除，并且删完当前页会自动换页，在后台挂着就行</p></section>
<section><h2>注意<a href="#注意"><span>#</span></a></h2><ol>
<li>默认从<strong>当前页第一条</strong>开始进行删除，因此如果你只需要删除部分说说，请先跳到你要开始删除的那一页再运行 js 语句</li>
<li>如果中途想停止删除可以直接关闭该标签页或者刷新页面</li>
<li>如果想加快删除速度，可以减小代码最后一行<code>5000</code>的值，单位是毫秒，不建议修改至低于<code>3000</code>，否则会容易出现对同一条说说提交数次删除请求的情况</li>
<li>如果你的说说数量大于<code>50</code>条，也不建议修改删除速度，删除过快容易引发验证码问题，js 无法解决，请等待半小时后再尝试继续删除（欲速则不达</li>
</ol></section>
<section><h2>感谢<a href="#感谢"><span>#</span></a></h2><p>此方法参考并修改自
<a href="https://greasyfork.org/zh-CN/scripts/31701" target="_blank">https://greasyfork.org/zh-CN/scripts/31701</a></p><p>主要是修正了删除频率过高导致重复提交删除请求的问题，并优化了执行逻辑，例如等待一定时间以保证删除确认框加载完毕再点击删除</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/chinadns-on-win/</id>
      <title type="text">[ChinaDNS] 无污染的智能路由 DNS 折腾记 #3</title>
      <published>2018-06-13T14:22:00.000Z</published>
      <updated>2018-06-30T11:26:51.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/chinadns-on-win/"/>
      <summary type="text">没想到这个系列还能有第三集，应该是完结篇了。这次是因为前不久试用了一下 Linux 的 Windows 子系统，发现意外的不错，与 Windows 本身契合度很高，于是在 Windows 里跑 DNSMasq + ChinaDNS 的设想得以实现√</summary>
      <content type="html"><![CDATA[<p>没想到这个系列还能有第三集，应该是完结篇了。这次是因为前不久试用了一下 Linux 的 Windows 子系统，发现意外的不错，与 Windows 本身契合度很高，于是在 Windows 里跑 DNSMasq + ChinaDNS 的设想得以实现√</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=69187235" target="_blank">「夏コミグッズ…」/「三村ざじゃ」のイラスト [pixiv]</a></p>
<hr />
<p>在<a href="/posts/chinadns-plus-dnsmasq/">上一篇文章</a>中，我讲到了在国内服务器上使用 DNSMasq + ChinaDNS 以能在任何支持自定义 DNS 的设备上解决 DNS 污染的方案，但这个方案也有缺点：如果平时你主要是自用，在 Windows 上做到无污染即可，那么为此专门去购买国内服务器（即使是很便宜的学生机）其实也有点大材小用。</p>
<p>不久前不小心才想起来还有一个 Windows 子系统的玩意没试过，说是可以在 Windows 上直接跑 Linux，这样是不是就可以解决没办法在 Windows 上跑 DNSMasq 的问题了？（当然能解决啦</p>
<div><div><div></div><div>Warning</div></div><div><p>Win10 必须是 1607 版本及以后的</p></div></div>
<p>这种解决方案还有一个好处，就是可以解决 IPv6 协议的 DNS 设置问题。
当你在 IPv6 下想用其他只支持 IPv4 的服务器做 DNS，IPv6 中的 DNS 地址就只能填写成 IPv4 镜像地址<code>::ffff:1.2.3.4</code>的形式使其立即 fallback 到 IPv4 去解析，虽然日常使用上不会感觉有什么大问题，但是在使用例如<code>nslookup</code>之类的工具时就会发生异常。
而在子系统 Linux 中使用 DNSMasq 可以同时监听 IPv6，因此就可以很好的解决这个问题。</p>
<section><h2>开启 Windows 子系统<a href="#开启-windows-子系统"><span>#</span></a></h2><section><h3>1. 开启子系统功能<a href="#1-开启子系统功能"><span>#</span></a></h3><ol>
<li>Win10 系统设置-&gt;更新与安全-&gt;开发者选项-&gt;勾选“开发人员模式”，然后会有文字提示你“正在搜索开发者软件包”之类的，无需理会
<img src="/usr/uploads/2018/06/1563990353.png" alt="" /></li>
<li>控制面板-&gt;程序和功能-&gt;启用或关闭 Windows 功能-&gt;勾选“适用于 Linux 的 Windows 子系统”-&gt;确定，然后等操作完成以后重启
<img src="/usr/uploads/2018/06/2616907228.png" alt="" /></li>
</ol></section><section><h3>2. 安装子系统 Linux<a href="#2-安装子系统-linux"><span>#</span></a></h3><p>打开 Win10 应用商店，右上角搜索“Linux”，然后根据结果指引你很容易能找到这里</p><p><img src="/usr/uploads/2018/06/3485633814.png" alt="" /></p><p>然后选择你喜欢的 Linux 系统安装即可，我比较喜欢 Debian 所以安装了 Debian</p><p>安装完成后打开系统，会让你输入新用户名，直接输入<code>root</code>即可，这样能默认就使用 root 登录，然后根据提示设置一个密码即可</p><p>完成后先替换软件源，因为在国内用国外的官方源会非常非常慢</p><p>我习惯用<code>nano</code>编辑器，因此之后的所有编辑命令都是<code>nano</code>，你可以用你自己习惯的编辑器命令</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>nano</span><span> </span><span>/etc/apt/sources.list</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>编辑完之后，<code>nano</code>编辑器是按<code>Ctrl + X</code>再按<code>Y</code>保存</p><p>将原来的软件源替换成阿里云的镜像源，以下示例是 Debian 9 的软件源，请你根据自己的系统发行版本来更换软件源</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>deb</span><span> </span><span>http://mirrors.aliyun.com/debian/</span><span> </span><span>stretch</span><span> </span><span>main</span></div></div><div><div><div>2</div></div><div><span>deb</span><span> </span><span>http://mirrors.aliyun.com/debian/</span><span> </span><span>stretch-updates</span><span> </span><span>main</span></div></div><div><div><div>3</div></div><div><span>deb</span><span> </span><span>http://mirrors.aliyun.com/debian-security/</span><span> </span><span>stretch/updates</span><span> </span><span>main</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后例行的<code>apt-get</code>二连，并安装后续所需依赖软件</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>update</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>upgrade</span><span> </span><span>-y</span></div></div><div><div><div>3</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>make</span><span> </span><span>gcc</span><span> </span><span>curl</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>至此子系统的部署就完成了</p></section></section>
<section><h2>部署 ChinaDNS<a href="#部署-chinadns"><span>#</span></a></h2><ol>
<li>下载 ChinaDNS 源码并解压编译</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/root</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span>  </span><span>https://github.com/shadowsocks/ChinaDNS/releases/download/1.3.2/chinadns-1.3.2.tar.gz</span></div></div><div><div><div>3</div></div><div><span>tar</span><span> </span><span>-zxvf</span><span> </span><span>chinadns-1.3.2.tar.gz</span></div></div><div><div><div>4</div></div><div><span>mv</span><span> </span><span>chinadns-1.3.2</span><span> </span><span>chinadns</span></div></div><div><div><div>5</div></div><div><span>cd</span><span> </span><span>chinadns</span></div></div><div><div><div>6</div></div><div><span>./configure</span><span> &amp;&amp; </span><span>make</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>更新 chnrouter</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># In /root/chinadns</span></div></div><div><div><div>2</div></div><div><span>curl</span><span> </span><span>'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest'</span><span> | </span><span>grep</span><span> </span><span>ipv4</span><span> | </span><span>grep</span><span> </span><span>CN</span><span> | </span><span>awk</span><span> </span><span>-F</span><span>\|</span><span> </span><span>'{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }'</span><span> &gt; </span><span>chnroute.txt</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>配置 supervisor 进程守护</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 安装 supervisor</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>supervisor</span></div></div><div><div><div>3</div></div><div><span># 写入配置（8053是ChinaDNS监听端口，你可以修改成其他的，但是请注意端口冲突问题以及后续DNSMasq配置的同步修改）</span></div></div><div><div><div>4</div></div><div><span>echo</span><span> </span><span>"[program:chinadns]</span></div></div><div><div><div>5</div></div><div><span>command = /root/chinadns/src/chinadns -p 8053 -m -c /root/chinadns/chnroute.txt -s 114.114.114.114,208.67.222.222:443</span></div></div><div><div><div>6</div></div><div><span>user = root</span></div></div><div><div><div>7</div></div><div><span>autostart = true</span></div></div><div><div><div>8</div></div><div><span>autorestart = true"</span><span> &gt; </span><span>/etc/supervisor/conf.d/chinadns.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>启动 supervisor 服务</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>service</span><span> </span><span>supervisor</span><span> </span><span>start</span></div></div><div><div><div>2</div></div><div><span># 然后检查下 ChinaDNS 是否有正常运行</span></div></div><div><div><div>3</div></div><div><span>supervisorctl</span><span> </span><span>status</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>部署 DNSMasq<a href="#部署-dnsmasq"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 安装 DNSMasq</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>dnsmasq</span></div></div><div><div><div>3</div></div><div><span># 写入配置（使用ChinaDNS做上游DNS）</span></div></div><div><div><div>4</div></div><div><span>echo</span><span> </span><span>"port=53</span></div></div><div><div><div>5</div></div><div><span>no-resolv</span></div></div><div><div><div>6</div></div><div><span>no-poll</span></div></div><div><div><div>7</div></div><div><span>server=127.0.0.1#8053"</span><span> &gt; </span><span>/etc/dnsmasq.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后修改一下 DNSMasq 服务的启动命令**（重要，请务必修改，否则 DNSMasq 会无法正常使用配置）**</p><p>编辑 DNSMasq 服务</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>nano</span><span> </span><span>/etc/init.d/dnsmasq</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>找到<code>start()</code>函数，按照此图注释掉并修改对应语句，然后保存退出</p><p><img src="/usr/uploads/2018/06/4135696945.png" alt="" /></p><p>启动 DNSMasq 服务</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>service</span><span> </span><span>dnsmasq</span><span> </span><span>start</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>修改系统 DNS 为本机<a href="#修改系统-dns-为本机"><span>#</span></a></h2><p>将 IPv4 DNS 改为仅<code>127.0.0.1</code>
将 IPv6 DNS 改为仅<code>::1</code></p><p>然后用<code>nslookup</code>试一下，是不是无污染啦</p><p><img src="/usr/uploads/2018/06/3838460752.png" alt="" /></p></section>
<section><h2>让上面这一套开机自启<a href="#让上面这一套开机自启"><span>#</span></a></h2><p>由于子系统 Linux 定制内核的特殊性无法运用<code>rc.local</code>那一套开机自启，因此需要曲线救国</p><p>新建<code>/root/.boot.sh</code>文件，写入以下内容</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/sh</span></div></div><div><div><div>2</div></div><div><span>service</span><span> </span><span>supervisor</span><span> </span><span>start</span></div></div><div><div><div>3</div></div><div><span>service</span><span> </span><span>dnsmasq</span><span> </span><span>start</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后打开 Windows 上的“启动”文件夹
路径是<code>C:\Users\你的用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup</code></p><p>在这里新建一个文本文件，写入以下代码</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>CreateObject(</span><span>"Wscript.Shell"</span><span>).run </span><span>"bash ~/.boot.sh"</span><span>,vbhide</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后将这个文本文件改名为<code>linux.vbs</code></p><p>Windows 上的<code>bash</code>命令实际上就是子系统 Linux 中的<code>bash</code>，进行到这里我相信你应该懂上面的操作是什么意思了√</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/cloudiplc-nat/</id>
      <title type="text">[CloudIPLC] NAT 主机的正确食用方法</title>
      <published>2018-06-10T09:23:00.000Z</published>
      <updated>2019-12-16T02:47:27.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/cloudiplc-nat/"/>
      <summary type="text">最近 NAT 主机突然就火了起来，很多人跟风购买，却没有去了解 NAT 到底能做什么、适合做什么、该怎么做。因此我打算写这篇文章介绍一下 NAT 主机的具体用途以及食用方法，以及推荐一家很不错的国内 NAT 主机商家——CloudIPLC</summary>
      <content type="html"><![CDATA[<p>最近 NAT 主机突然就火了起来，很多人跟风购买，却没有去了解 NAT 到底能做什么、适合做什么、该怎么做。因此我打算写这篇文章介绍一下 NAT 主机的具体用途以及食用方法，以及推荐一家很不错的国内 NAT 主机商家——CloudIPLC</p>
<section><h1>NAT<a href="#nat"><span>#</span></a></h1><p>NAT（Network Address Translation，网络地址转换）是1994年提出的。当在专用网内部的一些……</p><p>啊别关别关，我这里就不读下去了23333，想了解有关 NAT 的知识可以自行百度百科或者查阅Wiki</p><section><h2>NAT 主机的优势在哪里<a href="#nat-主机的优势在哪里"><span>#</span></a></h2><p>其实这与虚拟主机有异曲同工之妙，性质上算是<strong>合租</strong>，其核心优势就是<strong>省钱</strong></p><p>一个宿主机上可以开N个虚拟主机，他们共享（合租）同一个公网IP和带宽，仅仅允许你建站，而不会给你 root 权限让你做更多的事情。即使在这种严格的限制下，如果我们仍然会考虑去买一个虚拟主机而不是直接买一个 VPS，我们的考虑一定是：</p><ol>
<li>我只需要运行一个（或多个）网站就够了</li>
<li>我不需要用到 root 权限去做其他的事情</li>
<li>在仅考虑以上两点的情况下，虚拟主机的性价比要比 VPS 高：在同样的配置下我只需要花更少的钱，或者花同样的钱我能得到更高的配置（带宽、流量、空间大小）</li>
</ol><p>同样的，一个宿主机上可以开N个 NAT 鸡，他们也共享（合租）同一个公网IP和带宽。你可以得到完整的 root 权限，控制你的主机的权限，这几点和 VPS 一样，但不同是你只能得到有限的端口。</p><p>为什么会有这样的“合租”形式？</p><p>就目前 IPv6 还没有在国内推广普及的情况下，<strong>国内公网IP资源是十分有限的</strong>，因此一个国内公网IP的成本实际上是比较高的。</p><p>而<strong>成本更高的则是带宽</strong>，国内的带宽资源是更稀缺的，你可以随便找一家国内大厂（阿里云、腾讯云），VPS 默认独享带宽是 1Mbps (128KiB/s)，这时的价格可以接受，但远远无法满足日常使用。试着将带宽调高一点？价格立即爆炸。我们这样并不富裕的普通人也许并没有办法接受国内 VPS 的价格。</p><p>如果我们的需求是：</p><ol>
<li>我需要能搞事的主机（完整的 root 权限）</li>
<li>我不需要做站，<code>80</code>、<code>443</code>这些端口我都无所谓，我只需要很少量的端口就行了</li>
<li>我需要较大峰值的带宽（流量中转、代理），国内的 1Mbps 小水管根本无法满足我的使用需求</li>
</ol><p>那么我们就可以考虑购买 NAT 主机了</p></section><section><h2>国内 NAT 主机适合做什么<a href="#国内-nat-主机适合做什么"><span>#</span></a></h2><p>NAT 主机最大的局限性是只能得到很少量的端口使用权，因此我们是不能拿来做公共的、需要固定端口的服务，例如在 80 和 443 端口建站、邮局等</p><p>但是由于我们得到的是完整的 root 权限，我们可以拿来做很多其他事情：</p><ul>
<li><strong>中转流量以改善国内使用体验</strong>（中转酸酸或者其他国外服务）</li>
<li>做节点监控</li>
<li>挂机器人或者其他一些适合在国内运行的服务</li>
<li><strong>供海外留学生连回国内</strong>，无需再购买昂贵的国内 VPS</li>
</ul></section><section><h2>如何中转流量（使用<code>iptables</code>）<a href="#如何中转流量使用iptables"><span>#</span></a></h2><div><div><div></div><div>Note</div></div><div><p>注：iptables 总有许多奇奇怪怪的问题，我更推荐使用 haproxy 或者 rinetd 做端口转发，但缺点是不支持 UDP 转发；如果要转发 UDP 可以考虑 nginx 的 ngx_stream_core 模块</p></div></div><p>以下教程来自 CloudIPLC</p><p>同端口号转发示例：</p><ol>
<li>通过<code>ifconfig</code>命令查看本机内网IP，即<code>eth0</code>网卡对应的IPv4，记下</li>
<li>开启系统的IPv4转发功能</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 新手建议使用 nano 编辑器，更符合使用习惯</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>nano</span></div></div><div><div><div>3</div></div><div><span># 或</span></div></div><div><div><div>4</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>nano</span></div></div><div><div><div>5</div></div><div><span># 修改系统设置</span></div></div><div><div><div>6</div></div><div><span># 将 net.ipv4.ip_forward=0</span></div></div><div><div><div>7</div></div><div><span># 改为 net.ipv4.ip_forward=1</span></div></div><div><div><div>8</div></div><div><span>nano</span><span> </span><span>/etc/sysctl.conf</span></div></div><div><div><div>9</div></div><div><span># 更新系统设置使修改生效</span></div></div><div><div><div>10</div></div><div><span>sysctl</span><span> </span><span>-p</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>加入<code>iptables</code>防火墙规则</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>iptables</span><span> </span><span>-t</span><span> </span><span>nat</span><span> </span><span>-A</span><span> </span><span>PREROUTING</span><span> </span><span>-p</span><span> </span><span>tcp</span><span> </span><span>--dport</span><span> </span><span>端口号</span><span> </span><span>-j</span><span> </span><span>DNAT</span><span> </span><span>--to-destination</span><span> </span><span>目标IP</span></div></div><div><div><div>2</div></div><div><span>iptables</span><span> </span><span>-t</span><span> </span><span>nat</span><span> </span><span>-A</span><span> </span><span>PREROUTING</span><span> </span><span>-p</span><span> </span><span>udp</span><span> </span><span>--dport</span><span> </span><span>端口号</span><span> </span><span>-j</span><span> </span><span>DNAT</span><span> </span><span>--to-destination</span><span> </span><span>目标IP</span></div></div><div><div><div>3</div></div><div><span>iptables</span><span> </span><span>-t</span><span> </span><span>nat</span><span> </span><span>-A</span><span> </span><span>POSTROUTING</span><span> </span><span>-p</span><span> </span><span>tcp</span><span> </span><span>-d</span><span> </span><span>目标IP</span><span> </span><span>--dport</span><span> </span><span>端口号</span><span> </span><span>-j</span><span> </span><span>SNAT</span><span> </span><span>--to-source</span><span> </span><span>本机内网IP</span></div></div><div><div><div>4</div></div><div><span>iptables</span><span> </span><span>-t</span><span> </span><span>nat</span><span> </span><span>-A</span><span> </span><span>POSTROUTING</span><span> </span><span>-p</span><span> </span><span>udp</span><span> </span><span>-d</span><span> </span><span>目标IP</span><span> </span><span>--dport</span><span> </span><span>端口号</span><span> </span><span>-j</span><span> </span><span>SNAT</span><span> </span><span>--to-source</span><span> </span><span>本机内网IP</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>保存<code>iptables</code>规则</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># CentOS</span></div></div><div><div><div>2</div></div><div><span>service</span><span> </span><span>iptables</span><span> </span><span>save</span></div></div><div><div><div>3</div></div><div><span>service</span><span> </span><span>iptables</span><span> </span><span>restart</span></div></div><div><div><div>4</div></div><div><span># Ubuntu / Debian</span></div></div><div><div><div>5</div></div><div><span>iptables-save</span><span> &gt; </span><span>/etc/iptables.up.rules</span></div></div><div><div><div>6</div></div><div><span>iptables-restore</span><span> &lt; </span><span>/etc/iptables.up.rules</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>有更多需求（例如非同端口号转发、多端口号转发）可以查阅<a href="https://www.cloudiplc.com/knowledgebase.php?action=displayarticle&amp;id=9" target="_blank">完整教程</a>
以及<a href="https://www.cloudiplc.com/knowledgebase.php?action=displayarticle&amp;id=6" target="_blank">使用 rinetd 进行端口转发</a>的教程</p></section></section>
<section><h1>国内 NAT 主机商家推荐 CloudIPLC<a href="#国内-nat-主机商家推荐-cloudiplc"><span>#</span></a></h1><p>这是一家成立于2016年的国人 VPS 主机商，主要经营美国、香港、俄罗斯、泉州CN2的 VPS，以及国内徐州电信/联通和泉州移动的 NAT 主机，均为 KVM 虚拟架构</p><p>这家性价比高，口碑也相当好，亲身体验也确实很棒，特别是一些比较人性化的细节，并且他家 NAT 主机也是 KVM 虚拟化，因此相比很多为了打压价格使用 OVZ 虚拟化的 NAT 主机，能搞的事情就更多了，这点十分赞。</p><p>我和老板聊了一会，发现他们是十分为客户着想的，并且很低调没有四处打广告之类的，“我不喜欢广告，就是喜欢真实的体验觉得用下来好”，感觉这样走心的商家已经不多了</p><p>这里主要介绍下 NAT 主机，我入手了徐州电信、徐州联通和泉州移动各一台，后面会有详细评测</p><section><h2>套餐价格<a href="#套餐价格"><span>#</span></a></h2><p>这三个地区的 NAT 主机都有四种规格</p><table><tbody><tr><th></th><th>Nano</th><th>Micro</th><th>Mini</th><th>Standard</th></tr><tr><td>CPU 核心</td><td>1</td><td>1</td><td>1</td><td>1</td></tr><tr><td>内存</td><td>384 MB</td><td>512 MB</td><td>768 MB</td><td>1 GB</td></tr><tr><td>硬盘（SSD，无RAID）</td><td>4 GB</td><td>4 GB</td><td>5 GB</td><td>5 GB</td></tr><tr><td>流量（双向）</td><td>600 GB</td><td>1.5 TB</td><td>3 TB</td><td>5 TB</td></tr><tr><td>带宽</td><td>100 Mbps 峰值（非独享）</td></tr><tr><td>端口（tcp或udp）</td><td>10</td><td>10</td><td>15</td><td>15</td></tr><tr><td>价格（RMB/月）</td><td>￥29.99</td><td>￥39.99</td><td>￥59.99</td><td>￥89.99</td></tr></tbody></table><p>使用优惠码<code>cn-nat</code>可享 NAT 系列<code>88</code>折优惠（包括续费）
<a href="https://www.cloudiplc.com/aff.php?aff=179&amp;gid=11" target="_blank">徐州电信</a> <a href="https://www.cloudiplc.com/aff.php?aff=179&amp;gid=10" target="_blank">徐州联通</a> <a href="https://www.cloudiplc.com/aff.php?aff=179&amp;gid=12" target="_blank">江苏移动</a></p><p>补充说明：</p><ol>
<li>端口映射是可自定义的，而不是固定分配的，仅能使用 20000 以上端口</li>
<li>端口映射规则条数可以扩充，当然，需要额外交钱，但不是很贵</li>
<li>端口映射规则 TCP 和 UDP 是分开的，也就是说如果你需要同时映射同一端口的 TCP 与 UDP 就需要占用2条</li>
<li>SSH端口的映射是赠送的，不计算在10条（或15条）以内</li>
</ol></section><section><h2>区域选择<a href="#区域选择"><span>#</span></a></h2><p>电信、联通、移动各有其优势</p><ul>
<li>电信
适合中转<strong>CN2</strong>，解决非电信访问CN2的缓慢问题</li>
<li>联通
适合中转<strong>日本KDDI、IIJ</strong>等联通优势线路，解决电信、移动访问缓慢问题</li>
<li>移动
适合中转<strong>香港、日本、新加坡等的NTT线路</strong>（例如Vultr日本、AWS日本），直连NTT线路，解决电信、联通访问缓慢或绕路问题</li>
</ul><p>根据自己的需求选择适合地区的主机，我自己试着使用徐州联通移动中转阿里云日本或者是泉州移动中转亚马逊日本，解决了本地运营商QoS导致的UDP断流问题，吃鸡体验良好，不会出现严重丢包情况</p></section><section><h2>ZBench 网络测试<a href="#zbench-网络测试"><span>#</span></a></h2><p>CPU 等参数是一致的因此只放一次</p><p><img src="/usr/uploads/2018/06/133880202.png" alt="" /></p><section><h3>徐州电信<a href="#徐州电信"><span>#</span></a></h3><p><img src="/usr/uploads/2018/06/389715775.png" alt="" /></p></section><section><h3>徐州联通<a href="#徐州联通"><span>#</span></a></h3><p>由于测试脚本异常因此无法测试国内上传下载速度</p><p><img src="/usr/uploads/2018/06/34951393.png" alt="" /></p></section><section><h3>泉州移动<a href="#泉州移动"><span>#</span></a></h3><p>因为是之前买的特价款，因此峰值带宽是<code>50Mbps</code></p><p><img src="/usr/uploads/2018/06/696077391.png" alt="" /></p></section></section><section><h2>路由追踪<a href="#路由追踪"><span>#</span></a></h2><section><h3>阿里云日本（BBtec）<a href="#阿里云日本bbtec"><span>#</span></a></h3><section><h4>徐州电信（最优）<a href="#徐州电信最优"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>1  (hidden)    0.26 ms    *    局域网</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>2  (hidden)    3.76 ms    AS4134  中国 江苏 徐州 电信</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>3  *</span></div></div><div><div><div>4</div></div><div><span><span> </span></span><span>4  221.229.171.197  1.14 ms    AS4134  中国 江苏 徐州 电信</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>5  221.229.193.249  6.85 ms    AS4134  中国 江苏 徐州 电信</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>6  61.160.140.13  8.50 ms    AS23650  中国 江苏 南京 电信</span></div></div><div><div><div>7</div></div><div><span><span> </span></span><span>7  202.97.84.1    18.70 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>8  202.97.24.146  12.30 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>9</div></div><div><span><span> </span></span><span>9  202.97.35.98  12.68 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>10</div></div><div><span>10  221.111.202.49  36.09 ms  AS17676  日本 大阪府 大阪 bbtec.net</span></div></div><div><div><div>11</div></div><div><span>11  *</span></div></div><div><div><div>12</div></div><div><span>12  101.102.204.6  46.97 ms  AS17676  日本 bbtec.net</span></div></div><div><div><div>13</div></div><div><span>13  116.251.67.197  45.98 ms  AS45102  日本 东京都 东京 阿里云</span></div></div><div><div><div>14</div></div><div><span>14  *</span></div></div><div><div><div>15</div></div><div><span>15  (hidden)    43.54 ms  AS45102  日本 东京都 东京 阿里云</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>徐州联通（最优）<a href="#徐州联通最优"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>1  (hidden)    0.15 ms    *    局域网</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>2  (hidden)    4.07 ms    AS4837  中国 江苏 徐州 联通</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>3  10.15.0.5    0.60 ms    *    局域网</span></div></div><div><div><div>4</div></div><div><span><span> </span></span><span>4  10.8.0.1    1.03 ms    *    局域网</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>5  112.85.229.129  0.89 ms    AS4837  中国 江苏 徐州 联通</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>6  112.85.230.25  22.42 ms  AS4837  中国 江苏 徐州 联通</span></div></div><div><div><div>7</div></div><div><span><span> </span></span><span>7  219.158.14.153  13.04 ms  AS4837  中国 上海 联通</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>8  219.158.113.114  17.07 ms  AS4837  中国 上海 联通</span></div></div><div><div><div>9</div></div><div><span><span> </span></span><span>9  219.158.113.133  17.71 ms  AS4837  中国 上海 联通</span></div></div><div><div><div>10</div></div><div><span>10  221.111.202.45  38.06 ms  AS17676  日本 bbtec.net</span></div></div><div><div><div>11</div></div><div><span>11  *</span></div></div><div><div><div>12</div></div><div><span>12  101.102.204.6  46.00 ms  AS17676  日本 bbtec.net</span></div></div><div><div><div>13</div></div><div><span>13  116.251.67.197  49.05 ms  AS45102  日本 东京都 东京 阿里云</span></div></div><div><div><div>14</div></div><div><span>14  *</span></div></div><div><div><div>15</div></div><div><span>15  (hidden)    45.54 ms  AS45102  日本 东京都 东京 阿里云</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>泉州移动（已停运）<a href="#泉州移动已停运"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>1  (hidden)    0.38 ms    *    局域网</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>2  (hidden)    12.16 ms  AS9808  中国 福建 泉州 移动</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>3  *</span></div></div><div><div><div>4</div></div><div><span><span> </span></span><span>4  218.207.222.181  2.33 ms    AS9808  中国 福建 泉州 移动</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>5  221.183.27.225  4.28 ms    AS9808  中国 福建 福州 移动</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>6  221.183.11.233  16.80 ms  AS9808  中国 广东 广州 移动</span></div></div><div><div><div>7</div></div><div><span><span> </span></span><span>7  221.176.22.158  79.57 ms  AS9808  中国 广东 广州 移动</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>8  221.176.19.34  30.22 ms  AS9808  中国 广东 广州 移动</span></div></div><div><div><div>9</div></div><div><span><span> </span></span><span>9  221.183.55.81  35.00 ms  AS9808  中国 广东 广州 移动</span></div></div><div><div><div>10</div></div><div><span>10  223.120.2.185  87.09 ms  AS58453  日本 东京都 东京 移动</span></div></div><div><div><div>11</div></div><div><span>11  223.120.2.194  80.18 ms  AS58453  日本 东京都 东京 移动</span></div></div><div><div><div>12</div></div><div><span>12  223.118.4.113  88.91 ms  AS58453  中国 香港 移动</span></div></div><div><div><div>13</div></div><div><span>13  223.118.4.113  89.39 ms  AS58453  中国 香港 移动</span></div></div><div><div><div>14</div></div><div><span>14  116.251.73.149  82.07 ms  AS45102  日本 东京都 东京 阿里云</span></div></div><div><div><div>15</div></div><div><span>15  116.251.73.149  79.99 ms  AS45102  日本 东京都 东京 阿里云</span></div></div><div><div><div>16</div></div><div><span>16  (hidden)    85.63 ms  AS45102  日本 东京都 东京 阿里云</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section><section><h3>亚马逊日本（NTT）<a href="#亚马逊日本ntt"><span>#</span></a></h3><section><h4>徐州电信<a href="#徐州电信-1"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>1  (hidden)    0.22 ms    *    局域网</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>2  (hidden)    30.53 ms  AS4134  中国 江苏 徐州 电信</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>3  *</span></div></div><div><div><div>4</div></div><div><span><span> </span></span><span>4  221.229.171.201  1.23 ms    AS4134  中国 江苏 徐州 电信</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>5  221.229.192.237  6.31 ms    AS4134  中国 江苏 徐州 电信</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>6  202.97.92.9    15.33 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>7</div></div><div><span><span> </span></span><span>7  202.97.24.174  13.96 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>8  202.97.94.214  11.69 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>9</div></div><div><span><span> </span></span><span>9  202.97.51.62  226.39 ms  AS4134  日本 东京都 东京 电信</span></div></div><div><div><div>10</div></div><div><span>10  *</span></div></div><div><div><div>11</div></div><div><span>11  *</span></div></div><div><div><div>12</div></div><div><span>12  61.213.161.46  182.10 ms  AS2914  日本 东京都 东京 ntt.com</span></div></div><div><div><div>13</div></div><div><span>13  *</span></div></div><div><div><div>14</div></div><div><span>...</span></div></div><div><div><div>15</div></div><div><span>23  *</span></div></div><div><div><div>16</div></div><div><span>24  27.0.0.72    198.55 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>17</div></div><div><span>25  *</span></div></div><div><div><div>18</div></div><div><span>...</span></div></div><div><div><div>19</div></div><div><span>30  *</span></div></div><div><div><div>20</div></div><div><span>31  (hidden)    186.98 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>徐州联通<a href="#徐州联通-1"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>1  (hidden)    0.20 ms    *    局域网</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>2  (hidden)    3.06 ms    AS4837  中国 江苏 徐州 联通</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>3  10.15.0.5    18.07 ms  *    局域网</span></div></div><div><div><div>4</div></div><div><span><span> </span></span><span>4  *</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>5  112.85.229.133  0.84 ms    AS4837  中国 江苏 徐州 联通</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>6  221.6.209.141  18.83 ms  AS4837  中国 江苏 徐州 联通</span></div></div><div><div><div>7</div></div><div><span><span> </span></span><span>7  219.158.4.81  34.18 ms  AS4837  中国 北京 联通</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>8  219.158.5.154  37.66 ms  AS4837  中国 北京 联通</span></div></div><div><div><div>9</div></div><div><span><span> </span></span><span>9  219.158.3.182  38.96 ms  AS4837  中国 北京 联通</span></div></div><div><div><div>10</div></div><div><span>10  129.250.8.25  231.43 ms  AS2914  NTT.COM 骨干网 ntt.com</span></div></div><div><div><div>11</div></div><div><span>11  129.250.3.210  234.00 ms  AS2914  NTT.COM 骨干网 ntt.com</span></div></div><div><div><div>12</div></div><div><span>12  *</span></div></div><div><div><div>13</div></div><div><span>13  *</span></div></div><div><div><div>14</div></div><div><span>14  *</span></div></div><div><div><div>15</div></div><div><span>15  54.239.53.157  333.54 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>16</div></div><div><span>16  54.239.53.92  321.56 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>17</div></div><div><span>17  54.239.53.103  328.26 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>18</div></div><div><span>18  54.239.53.38  333.59 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>19</div></div><div><span>19  *</span></div></div><div><div><div>20</div></div><div><span>20  52.95.31.33    333.83 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>21</div></div><div><span>21  52.95.31.80    332.46 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>22</div></div><div><span>22  27.0.0.72    331.51 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>23</div></div><div><span>23  *</span></div></div><div><div><div>24</div></div><div><span>...</span></div></div><div><div><div>25</div></div><div><span>27  *</span></div></div><div><div><div>26</div></div><div><span>28  (hidden)    336.03 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>泉州移动（最优）（已停运）<a href="#泉州移动最优已停运"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>1  (hidden)    0.28 ms    *    局域网</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>2  (hidden)    20.03 ms  AS9808  中国 福建 泉州 移动</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>3  112.47.0.1    8.26 ms    AS9808  中国 福建 泉州 移动</span></div></div><div><div><div>4</div></div><div><span><span> </span></span><span>4  218.207.222.177  4.55 ms    AS9808  中国 福建 泉州 移动</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>5  221.183.27.189  54.50 ms  AS9808  中国 福建 福州 移动</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>6  221.176.16.42  28.47 ms  AS9808  中国 广东 广州 移动</span></div></div><div><div><div>7</div></div><div><span><span> </span></span><span>7  221.176.18.110  35.01 ms  AS9808  中国 广东 广州 移动</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>8  221.176.19.190  47.31 ms  AS9808  中国 广东 广州 移动</span></div></div><div><div><div>9</div></div><div><span><span> </span></span><span>9  221.183.55.53  36.20 ms  AS9808  中国 广东 广州 移动</span></div></div><div><div><div>10</div></div><div><span>10  223.120.2.233  91.49 ms  AS58453  日本 东京都 东京 移动</span></div></div><div><div><div>11</div></div><div><span>11  223.120.2.250  93.79 ms  AS58453  日本 东京都 东京 移动</span></div></div><div><div><div>12</div></div><div><span>12  203.190.230.53  93.96 ms  *    日本 东京都 东京 equinix.com</span></div></div><div><div><div>13</div></div><div><span>13  203.190.230.53  93.06 ms  *    日本 东京都 东京 equinix.com</span></div></div><div><div><div>14</div></div><div><span>14  *</span></div></div><div><div><div>15</div></div><div><span>15  *</span></div></div><div><div><div>16</div></div><div><span>16  52.95.30.158  84.56 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>17</div></div><div><span>17  52.95.30.155  93.35 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>18</div></div><div><span>18  52.95.30.26    86.59 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>19</div></div><div><span>19  *</span></div></div><div><div><div>20</div></div><div><span>...</span></div></div><div><div><div>21</div></div><div><span>22  *</span></div></div><div><div><div>22</div></div><div><span>23  52.95.31.37    92.26 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>23</div></div><div><span>24  52.95.31.84    96.19 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>24</div></div><div><span>25  27.0.0.72    95.14 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div><div><div><div>25</div></div><div><span>26  *</span></div></div><div><div><div>26</div></div><div><span>...</span></div></div><div><div><div>27</div></div><div><span>29  *</span></div></div><div><div><div>28</div></div><div><span>30  (hidden)    87.37 ms  AS16509,AS38895  日本 东京都 东京 amazon.com</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section><section><h3>搬瓦工洛杉矶CN2（QN）<a href="#搬瓦工洛杉矶cn2qn"><span>#</span></a></h3><section><h4>徐州电信（最优）<a href="#徐州电信最优-1"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>1  (hidden)    0.32 ms    *    局域网</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>2  (hidden)    5.02 ms    AS4134  中国 江苏 徐州 电信</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>3  10.15.0.1    0.50 ms    *    局域网</span></div></div><div><div><div>4</div></div><div><span><span> </span></span><span>4  221.229.171.201  1.16 ms    AS4134  中国 江苏 徐州 电信</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>5  221.229.193.253  8.68 ms    AS4134  中国 江苏 徐州 电信</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>6  221.228.19.21  10.21 ms  AS23650  中国 江苏 南京 电信</span></div></div><div><div><div>7</div></div><div><span><span> </span></span><span>7  202.97.84.93  13.95 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>8  202.97.24.226  12.50 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>9</div></div><div><span><span> </span></span><span>9  202.97.34.126  13.41 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>10</div></div><div><span>10  59.43.244.117  13.10 ms  *    中国 上海 电信</span></div></div><div><div><div>11</div></div><div><span>11  *</span></div></div><div><div><div>12</div></div><div><span>12  59.43.248.105  162.77 ms  *    美国 加利福尼亚州 洛杉矶 电信</span></div></div><div><div><div>13</div></div><div><span>13  218.30.48.146  154.32 ms  AS4134  美国 加利福尼亚州 洛杉矶 ctamericas.com</span></div></div><div><div><div>14</div></div><div><span>14  96.44.180.98  154.60 ms  AS8100  美国 加利福尼亚州 洛杉矶 quadranet.com</span></div></div><div><div><div>15</div></div><div><span>15  *</span></div></div><div><div><div>16</div></div><div><span>16  65.49.198.150  154.22 ms  AS25820  美国 加利福尼亚州 洛杉矶 it7.net</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>徐州联通<a href="#徐州联通-2"><span>#</span></a></h4><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>1  (hidden)    0.43 ms    *    局域网</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>2  (hidden)    8.75 ms    AS4837  中国 江苏 徐州 联通</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>3  10.15.0.5    0.55 ms    *    局域网</span></div></div><div><div><div>4</div></div><div><span><span> </span></span><span>4  10.8.0.1    0.97 ms    *    局域网</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>5  112.85.229.129  0.74 ms    AS4837  中国 江苏 徐州 联通</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>6  112.85.230.149  12.90 ms  AS4837  中国 江苏 徐州 联通</span></div></div><div><div><div>7</div></div><div><span><span> </span></span><span>7  219.158.116.113  33.70 ms  AS4837  中国 北京 联通</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>8  219.158.5.150  44.34 ms  AS4837  中国 北京 联通</span></div></div><div><div><div>9</div></div><div><span><span> </span></span><span>9  219.158.3.138  40.86 ms  AS4837  中国 北京 联通</span></div></div><div><div><div>10</div></div><div><span>10  *</span></div></div><div><div><div>11</div></div><div><span>...</span></div></div><div><div><div>12</div></div><div><span>15  *</span></div></div><div><div><div>13</div></div><div><span>16  65.49.198.150  468.45 ms  AS25820  美国 加利福尼亚州 洛杉矶 it7.net</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>泉州移动（已停运）<a href="#泉州移动已停运-1"><span>#</span></a></h4><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span> </span></span><span>1  (hidden)    0.40 ms    *    局域网</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>2  (hidden)    19.96 ms  AS9808  中国 福建 泉州 移动</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>3  112.47.0.5    0.54 ms    AS9808  中国 福建 泉州 移动</span></div></div><div><div><div>4</div></div><div><span><span> </span></span><span>4  218.207.222.181  1.85 ms    AS9808  中国 福建 泉州 移动</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>5  221.183.27.225  13.49 ms  AS9808  中国 福建 福州 移动</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>6  221.183.11.118  38.02 ms  AS9808  中国 上海 移动</span></div></div><div><div><div>7</div></div><div><span><span> </span></span><span>7  221.176.17.162  26.81 ms  AS9808  中国 上海 移动</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>8  202.97.15.5    29.80 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>9</div></div><div><span><span> </span></span><span>9  202.97.46.5    34.08 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>10</div></div><div><span>10  202.97.48.26  28.22 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>11</div></div><div><span>11  202.97.90.29  28.68 ms  AS4134  中国 上海 电信</span></div></div><div><div><div>12</div></div><div><span>12  59.43.244.113  26.97 ms  *    中国 上海 电信</span></div></div><div><div><div>13</div></div><div><span>13  *</span></div></div><div><div><div>14</div></div><div><span>14  59.43.247.29  162.36 ms  *    中国 北京 电信</span></div></div><div><div><div>15</div></div><div><span>15  218.30.48.146  196.73 ms  AS4134  美国 加利福尼亚州 洛杉矶 ctamericas.com</span></div></div><div><div><div>16</div></div><div><span>16  96.44.180.98  198.63 ms  AS8100  美国 加利福尼亚州 洛杉矶 quadranet.com</span></div></div><div><div><div>17</div></div><div><span>17  *</span></div></div><div><div><div>18</div></div><div><span>18  65.49.198.150  194.18 ms  AS25820  美国 加利福尼亚州 洛杉矶 it7.net</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/asf-see/</id>
      <title type="text">[ASF+SEE] Steam 挂卡卖卡两件套</title>
      <published>2018-06-02T15:40:00.000Z</published>
      <updated>2018-10-12T05:36:17.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/asf-see/"/>
      <summary type="text">最近想给一些真爱游戏（当然是Nekopara）合五级徽章，但是不停买宝石合实际上成本挺高的……忽然想起我还有很多买来（或者白嫖来）就没怎么玩过的游戏可以挂卡再卖掉回血，于是思路就有了，使用 ArchiSteamFarm 自动挂卡再用 Steam Economy Enhancer 批量卖出（然后我立赚￥100）</summary>
      <content type="html"><![CDATA[<p>最近想给一些真爱游戏（当然是Nekopara）合五级徽章，但是不停买宝石合实际上成本挺高的……忽然想起我还有很多买来（或者白嫖来）就没怎么玩过的游戏可以挂卡再卖掉回血，于是思路就有了，使用 ArchiSteamFarm 自动挂卡再用 Steam Economy Enhancer 批量卖出（然后我立赚￥100）</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=58839975" target="_blank">「バトルフィールド」/「Bae.C / 裴.C」[pixiv]</a>
我 Tina 老婆真帅.jpg</p>
<hr />
<p>介绍下需要用到的这俩工具</p>
<section><h2>ArchiSteamFarm<a href="#archisteamfarm"><span>#</span></a></h2><a href="https://github.com/JustArchiNET/ArchiSteamFarm" target="_blank"><div><div><div><div></div><div>JustArchiNET</div></div><div>/</div><div>ArchiSteamFarm</div></div><div></div></div><div>C# application with primary purpose of farming Steam cards from multiple accounts simultaneously.</div><div><div>—</div><div>—</div><div>Apache-2.0</div><span>C#</span></div></a><p>挂卡其实只是这个程序功能的冰山一角……</p><p><img src="/usr/uploads/2018/06/3967335780.png" alt="" /></p><section><h3>如何操作<a href="#如何操作"><span>#</span></a></h3><section><h4>1. 下载程序<a href="#1-下载程序"><span>#</span></a></h4><p>到项目 releases 页面下载最新版程序，支持 linux 与 win，下载对应版本并解压</p><p><a href="https://github.com/JustArchiNET/ArchiSteamFarm/releases" target="_blank">Releases of JustArchi/ArchiSteamFarm</a></p></section><section><h4>2. 生成 ASF 配置<a href="#2-生成-asf-配置"><span>#</span></a></h4><p><a href="https://justarchinet.github.io/ASF-WebConfigGenerator/#/bot" target="_blank">ASF 配置生成器</a></p><ol>
<li>打开上面的网页</li>
<li>填写你看到的那三个框，“Name”是配置文件名称，随便填即可</li>
<li>将下方的“Enable”打勾</li>
</ol><p>这样下载得到的配置就可以直接使用了，但是别急，高级设置里还有更多好玩的东西，不妨来看一看</p><section><h5>ASF 高级设置<a href="#asf-高级设置"><span>#</span></a></h5><p>点击“切换高级设置”，在这里我挑一些常用的说明一下</p><ul>
<li><strong>挂卡</strong></li>
<li><strong>AutoSteamSaleEvent</strong>
自动帮你完成夏季/冬季特卖活动期间的发现队列以及 Steam 奖项投票</li>
<li><strong>FarmOffline</strong>
挂卡/游戏时长时不会显示“正在玩xxxxx”，相当于隐身</li>
<li><strong>自定义</strong></li>
<li><strong>DismissInventoryNotifications</strong>
自动帮你消除得到卡片时的烦人仓库提醒</li>
<li><strong>GamesPlayedWhileIdle</strong>
当没卡可挂时自动帮你挂指定游戏，你需要拿到游戏ID（打开游戏商店页面，URL最后的一串数字就是ID），填进去然后点“新增”，可以加多款游戏来挂</li>
<li><strong>CustomGamePlayedWhileFarming</strong>
挂卡时显示“非Steam游戏中”并显示你指定的游戏名</li>
<li><strong>CustomGamePlayedWhileIdle</strong>
挂游戏时长时显示“非Steam游戏中”并显示你指定的游戏名</li>
</ul><p>更多高级设置说明请看 Wiki
<a href="https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Configuration" target="_blank">https://github.com/JustArchiNET/ArchiSteamFarm/wiki/Configuration</a></p></section></section><section><h4>3. 开始愉快的自动挂卡<a href="#3-开始愉快的自动挂卡"><span>#</span></a></h4><p>将配置文件放入程序内的<code>config</code>目录中，然后打开<code>ArchiSteamFarm.exe</code>即可</p></section><section><h4>注意事项<a href="#注意事项"><span>#</span></a></h4><ol>
<li>使用 ASF 前必须确保你当前网络是可以正常访问 Steam 社区的~~，由于国内一般是无法直接访问，可以通过改 Host 等手段，而我比较推荐直接使用 Steamcommunity 302~~
由于 GFW 已经升级成 SNI 阻断，因此你只能在国外VPS或系统层级的代理或透明代理环境下使用</li>
<li>当你正在运行 Steam PC客户端时启动 ASF 将不能挂卡，因为不能同时多地登录；同样的，当你正在使用 ASF 挂卡时，你也无法登陆PC客户端，会被秒T下线</li>
</ol></section></section></section>
<section><h2>Steam Economy Enhancer<a href="#steam-economy-enhancer"><span>#</span></a></h2><a href="https://github.com/Nuklon/Steam-Economy-Enhancer" target="_blank"><div><div><div><div></div><div>Nuklon</div></div><div>/</div><div>Steam-Economy-Enhancer</div></div><div></div></div><div>Enhances the Steam Inventory and Steam Market.</div><div><div>—</div><div>—</div><div>MIT</div><span>JavaScript</span></div></a><p>这是个 Steam 市场辅助插件</p><section><h3>如何安装<a href="#如何安装"><span>#</span></a></h3><p>这是个油猴脚本，因此你的浏览器必须先安装油猴插件，然后</p><p><a href="https://github.com/Nuklon/Steam-Economy-Enhancer/raw/master/code.user.js" target="_blank">点此安装 Steam Economy Enhancer 脚本</a></p></section><section><h3>如何操作<a href="#如何操作-1"><span>#</span></a></h3><p>登录 Steam 社区网页，查看你的库存，此时网页上方“安装Steam”按钮旁边会多出一个“Steam Economy Enhancer”，点进去是插件设置，这里按顺序翻译一下</p><ol>
<li>卖卡价格的计算方式，两个选择：</li>
<li>过去12小时的均价 和 当前最低售价 两个数间取大值（默认）</li>
<li>当前最低售价</li>
<li>在上面计算出的售价的基础上调整价格（例如你输<code>0.1</code>就是卖卡的时候会帮你多加<code>0.1</code>元再卖）</li>
<li>当最低售价的卖单很少时，选择第二低的售价作为“当前最低售价”去计算1中的售价。</li>
<li>设定物品的价格区间：</li>
<li>普卡</li>
<li>闪卡</li>
<li>其他</li>
<li>市场页面每页显示的物品数量</li>
<li>自动重新上架售价过高的物品（在市场页面起效，如果不想每次进市场页面都帮你重新上架，建议取消，可以手动选择物品执行重新上架）
<img src="/usr/uploads/2018/06/4176722479.png" alt="" /></li>
</ol><p>设置完后点击保存，页面会刷新</p><p>然后请注意不要突然手抖点击“Sell All Items”和“Sell All Cards”，你应该知道这两个按钮是什么意思</p><p>下面看到仓库物品栏，你可以在这里用<code>Ctrl</code>和<code>Shift</code>去多选你想卖出的卡或者物品，然后点击“Sell X Items”去卖掉他们，像这样</p><p><img src="/usr/uploads/2018/06/722684736.png" alt="" /></p><p>同时请注意一下，“Turn X Items Into Gems”是把你选中的东西全换成宝石</p><p>插件只会帮你提交上架请求，接下来就自己到手机令牌里确认上架吧~</p><p>如果你要卖的卡太多不想一个个点确认，可以试试 <a href="https://steamcn.com/t182879-1-1" target="_blank">WinAuth</a> 批量确认，这实际上就是一个在电脑上使用的手机令牌，不过缺点是你需要解绑手机令牌再去绑定 WinAuth，会锁定交易7天</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/hexo-github-pages/</id>
      <title type="text">[Hexo + GitHub Pages] 零成本的 HTTPS 建站大法</title>
      <published>2018-05-29T14:39:00.000Z</published>
      <updated>2020-02-11T17:08:17.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/hexo-github-pages/"/>
      <summary type="text">本文比较适合初次尝试这样建站的萌新阅读，借助 GitHub Pages 平台，我们可以将自己的静态网站零成本托管到 GItHub，并且还可以使用自己的域名，甚至支持自动帮你申请 SSL 证书以开启 HTTPS 访问，可以说是非常造福射惠了~</summary>
      <content type="html"><![CDATA[<p>本文比较适合初次尝试这样建站的萌新阅读，借助 GitHub Pages 平台，我们可以将自己的静态网站<strong>零成本</strong>托管到 GItHub，并且还可以使用自己的域名，甚至支持自动帮你申请 SSL 证书以开启 HTTPS 访问，可以说是非常造福射惠了~</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=64035231" target="_blank">「そらたび」/「凪白みと」[pixiv]</a></p>
<hr />
<p>2018年5月1日，GitHub 正式宣布 GitHub Pages (*.github.io) 支持自定义域名 HTTPS，可以自动帮你申请 Let’s Encrypt 的 SSL 证书并自动部署、续期，这就非常劲爆了</p>
<p>这意味着你可以不用花钱去租赁主机，仅仅需要购买一个域名（如果你愿意使用 GitHub 给的 *.github.io 域名，那甚至连域名钱都不用花了），就可以享受到建站到 SSL 的全套服务，而且访问速度也不赖</p>
<p>当然，只限纯静态网站（仅 html + css + js），关于这个，我仅知道也只能推荐 <a href="https://hexo.io/zh-cn/" target="_blank">Hexo</a>，用的人也蛮多的</p>
<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>本文属于启蒙型文章，因为我不用 Hexo，所以我没办法写出更深层次的教程。主要目的还是为了介绍 GitHub Pages 的 HTTPS 要点，Hexo 算是附赠的（什么鬼</p><p>我会推荐写得好的 Hexo 搭建教程文章，并补充一些关键点，以及说明 GitHub Pages 的建立。</p></section>
<section><h2>GitHub Pages 的建立<a href="#github-pages-的建立"><span>#</span></a></h2><p>如果你没有 GitHub 帐号那当然得注册，进入首页后点击右上角加号，“New repository”</p><p>接下来是很关键的一点，<strong>Name 必须填写成<code>yourname.github.io</code>的形式</strong>，将<code>yourname</code>替换成你的用户名，例如下图中我自己的账户的用户名是<code>ykilin</code></p><p><img src="/usr/uploads/2018/05/1342732500.png" alt="" /></p><p>接着，进入新建好的项目页面，点击右侧的“Setting”进入设置页面</p><p><img src="/usr/uploads/2018/05/4270532664.png" alt="" /></p><p>往下拉找到“GitHub Pages”，将其开启，然后你就可以在“Custom domain”中填入你自己的域名了，记得点“Save”</p><p>以下是注意点：</p><ol>
<li>设置好之后，请为你填写的那个自定义域名创建 CNAME 记录，指向<code>yourname.github.io</code>（将<code>yourname</code>替换成你的用户名）</li>
<li>勾选“Enforce HTTPS”即可以开启我在文章开头提到的“GitHub Pages 支持自定义域名 HTTPS”啦！
不过如果你是刚设置好自定义域名，这个选项应该是灰色的，因为你的自定义域名的 CNAME 记录并没不会那么快生效
你需要做的仅仅是等待，一般短则几十分钟长则几个小时，等 GitHub 认为你的解析生效了，这个勾就可以勾上了</li>
</ol><p><img src="/usr/uploads/2018/05/963883469.png" alt="" /></p><p>然后你可以试着访问一下你的自定义域名，应该就有 HTTPS 并且会显示 GitHub Pages 默认页了</p></section>
<section><h2>关于 Hexo<a href="#关于-hexo"><span>#</span></a></h2><p>Hexo 是一个快速、简洁且高效的博客框架，使用 Markdown（或其他渲染引擎）解析文章</p><p>其基于 Node.js，使用上（例如新建文章）可依靠命令行快速完成</p><section><h3>准备工作<a href="#准备工作"><span>#</span></a></h3><p>*这些都是对于 Windows 的</p><section><h4>Node.js<a href="#nodejs"><span>#</span></a></h4><p>首先需要安装 Node.js，到官网 <a href="https://nodejs.org/" target="_blank">https://nodejs.org/</a> ，点击左侧的绿色按钮下载安装包并安装即可。</p><p>安装过程中“Custom Setup”有一个选项是要不要添加到系统环境变量（英文，注意一下有没有“<strong>Add to PATH</strong>”这个单词），一定要选</p></section></section><section><h3>Git<a href="#git"><span>#</span></a></h3><p>直接去 Git 官网下载 <a href="https://git-scm.com/download/win" target="_blank">https://git-scm.com/download/win</a></p><p>安装步骤及环境变量设置请参考 <a href="https://www.jianshu.com/p/fee5baf756c8" target="_blank">windows安装git和环境变量配置</a></p></section></section>
<section><h2>Hexo 的使用<a href="#hexo-的使用"><span>#</span></a></h2><p>推荐以下几篇文章，请注意，你需要做的是参考、理解、根据你的实际需要效仿，而不是完全照搬步骤</p><ol>
<li><a href="https://blog.csdn.net/gdutxiaoxu/article/details/53576018" target="_blank">手把手教你用 Hexo+Github 搭建属于自己的博客</a></li>
<li><a href="https://www.jianshu.com/p/3e6083a2b498" target="_blank">Hexo配合github搭建网站</a></li>
<li><a href="https://www.jianshu.com/p/e03e363713f9" target="_blank">通过Git将Hexo博客部署到服务器</a></li>
</ol></section>
<section><h2>自动化构建<a href="#自动化构建"><span>#</span></a></h2><p>部署 Hexo 等静态博客的过程其实都大体相同：
写 Markdown -&gt; 构建 -&gt; 推送至仓库</p><p>自从有了 GitHub Action 后，我们可以将构建这一重复性工作交给 GitHub 来进行，这样一来我们就只需要写好 Markdown 然后直接推送到仓库就行了</p><p>关于 GitHub Action 的介绍可以查看这篇文章</p><a href="/posts/github-actions-experience/"><div><div>GitHub Actions 初体验及踩坑记录</div><div>上周摸鱼摸到 GitHub Actions，听说今年 11 月就要正式向大众开放了，试了下蛮好玩的，但局限性和坑点也非常多</div><div><span>2019-11-14</span><span>杂七杂八的</span><span><span>#github actions</span><span>#自动化</span><span>#持续集成</span><span>#部署</span></span></div></div><div><img src="/usr/uploads/2019/11/2612016269.png" alt="" loading="lazy" /></div></a></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/rsshub/</id>
      <title type="text">[RSSHub] 万物皆可RSS</title>
      <published>2018-05-25T13:25:00.000Z</published>
      <updated>2018-05-26T05:49:50.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/rsshub/"/>
      <summary type="text">这是一个轻量、易于扩展的 RSS 生成器，可以给任何奇奇怪怪的内容生成 RSS 订阅源（真好玩耶</summary>
      <content type="html"><![CDATA[<p>这是一个轻量、易于扩展的 RSS 生成器，可以给任何奇奇怪怪的内容生成 RSS 订阅源（真好玩耶</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=64974401" target="_blank">「ヴェールヌイと星降る夜に」/「むらさき*関西コミティアC45」[pixiv]</a></p>
<hr />
<a href="https://github.com/DIYgod/RSSHub" target="_blank"><div><div><div><div></div><div>DIYgod</div></div><div>/</div><div>RSSHub</div></div><div></div></div><div>🧡 Everything is RSSible</div><div><div>—</div><div>—</div><div>AGPL-3.0</div><span>TypeScript</span></div></a>
<p>既有用又有趣的……应该叫万能 RSS 生成器吧233333</p>
<p>是 Nodejs 程序，想自己部署也非常方便</p>
<section><h2>Demo<a href="#demo"><span>#</span></a></h2><p><a href="https://rsshub.app" target="_blank">RSSHub</a></p><p><a href="https://docs.rsshub.app" target="_blank">使用说明</a></p></section>
<section><h2>支持哪些奇奇怪怪的东西呢<a href="#支持哪些奇奇怪怪的东西呢"><span>#</span></a></h2><p>有点多，因此这里只节选部分，完整的支持可以到上面的使用说明查看</p><ul>
<li>RSSHub
<ul>
<li><a href="https://rsshub.app/rsshub/rss" target="_blank">支持的 RSS</a>（如果有新的可以被做成 RSS 订阅的东西）</li>
</ul>
</li>
<li>bilibili
<ul>
<li>番剧</li>
<li>UP 主投稿</li>
<li>UP 主动态</li>
<li>UP 主收藏夹</li>
<li>UP 主投币视频</li>
<li>UP 主粉丝</li>
<li>UP 主关注用户</li>
<li>分区视频</li>
<li>视频评论</li>
<li>link 公告</li>
<li>直播开播</li>
<li>直播搜索</li>
<li>直播分区</li>
</ul>
</li>
<li>微博
<ul>
<li>博主</li>
<li>关键词</li>
</ul>
</li>
<li>网易云音乐
<ul>
<li>歌单歌曲</li>
<li>用户歌单</li>
<li>歌手专辑</li>
</ul>
</li>
<li>简书
<ul>
<li>首页</li>
<li>7 日热门</li>
<li>30 日热门</li>
<li>专题</li>
<li>作者</li>
</ul>
</li>
<li>知乎
<ul>
<li>收藏夹</li>
<li>用户动态</li>
<li>用户回答</li>
<li>专栏</li>
<li>知乎日报</li>
</ul>
</li>
<li>快递</li>
<li>贴吧
<ul>
<li>帖子列表</li>
</ul>
</li>
<li>pixiv
<ul>
<li>用户收藏</li>
<li>用户动态</li>
<li>排行榜</li>
</ul>
</li>
<li>豆瓣
<ul>
<li>正在上映的电影</li>
<li>正在上映的高分电影</li>
<li>即将上映的电影</li>
<li>北美票房榜</li>
</ul>
</li>
<li>今日头条
<ul>
<li>关键词</li>
</ul>
</li>
<li>Twitter
<ul>
<li>用户</li>
</ul>
</li>
<li>Instagram
<ul>
<li>用户</li>
</ul>
</li>
<li>Youtube
<ul>
<li>用户</li>
<li>频道</li>
</ul>
</li>
<li>爱奇艺
<ul>
<li>动漫</li>
</ul>
</li>
<li>斗鱼
<ul>
<li>直播间开播</li>
</ul>
</li>
<li>熊猫直播
<ul>
<li>直播间开播下播</li>
</ul>
</li>
<li>V2EX
<ul>
<li>最热/最新主题</li>
</ul>
</li>
<li>Telegram
<ul>
<li>频道</li>
</ul>
</li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/chinadns-plus-dnsmasq/</id>
      <title type="text">[ChinaDNS] 无污染的智能路由 DNS 折腾记 #2</title>
      <published>2018-05-19T07:51:00.000Z</published>
      <updated>2019-02-08T16:59:24.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/chinadns-plus-dnsmasq/"/>
      <summary type="text">这篇文章算是上一篇文章的完善，教你如何将 ChinaDNS 与 DNSMasq 结合起来用，使其更加稳定并且可以支持 TCP 查询</summary>
      <content type="html"><![CDATA[<p>这篇文章算是上一篇文章的完善，教你如何将 ChinaDNS 与 DNSMasq 结合起来用，使其更加稳定并且可以支持 TCP 查询</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=61433155" target="_blank">「ﾁｬﾝのｴﾘ」/「はれんちとめこ」[pixiv]</a></p>
<hr />
<p>之前一篇文章讲到了如何搭建 ChinaDNS 以及关于 DNS 污染现象的详细说明，但是单纯使用 ChinaDNS 可能会不稳定，并且只支持通过<code>UDP</code>的<code>53</code>端口进行查询</p>
<p>因此，我们最好是使用 DNSMasq 作为主 DNS 服务端，将 ChinaDNS 作为 DNSMasq 的上游 DNS</p>
<p>以下部署过程在我两篇文章里独有讲到，但是这里会对某些步骤稍作修改，想了解关于 DNSMasq 和 ChinaDNS 的更多内容可以看我在文章末尾留的两篇文章</p>
<section><h2>ChinaDNS<a href="#chinadns"><span>#</span></a></h2><section><h3>1. 下载并编译<a href="#1-下载并编译"><span>#</span></a></h3><ol>
<li>如果你的系统中没有<code>make</code>和<code>gcc</code>就需要先安装</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Ubuntu / Debian</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>make</span><span> </span><span>gcc</span></div></div><div><div><div>3</div></div><div><span># CentOS</span></div></div><div><div><div>4</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>make</span><span> </span><span>gcc</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>下载 ChinaDNS 源码并解压编译</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/root</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span>  </span><span>https://github.com/shadowsocks/ChinaDNS/releases/download/1.3.2/chinadns-1.3.2.tar.gz</span></div></div><div><div><div>3</div></div><div><span>tar</span><span> </span><span>-zxvf</span><span> </span><span>chinadns-1.3.2.tar.gz</span></div></div><div><div><div>4</div></div><div><span>mv</span><span> </span><span>chinadns-1.3.2</span><span> </span><span>chinadns</span></div></div><div><div><div>5</div></div><div><span>cd</span><span> </span><span>chinadns</span></div></div><div><div><div>6</div></div><div><span>./configure</span><span> &amp;&amp; </span><span>make</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>更新 chnrouter</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># In /root/chinadns</span></div></div><div><div><div>2</div></div><div><span>curl</span><span> </span><span>'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest'</span><span> | </span><span>grep</span><span> </span><span>ipv4</span><span> | </span><span>grep</span><span> </span><span>CN</span><span> | </span><span>awk</span><span> </span><span>-F</span><span>\|</span><span> </span><span>'{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }'</span><span> &gt; </span><span>chnroute.txt</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>2. 配置 supervisor 守护进程<a href="#2-配置-supervisor-守护进程"><span>#</span></a></h3><p>防止 ChinaDNS 进程挂掉
如果你的系统中已经有 supervisor，那么忽略安装步骤，<strong>酌情参考</strong>除了安装之外的配置步骤</p><ol>
<li>安装</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># python2</span></div></div><div><div><div>2</div></div><div><span>pip</span><span> </span><span>install</span><span> </span><span>supervisord</span></div></div><div><div><div>3</div></div><div><span># python3</span></div></div><div><div><div>4</div></div><div><span>pip</span><span> </span><span>install</span><span> </span><span>git+https://github.com/Supervisor/supervisor</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>初始化并修改配置文件
此处和原先不一样的一点：让 ChinaDNS 在<code>8053</code>端口（或者其他非<code>53</code>端口）监听，因为我们要让它做 DNSMasq 的上游 DNS</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo_supervisord_conf</span><span> &gt; </span><span>/etc/supervisord.conf</span></div></div><div><div><div>2</div></div><div><span>echo</span><span> </span><span>"[program:chinadns]</span></div></div><div><div><div>3</div></div><div><span>command=/root/chinadns/src/chinadns -p 8053 -m -c /root/chinadns/chnroute.txt -s 114.114.114.114,208.67.222.222:443</span></div></div><div><div><div>4</div></div><div><span>user = root</span></div></div><div><div><div>5</div></div><div><span>autostart = true</span></div></div><div><div><div>6</div></div><div><span>autorestart = true"</span><span> &gt;&gt; </span><span>/etc/supervisord.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>添加 supervisor 开机自启</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span> </span><span>"supervisord -c /etc/supervisord.conf"</span><span> &gt;&gt; </span><span>/etc/rc.local</span></div></div><div><div><div>2</div></div><div><span># 执行此命令以防系统没有权限执行开机自启脚本(by youngerzhong)</span></div></div><div><div><div>3</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>/etc/rc.local</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>之后查看<code>/etc/rc.local</code>文件，如果有<code>exit 0</code>这行，就把它移动到文件的最后一行，即保证我们上面添加的这句在<code>exit 0</code>前面</p><ol>
<li>启动 supervisor</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>supervisord</span><span> </span><span>-c</span><span> </span><span>/etc/supervisord.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后查看程序运行状态</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>supervisorctl</span><span> </span><span>status</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果有输出 chinadns 的运行状态<code>RUNNING</code>就说明成功了</p><p>此时可以用<code>dig</code>命令检查一下看 ChinaDNS 是否有正常运作</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>dig</span><span> </span><span>www.pixiv.net</span><span> </span><span>@127.0.0.1</span><span> </span><span>-p</span><span> </span><span>8053</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>DNSMasq<a href="#dnsmasq"><span>#</span></a></h2><p>如果你已经有 DNSMasq，那么忽略安装步骤，<strong>酌情参考</strong>除了安装之外的配置步骤</p><section><h3>1. 安装<a href="#1-安装"><span>#</span></a></h3><section><h4>Ubuntu / Debian<a href="#ubuntu--debian"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>dnsmasq</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>CentOS<a href="#centos"><span>#</span></a></h4><p>由于 CentOS 的<code>yum</code>安装的 DNSmasq 版本比较旧，因此我们可以先下载最新版编译好，用<code>yum</code>安装完之后再替换掉程序。</p><p>先从 <a href="http://www.thekelleys.org.uk/dnsmasq/" target="_blank">http://www.thekelleys.org.uk/dnsmasq/</a> 找到你想要的 DNSmasq 版本的源码压缩包的下载地址，例如我选择的是我写这篇文章时的最新版<code>dnsmasq-2.79.tar.gz</code>。</p><p>下载对应的源码压缩包并解压</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/root</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>http://www.thekelleys.org.uk/dnsmasq/dnsmasq-2.79.tar.gz</span></div></div><div><div><div>3</div></div><div><span>tar</span><span> </span><span>xf</span><span> </span><span>dnsmasq-2.79.tar.gz</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>编译，源码 make 不带 etc 等</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>dnsmasq-2.79</span></div></div><div><div><div>2</div></div><div><span>make</span><span> </span><span>V=s</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后用 yum 安装 DNSmasq</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>dnsmasq</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>yum 安装的是<code>2.4.8</code>版本，然后我们再用我们编译好的最新版本替换</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yes</span><span> | </span><span>cp</span><span> </span><span>-f</span><span> </span><span>./src/dnsmasq</span><span> </span><span>/usr/sbin/dnsmasq</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这时可以查看 DNSmasq 的版本检验一下</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>dnsmasq</span><span> </span><span>-v</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>看一下版本号，应该就是我们编译好的版本了</p></section></section><section><h3>2. 配置<a href="#2-配置"><span>#</span></a></h3><p>编辑<code>/etc/dnsmasq.conf</code>文件，将下面提到的配置项解除注释并进行更改</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 指定监听 53 端口</span></div></div><div><div><div>2</div></div><div><span>port</span><span>=</span><span>53</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 禁止 DNSMasq 使用 resolv.conf</span></div></div><div><div><div>5</div></div><div><span>no-resolv</span></div></div><div><div><div>6</div></div><div><span>no-poll</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span># 指定监听IP，将 x.x.x.x 换成你的 eth0 网卡IP（用 ifconfig 命令查看）</span></div></div><div><div><div>9</div></div><div><span>listen-address</span><span>=</span><span>127.0.0.1,x.x.x.x</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># 指定额外配置文件夹</span></div></div><div><div><div>12</div></div><div><span>conf-dir</span><span>=</span><span>/etc/dnsmasq.d/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果你比较懒不想找而且只需要用 DNSMasq 做到本文所述功能，也可以直接
（注意替换<code>x.x.x.x</code>）</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span> </span><span>"port=53</span></div></div><div><div><div>2</div></div><div><span>no-resolv</span></div></div><div><div><div>3</div></div><div><span>no-poll</span></div></div><div><div><div>4</div></div><div><span>listen-address=127.0.0.1,x.x.x.x</span></div></div><div><div><div>5</div></div><div><span>conf-dir=/etc/dnsmasq.d/"</span><span> &gt; </span><span>/etc/dnsmasq.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后运行以下命令写入配置以将 ChinaDNS 作为上游 DNS</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span> </span><span>"server=127.0.0.1#8053"</span><span> &gt; </span><span>/etc/dnsmasq.d/chinadns.conf</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>重启 DNSMasq</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>/etc/init.d/dnsmasq</span><span> </span><span>restart</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>3. 开放安全组/防火墙端口<a href="#3-开放安全组防火墙端口"><span>#</span></a></h3><p>这里只是特别提醒一下记得开放，特别是部分 IDC 是有“安全组”的，记得开放<code>53</code>端口的 TCP 和 UDP</p><p>其余的<code>iptables</code>操作这里就不教了，因为一般都是全开放，或者去百度一下</p></section></section>
<section><h2>相关文章<a href="#相关文章"><span>#</span></a></h2><a href="/posts/chinadns/"><div><div>[ChinaDNS] 无污染的智能路由 DNS 折腾记</div><div>手上有台去年被京东云骗了买的80多rmb一年的1M小水管机子，闲着也是闲着，就打算用 ChinaDNS 项目部署一个无污染的DNS服务，其中遇到了许多坑，弄清楚了之后我觉得很有必要写一篇教程（特别是在用H大的老毛子固件上的ChinaDNS的朋友们需要看一看），其中涉及到 DNS 污染的问题是重点</div><div><span>2018-04-05</span><span>教程</span><span><span>#chinadns</span><span>#dns污染</span><span>#linux</span></span></div></div><div><img src="/usr/uploads/2018/04/1957003341.jpg" alt="" loading="lazy" /></div></a><a href="/posts/dnsmasq/"><div><div>[DNSmasq] 安装&amp;配置详解</div><div>DNSmasq 是 Linux 下的一个用于配置 DNS 和 DHCP 的工具，个人认为最主要的功能还是用来做 DNS 服务器。一句话，好用的不行。</div><div><span>2017-11-06</span><span>Linux 笔记</span><span><span>#dnsmasq</span><span>#dns</span><span>#分流</span></span></div></div><div><img src="/usr/uploads/2017/11/4182928883.jpg" alt="" loading="lazy" /></div></a></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/frp/</id>
      <title type="text">[frp] 内网穿透神器搭建 萌新也看得懂的教程系列</title>
      <published>2018-05-12T06:33:00.000Z</published>
      <updated>2018-10-16T06:32:15.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/frp/"/>
      <summary type="text">目前个人认为配置和使用上是最方便的内网穿透工具，已经用了快两年了，拿来穿透进没有公网的位于学校宿舍的路由器，蹭蹭百度文库企业账号和知网之类的23333</summary>
      <content type="html"><![CDATA[<p>目前个人认为配置和使用上是最方便的内网穿透工具，已经用了快两年了，拿来穿透进没有公网的位于学校宿舍的路由器，蹭蹭百度文库企业账号和知网之类的23333</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=65406147" target="_blank">「ALTER」/「NIAN」[pixiv]</a></p>
<hr />
<a href="https://github.com/fatedier/frp" target="_blank"><div><div><div><div></div><div>fatedier</div></div><div>/</div><div>frp</div></div><div></div></div><div>A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.</div><div><div>—</div><div>—</div><div>Apache-2.0</div><span>Go</span></div></a>
<p>frp 是一个可用于内网穿透的高性能的反向代理应用，支持 tcp, udp, http, https 协议</p>
<section><h2>前言<a href="#前言"><span>#</span></a></h2><p>为什么不直接放一个一键脚本？手动搭建不会很麻烦吗？</p><ol>
<li>这个程序配置起来一点都不麻烦</li>
<li>一键脚本固然方便，但是对于萌新，我更建议你们尝试手动配置，这样对熟悉与理解 Linux 会有更大帮助</li>
<li>手动配置具有更大的自由度，并且你将会很清楚这些程序是干什么的</li>
</ol><p>本文将以萌新也能看懂的方式讲解</p><ol>
<li>frp服务端搭建</li>
<li>frp服务端配置</li>
<li>frp客户端配置</li>
</ol><p>不会讲解frp客户端的搭建，因为目前frp的主要用途是用于内网穿透，因此客户端通常情况下是家用路由器之类的没有公网的设备</p><p>本文针对的受众是拥有“刷了带frp的固件的路由器（<a href="http://www.right.com.cn/forum/thread-161324-1-1.html" target="_blank">比如这个</a>）”而不清楚如何使用或者在使用上存在疑惑的萌新</p><p>如果你需要在一个不含 frp 的 openwrt 路由器上搭建客户端，或者是拥有树莓派之类的家用 linux 机想部署客户端，那么我认为你的知识水平应该足以根据frp服务端搭建的步骤来类比出客户端的搭建方法，以及通过百度谷歌来解决问题</p><div><div><div></div><div>Warning</div></div><div><p>从<code>0.18.0</code>版本开始，新版与旧版不兼容，并且部分配置字段不同，为了不混淆，这里讲的是新版的搭建与配置</p></div></div></section>
<section><h2>服务端 - frps<a href="#服务端---frps"><span>#</span></a></h2><section><h3>1. 下载程序<a href="#1-下载程序"><span>#</span></a></h3><p>首先到 frp 的 releases 页面下载最新版的对应 VPS 的处理器架构的压缩包
<a href="https://github.com/fatedier/frp/releases" target="_blank">https://github.com/fatedier/frp/releases</a></p><p>如何知道 VPS 的处理器架构？在 VPS 上运行这个命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>arch</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果输出<code>x86_64</code>则需要下载带<code>linux_amd64</code>的那个压缩包；
如果输出的是其他的，则在文件列表中找 linux 的对应架构的压缩包</p><p>以<code>x86_64</code>架构举例（目前大多数都应该是这个架构），本文撰写时 frp 最新版是<code>v0.18.0</code></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/root</span></div></div><div><div><div>2</div></div><div><span># 下载</span></div></div><div><div><div>3</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>https://github.com/fatedier/frp/releases/download/v0.18.0/frp_0.18.0_linux_amd64.tar.gz</span></div></div><div><div><div>4</div></div><div><span># 解压</span></div></div><div><div><div>5</div></div><div><span>tar</span><span> </span><span>-xzvf</span><span> </span><span>frp_0.18.0_linux_amd64.tar.gz</span></div></div><div><div><div>6</div></div><div><span># 文件夹名改成 frp，不然目录太长了不方便</span></div></div><div><div><div>7</div></div><div><span>mv</span><span> </span><span>frp_0.18.0_linux_amd64</span><span> </span><span>frp</span></div></div><div><div><div>8</div></div><div><span>cd</span><span> </span><span>frp</span></div></div><div><div><div>9</div></div><div><span># 确保 frps 程序具有可执行权限</span></div></div><div><div><div>10</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>frps</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后试着运行一下<code>frps</code>，看看是否能正常运行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>./frps</span><span> </span><span>--help</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>正常情况下会输出一串帮助信息，那么就说明你下载了正确架构的版本</p><p>如果提示<code>-bash: ./frps: cannot execute binary file: Exec format error</code>就说明你下错版本了</p></section><section><h3>2. 配置程序<a href="#2-配置程序"><span>#</span></a></h3><p>参考以下配置说明来书写配置文件<code>frps.ini</code>，你可以先在电脑上打一份草稿
此处只解释说明一些必要和常用的配置，如需研究完整配置说明请看目录下的<code>frps_full.ini</code>，以及参考<a href="https://github.com/fatedier/frp/blob/master/README_zh.md" target="_blank">frp中文说明</a></p><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 下面这句开头必须要有，表示配置的开始</span></div></div><div><div><div>2</div></div><div><span>[common]</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># frp 服务端端口（必须）</span></div></div><div><div><div>5</div></div><div><span>bind_port</span><span> </span><span>=</span><span> </span><span>7000</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># frp 服务端密码（必须）</span></div></div><div><div><div>8</div></div><div><span>token</span><span> </span><span>=</span><span> </span><span>12345678</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># 认证超时时间，由于时间戳会被用于加密认证，防止报文劫持后被他人利用</span></div></div><div><div><div>11</div></div><div><span># 因此服务端与客户端所在机器的时间差不能超过这个时间（秒）</span></div></div><div><div><div>12</div></div><div><span># 默认为900秒，即15分钟，如果设置成0就不会对报文时间戳进行超时验证</span></div></div><div><div><div>13</div></div><div><span>authentication_timeout</span><span> </span><span>=</span><span> </span><span>900</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span># 仪表盘端口，只有设置了才能使用仪表盘（即后台）</span></div></div><div><div><div>16</div></div><div><span>dashboard_port</span><span> </span><span>=</span><span> </span><span>7500</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span># 仪表盘访问的用户名密码，如果不设置，则默认都是 admin</span></div></div><div><div><div>19</div></div><div><span>dashboard_user</span><span> </span><span>=</span><span> </span><span>admin</span></div></div><div><div><div>20</div></div><div><span>dashboard_pwd</span><span> </span><span>=</span><span> </span><span>admin</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span># 如果你想要用 frp 穿透访问内网中的网站（例如路由器设置页面）</span></div></div><div><div><div>23</div></div><div><span># 则必须要设置以下两个监听端口，不设置则不会开启这项功能</span></div></div><div><div><div>24</div></div><div><span>vhost_http_port</span><span> </span><span>=</span><span> </span><span>10080</span></div></div><div><div><div>25</div></div><div><span>vhost_https_port</span><span> </span><span>=</span><span> </span><span>10443</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span># 此设置需要配合客户端设置，仅在穿透到内网中的 http 或 https 时有用（可选）</span></div></div><div><div><div>28</div></div><div><span># 假设此项设置为 example.com，客户端配置 http 时将 subdomain 设置为 test，</span></div></div><div><div><div>29</div></div><div><span># 则你将 test.example.com 解析到服务端后，可以使用此域名来访问客户端对应的 http</span></div></div><div><div><div>30</div></div><div><span>subdomain_host</span><span> </span><span>=</span><span> </span><span>example.com</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>然后把你的准备好的配置文件内容写入<code>frps.ini</code></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span> </span><span>"[common]</span></div></div><div><div><div>2</div></div><div><span>bind_port = 7000</span></div></div><div><div><div>3</div></div><div><span>token = 12345678</span></div></div><div><div><div>4</div></div><div><span>dashboard_port = 7500</span></div></div><div><div><div>5</div></div><div><span>dashboard_user = admin</span></div></div><div><div><div>6</div></div><div><span>dashboard_pwd = admin</span></div></div><div><div><div>7</div></div><div><span>vhost_http_port = 10080</span></div></div><div><div><div>8</div></div><div><span>vhost_https_port = 10443</span></div></div><div><div><div>9</div></div><div><span>subdomain_host = example.com"</span><span> &gt; </span><span>frps.ini</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>试着启动一下<code>frps</code></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 使用 -c 参数指定配置文件</span></div></div><div><div><div>2</div></div><div><span>./frps</span><span> </span><span>-c</span><span> </span><span>frps.ini</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果没有出现错误提示就说明配置没有问题，可以正常使用</p><p>接着按下<code>Ctrl + C</code>终止程序运行</p></section><section><h3>3. 使 frps 在后台持续运行<a href="#3-使-frps-在后台持续运行"><span>#</span></a></h3><section><h4>启动<a href="#启动"><span>#</span></a></h4><p>直接使用前面的命令行来运行是不行的，因为在关掉 ssh 窗口后程序<code>frps</code>就会停止运行，因此要使用<code>nohup [command] &amp;</code>这种操作来使其在后台运行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>nohup</span><span> </span><span>/root/frp/frps</span><span> </span><span>-c</span><span> </span><span>/root/frp/frps.ini</span><span> &amp;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>并且程序的所有输出（日志）会被写入<code>nohup.out</code>文件中，你可以使用<code>cat</code>命令查看其内容</p></section><section><h4>停止<a href="#停止"><span>#</span></a></h4><p>想停止的话，结束<code>frps</code>即可</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>pkill</span><span> </span><span>frps</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>重启<a href="#重启"><span>#</span></a></h4><p>那就先停止再启动嘛23333</p></section><section><h4>加入开机自启<a href="#加入开机自启"><span>#</span></a></h4><p>编辑<code>/etc/rc.local</code>文件，将启动那句命令加到<code>exit 0</code>语句之前（如果有）</p></section></section></section>
<section><h2>客户端 - frpc<a href="#客户端---frpc"><span>#</span></a></h2><p>如需研究完整配置说明请看目录下的<code>frpc_full.ini</code>，以及参考<a href="https://github.com/fatedier/frp/blob/master/README_zh.md" target="_blank">frp中文说明</a></p><section><h3>书写配置<a href="#书写配置"><span>#</span></a></h3><section><h4>基本配置（必须）<a href="#基本配置必须"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 下面这句开头必须要有，表示配置的开始</span></div></div><div><div><div>2</div></div><div><span>[common]</span></div></div><div><div><div>3</div></div><div><span># frp 服务端地址，可以填ip或者域名</span></div></div><div><div><div>4</div></div><div><span>server_addr</span><span> </span><span>=</span><span> </span><span>0.0.0.0</span></div></div><div><div><div>5</div></div><div><span># frp 服务端端口，即填写服务端配置中的 bind_port</span></div></div><div><div><div>6</div></div><div><span>server_port</span><span> </span><span>=</span><span> </span><span>7000</span></div></div><div><div><div>7</div></div><div><span># 填写 frp 服务端密码</span></div></div><div><div><div>8</div></div><div><span>token</span><span> </span><span>=</span><span> </span><span>12345678</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>TCP/UDP<a href="#tcpudp"><span>#</span></a></h4><p>这里以转发 ssh 为例</p><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 自定义一个配置名称，格式为“[名称]”，放在开头</span></div></div><div><div><div>2</div></div><div><span>[ssh]</span></div></div><div><div><div>3</div></div><div><span># 连接类型，填 tcp 或 udp</span></div></div><div><div><div>4</div></div><div><span>type</span><span> </span><span>=</span><span> </span><span>tcp</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span># 本地ip，填你需要转发到的目的ip</span></div></div><div><div><div>7</div></div><div><span># 如果是转发到frp客户端所在本机（比如路由器）则填 127.0.0.1</span></div></div><div><div><div>8</div></div><div><span># 否则填对应机器的内网ip</span></div></div><div><div><div>9</div></div><div><span>local_ip</span><span> </span><span>=</span><span> </span><span>127.0.0.1</span></div></div><div><div><div>10</div></div><div><span># 需要转发到的端口，比如 ssh 端口是 22</span></div></div><div><div><div>11</div></div><div><span>local_port</span><span> </span><span>=</span><span> </span><span>22</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 是否加密客户端与服务端之间的通信，默认是 false</span></div></div><div><div><div>14</div></div><div><span>use_encryption</span><span> </span><span>=</span><span> </span><span>false</span></div></div><div><div><div>15</div></div><div><span># 是否压缩客户端与服务端之间的通信，默认是 false</span></div></div><div><div><div>16</div></div><div><span># 压缩可以节省流量，但需要消耗 CPU 资源</span></div></div><div><div><div>17</div></div><div><span># 加密自然也会消耗 CPU 资源，但是不大</span></div></div><div><div><div>18</div></div><div><span>use_compression</span><span> </span><span>=</span><span> </span><span>false</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span># frp 服务端的远程监听端口，即你访问服务端的 remote_port 就相当于访问</span></div></div><div><div><div>21</div></div><div><span># 客户端的 local_port，如果填0则会随机分配一个端口</span></div></div><div><div><div>22</div></div><div><span>remote_port</span><span> </span><span>=</span><span> </span><span>6001</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>HTTP(S)<a href="#https"><span>#</span></a></h4><p>以转发路由器设置页面为例</p><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 自定义一个配置名称，格式为“[名称]”，放在开头</span></div></div><div><div><div>2</div></div><div><span>[router-web]</span></div></div><div><div><div>3</div></div><div><span># 连接类型，填 http 或 https</span></div></div><div><div><div>4</div></div><div><span>type</span><span> </span><span>=</span><span> </span><span>http</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>local_ip</span><span> </span><span>=</span><span> </span><span>127.0.0.1</span></div></div><div><div><div>7</div></div><div><span>local_port</span><span> </span><span>=</span><span> </span><span>80</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># http 可以考虑加密和压缩一下</span></div></div><div><div><div>10</div></div><div><span>use_encryption</span><span> </span><span>=</span><span> </span><span>true</span></div></div><div><div><div>11</div></div><div><span>use_compression</span><span> </span><span>=</span><span> </span><span>true</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 自定义访问网站的用户名和密码，如果不定义的话谁都可以访问，会不安全</span></div></div><div><div><div>14</div></div><div><span># 有些路由器如果从内部访问web是不需要用户名密码的，因此需要在这里加一层密码保护</span></div></div><div><div><div>15</div></div><div><span># 如果你发现不加这个密码保护，路由器配置页面原本的用户认证能正常生效的话，可以不加</span></div></div><div><div><div>16</div></div><div><span>http_user</span><span> </span><span>=</span><span> </span><span>admin</span></div></div><div><div><div>17</div></div><div><span>http_pwd</span><span> </span><span>=</span><span> </span><span>admin</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span># 还记得我们在服务端配置的 subdomain_host = example.com 吗</span></div></div><div><div><div>20</div></div><div><span># 假设这里我们填 web01，那么你将 web01.example.com 解析到服务端ip后</span></div></div><div><div><div>21</div></div><div><span># 你就可以使用 域名:端口 来访问你的 http 了</span></div></div><div><div><div>22</div></div><div><span># 这个域名的作用是用来区分不同的 http，因为你可以配置多个这样的配置</span></div></div><div><div><div>23</div></div><div><span>subdomain</span><span> </span><span>=</span><span> </span><span>web01</span></div></div><div><div><div>24</div></div><div>
</div></div><div><div><div>25</div></div><div><span># 自定义域名，这个不同于 subdomain，你可以设置与 subdomain_host 无关的其他域名</span></div></div><div><div><div>26</div></div><div><span># subdomain 与 custom_domains 中至少有一个必须要设置</span></div></div><div><div><div>27</div></div><div><span>custom_domains</span><span> </span><span>=</span><span> </span><span>web02.yourdomain.com</span></div></div><div><div><div>28</div></div><div>
</div></div><div><div><div>29</div></div><div><span># 匹配路径，可以设置多个，用逗号分隔，比如你设置 locations 为以下这个，</span></div></div><div><div><div>30</div></div><div><span># 那么所有 http://xxx/abc 和 http://xxx/def 都会被转发到 http://xxx/</span></div></div><div><div><div>31</div></div><div><span># 如果不需要这个功能可以不写这项，就直接该怎么访问就怎么访问</span></div></div><div><div><div>32</div></div><div><span>locations</span><span> </span><span>=</span><span> </span><span>/abc,/def</span></div></div><div><div><div>33</div></div><div>
</div></div><div><div><div>34</div></div><div><span># 重写 host header，相当于反向代理中的“发送域名”</span></div></div><div><div><div>35</div></div><div><span># 如果设置了，转发 http 时，请求中的 host 会被替换成这个</span></div></div><div><div><div>36</div></div><div><span># 一般情况下不需要用到这个，可以不写这项</span></div></div><div><div><div>37</div></div><div><span>host_header_rewrite</span><span> </span><span>=</span><span> </span><span>dev.yourdomain.com</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>TCP/UDP 范围转发<a href="#tcpudp-范围转发"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 自定义一个配置名称，格式为“[range:名称]”，放在开头</span></div></div><div><div><div>2</div></div><div><span>[range:multi-port]</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>type</span><span> </span><span>=</span><span> </span><span>tcp</span></div></div><div><div><div>5</div></div><div><span>local_ip</span><span> </span><span>=</span><span> </span><span>127.0.0.1</span></div></div><div><div><div>6</div></div><div><span>use_encryption</span><span> </span><span>=</span><span> </span><span>false</span></div></div><div><div><div>7</div></div><div><span>use_compression</span><span> </span><span>=</span><span> </span><span>false</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># 本地端口和远程端口可以指定多个范围，如下格式，且范围之间必须一一对应</span></div></div><div><div><div>10</div></div><div><span>local_port</span><span> </span><span>=</span><span> </span><span>6010-6020,6022,6024-6028</span></div></div><div><div><div>11</div></div><div><span>remote_port</span><span> </span><span>=</span><span> </span><span>16010-16020,16022,16024-16028</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>合并配置<a href="#合并配置"><span>#</span></a></h3><p>将你决定要使用的配置合起来，然后填到路由器的 frp 配置脚本中</p><p>如果你是在 linux 上运行，则写入到<code>frpc.ini</code>中，然后仿照运行服务端的方式来运行客户端</p><p>比如将以上示例配置合并之后，看起来应该是这个样子</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[common]</span></div></div><div><div><div>2</div></div><div><span>server_addr = 0.0.0.0</span></div></div><div><div><div>3</div></div><div><span>server_port = 7000</span></div></div><div><div><div>4</div></div><div><span>token = 12345678</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>[ssh]</span></div></div><div><div><div>7</div></div><div><span>type = tcp</span></div></div><div><div><div>8</div></div><div><span>local_ip = 127.0.0.1</span></div></div><div><div><div>9</div></div><div><span>local_port = 22</span></div></div><div><div><div>10</div></div><div><span>use_encryption = false</span></div></div><div><div><div>11</div></div><div><span>use_compression = false</span></div></div><div><div><div>12</div></div><div><span>remote_port = 6001</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>[router-web]</span></div></div><div><div><div>15</div></div><div><span>type = http</span></div></div><div><div><div>16</div></div><div><span>local_ip = 127.0.0.1</span></div></div><div><div><div>17</div></div><div><span>local_port = 80</span></div></div><div><div><div>18</div></div><div><span>use_encryption = true</span></div></div><div><div><div>19</div></div><div><span>use_compression = true</span></div></div><div><div><div>20</div></div><div><span>http_user = admin</span></div></div><div><div><div>21</div></div><div><span>http_pwd = admin</span></div></div><div><div><div>22</div></div><div><span>subdomain = web01</span></div></div><div><div><div>23</div></div><div><span>custom_domains = web02.yourdomain.com</span></div></div><div><div><div>24</div></div><div><span>locations = /abc,/def</span></div></div><div><div><div>25</div></div><div><span>host_header_rewrite = dev.yourdomain.com</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span>[range:multi-port]</span></div></div><div><div><div>28</div></div><div><span>type = tcp</span></div></div><div><div><div>29</div></div><div><span>local_ip = 127.0.0.1</span></div></div><div><div><div>30</div></div><div><span>use_encryption = false</span></div></div><div><div><div>31</div></div><div><span>use_compression = false</span></div></div><div><div><div>32</div></div><div><span>local_port = 6010-6020,6022,6024-6028</span></div></div><div><div><div>33</div></div><div><span>remote_port = 16010-16020,16022,16024-16028</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section>
<section><h2>事后<a href="#事后"><span>#</span></a></h2><p>登录服务端的 dashboard，看看是否连接成功，测试各项转发是否可用</p><p>如果出现无法使用的情况，按照基本思路排查问题：</p><ol>
<li>看服务端和客户端日志是否有报错</li>
<li>客户端与服务端连接正常，就检查是否是服务端的防火墙或者安全组是否没开放使用到的端口</li>
<li>如果客户端是在路由器上，想转发至内网设备上的某个端口或服务，请检查目标设备的防火墙是否开放所需端口，且建议为该内网设备分配一个静态ip</li>
</ol></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/fail2ban/</id>
      <title type="text">[fail2ban] 防止SSH暴力破解 一键脚本</title>
      <published>2018-05-11T09:23:29.000Z</published>
      <updated>2018-05-11T09:23:29.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/fail2ban/"/>
      <summary type="text">因为最近用的比较多，所以还是搬运过来记录一下把，以后也方便找</summary>
      <content type="html"><![CDATA[<p>因为最近用的比较多，所以还是搬运过来记录一下把，以后也方便找</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=60572714" target="_blank">「メカ娘！」/「mamuru」[pixiv]</a></p>
<hr />
<a href="https://github.com/FunctionClub/Fail2ban" target="_blank"><div><div><div><div></div><div>FunctionClub</div></div><div>/</div><div>Fail2ban</div></div><div></div></div><div>最简单的防止SSH暴力破解的脚本</div><div><div>—</div><div>—</div><div>GPL-3.0</div><span>Shell</span></div></a>
<p>这个一键脚本可以帮你安装 fail2ban，各位应该都听说过这个程序，可以根据 ssh 登录失败记录来屏蔽某个 IP</p>
<section><h2>功能<a href="#功能"><span>#</span></a></h2><ul>
<li>自助修改SSH端口</li>
<li>自定义SSH尝试连接次数</li>
<li>自定义最高封禁IP的时间（以小时为单位）</li>
<li>一键完成SSH防止暴力破解</li>
</ul></section>
<section><h2>支持<a href="#支持"><span>#</span></a></h2><ul>
<li>Centos 6/7 (x86/x64)</li>
<li>Ubuntu 14.04/16.10 (x86/x64)</li>
<li>Debian 7/8 (x86/x64)</li>
</ul></section>
<section><h2>安装<a href="#安装"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>https://raw.githubusercontent.com/FunctionClub/Fail2ban/master/fail2ban.sh</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>fail2ban.sh</span><span> 2&gt;&amp;1 | </span><span>tee</span><span> </span><span>fail2ban.log</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>第一步：选择是否修改SSH端口。
第二步：输入最多尝试输入SSH连接密码的次数
第三步：输入每个恶意IP的封禁时间（单位：小时）</p></section>
<section><h2>卸载<a href="#卸载"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>https://raw.githubusercontent.com/FunctionClub/Fail2ban/master/uninstall.sh</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>uninstall.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ol>
<li>如果你需要更改SSH端口，请记得在防火墙或者安全组中开放新的SSH端口</li>
<li>安装完成后请会重启SSH服务，请重新连接SSH会话</li>
<li>若出现SSH无法连接的情况，请检查是否修改过SSH端口，请填写写改后的正确端口进行连接</li>
</ol></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/domain-app/</id>
      <title type="text">[.app] 谷歌.app域名正式开放注册了</title>
      <published>2018-05-08T17:32:00.000Z</published>
      <updated>2018-05-16T09:05:05.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/domain-app/"/>
      <summary type="text">不知道大家抢到自己心仪的域名没有哇~</summary>
      <content type="html"><![CDATA[<p>不知道大家抢到自己心仪的域名没有哇~</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=66983127" target="_blank">「🌸謹賀新年🌸」/「chihiro🍓」[pixiv]</a></p>
<hr />
<p>谷歌花了2500万美金买下的顶级域名 ╮(￣▽￣”)╭</p>
<section><h2>瞎扯<a href="#瞎扯"><span>#</span></a></h2><p>谷歌说这是世界上首个需要 HTTPS 加密的顶级域名，emmmm，其实只是因为谷歌把<code>.app</code>加到了 preloaded HSTS 列表当中</p><p>这倒也是件好事，HTTPS 加密保障网站不会受到劫持，除非受到中间人攻击，不过只要不是在公共网络环境下一般不需要担心这个问题</p><p>唯一的缺点大概就是对于纯下载文件来说会影响下载速度，毕竟需要进行加解密，不过影响是微乎其微的</p><p>更何况今年 Let’s Encrypt 已经支持免费申请泛域名证书了，这下可方便了，离全民 HTTPS 的梦想又近了一步</p><a href="/posts/acme-le-wc/"><div><div>使用 acme.sh 申请 Let's Encrypt 泛域名SSL证书详细教程</div><div>Let's Encrypt 泛域名SSL已经出来挺长一段时间了，昨天才有需要，因此尝试了一下部署。 一开始看的是 Leonn 的教程，但不是很详细，自己弄懂了流程之后决定写一篇详细一点的教程（使用 CloudXNS 的 API 添加记录进行验证）。</div><div><span>2018-04-01</span><span>教程</span><span><span>#acme.sh</span><span>#证书</span><span>#泛域名</span><span>#dns</span></span></div></div><div><img src="/usr/uploads/2018/04/1493091948.jpg" alt="" loading="lazy" /></div></a></section>
<section><h2>注册<a href="#注册"><span>#</span></a></h2><p>据我所知在谷歌自家注册目前还是最便宜的，14刀一年，约合人民币90元</p><p><a href="https://domains.google" target="_blank">https://domains.google</a></p><p>域名抢注期已经过了，现在是先到先得</p></section>
<section><h2>我的战绩<a href="#我的战绩"><span>#</span></a></h2><p>老实说也真不知道怎么起名字，柑橘都词穷了，而且老婆也就那么几个</p><p>而且我是预注册的，西部数码<code>98元</code>帮忙抢注册，本来以为会有人比我先抢到，也不抱太大希望，结果四个居然都成功强到了</p><p><img src="/usr/uploads/2018/05/2406754468.png" alt="" /></p><p>突然很心疼我的400大洋</p><p>然而又舍不得出掉</p></section>
<section><h2>后记<a href="#后记"><span>#</span></a></h2><p>这篇文章我重写了一次</p><p>因为头图原标题含有 emoji，而我 Typecho 的数据库字符集是不支持 emoji 的那种 uft8，然后我一点击发布，结果发现文章从那个 emoji 本来应该在的地方开始戛然而止……</p><p>心情如下</p><p><img src="/usr/uploads/2018/05/2580666877.jpg" alt="" /></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/bilibili-1080p60fps/</id>
      <title type="text">[bilibili] 教你如何压制B站1080P60帧不二压视频（已GG）</title>
      <published>2018-04-19T09:10:00.000Z</published>
      <updated>2019-08-12T07:42:28.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/bilibili-1080p60fps/"/>
      <summary type="text">在几个月前，B站放宽了视频码率和帧率要求，并将其与大会员挂钩，但是作为UP主肯定还是要去照顾那些没有买大会员的观众，这篇文章将会教你如何方便的压制不二压视频。 基于“小丸工具箱”，可以做到傻瓜式实现，但是要求对命令行相关知识有一点点了解，不要求压制程序的相关知识。</summary>
      <content type="html"><![CDATA[<p>在几个月前，B站放宽了视频码率和帧率要求，并将其与大会员挂钩，但是作为UP主肯定还是要去照顾那些没有买大会员的观众，这篇文章将会教你如何方便的压制不二压视频。</p>
<p>基于“小丸工具箱”，可以做到傻瓜式实现，但是要求对命令行相关知识有一点点了解，不要求压制程序的相关知识。</p>
<p>Head Pic: 苍之彼方的四重奏-有板真白
应该是gal的cg，所以没有原图链接</p>
<hr />
<div><div><div></div><div>Caution</div></div><div><p>由于B站上线 DASH 技术，非大会员已经不能以60帧观看以此方法压制的视频，大家洗洗睡吧</p></div></div>
<p><a href="https://www.bilibili.com/read/cv949156" target="_blank">https://www.bilibili.com/read/cv949156</a></p>
<section><h2>准备<a href="#准备"><span>#</span></a></h2><p>首先你需要一个小丸工具箱</p><p><a href="https://maruko.appinn.me/" target="_blank">小丸工具箱官网</a> <a href="https://dl.hdslb.com/video-press/xiaowantoolsrev194.zip" target="_blank">下载小丸工具箱（B站载点）</a></p></section>
<section><h2>已经写好的傻瓜式批处理脚本<a href="#已经写好的傻瓜式批处理脚本"><span>#</span></a></h2><p>这个 Windows 批处理脚本的适用压制情况：
编码器：<code>x264_64-8bit.exe</code>
音频模式：<code>复制音频流</code>
压制：<code>2Pass</code>、<code>保持原分辨率</code>、<code>保持原帧率</code>
对<code>.mp4</code>进行压制，输出格式依然是<code>.mp4</code></p><p>将以下代码复制下来粘贴到记事本中，修改前面的设置，然后保存成<code>.bat</code>批处理文件，然后将你要压制的视频（仅支持单个文件）直接拖到批处理文件即可自动压制</p><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>@echo</span><span> </span><span>off</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>:</span><span>:设置小丸工具箱目录，不要加末尾的斜杠，不要加双引号</span></div></div><div><div><div>4</div></div><div><span>SET</span><span> </span><span>MarukoToolbox=F:</span><span>\P</span><span>rogram</span><span> </span><span>Files</span><span>\M</span><span>arukoToolbox</span></div></div><div><div><div>5</div></div><div><span>:</span><span>:设置输出目录，不要加末尾的斜杠，不要加双引号</span></div></div><div><div><div>6</div></div><div><span>SET</span><span> </span><span>OutputDir=F:</span><span>\o</span><span>utput</span></div></div><div><div><div>7</div></div><div><span>:</span><span>:视频比特率</span><span>(</span><span>Kbps</span><span>)</span></div></div><div><div><div>8</div></div><div><span>SET</span><span> </span><span>BitRate=</span><span>2900</span></div></div><div><div><div>9</div></div><div><span>:</span><span>:压制线程数</span></div></div><div><div><div>10</div></div><div><span>SET</span><span> </span><span>Threads=</span><span>8</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>:</span><span>:后续部分不需要动</span></div></div><div><div><div>14</div></div><div><span>SET</span><span> </span><span>fullpath=%1</span></div></div><div><div><div>15</div></div><div><span>SET</span><span> </span><span>filename=%~n1</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>:</span><span>:提取音频（复制音频流）</span></div></div><div><div><div>18</div></div><div><span>"%MarukoToolbox%\tools\ffmpeg.exe"</span><span> </span><span>-i</span><span> </span><span>%fullpath%</span><span> </span><span>-vn</span><span> </span><span>-sn</span><span> </span><span>-c:a</span><span> </span><span>copy</span><span> </span><span>-y</span><span> </span><span>-map</span><span> </span><span>0:a:0</span><span> </span><span>"%MarukoToolbox%\temp\%filename%_atemp.aac"</span></div></div><div><div><div>19</div></div><div><span>:</span><span>:VBR</span><span> </span><span>第一次压制</span></div></div><div><div><div>20</div></div><div><span>"%MarukoToolbox%\tools\x264_64-8bit.exe"</span><span> </span><span>--pass</span><span> </span><span>1</span><span> </span><span>--bitrate</span><span> </span><span>%BitRate%</span><span> </span><span>--stats</span><span> </span><span>"%MarukoToolbox%\temp\%filename%_vtemp.stats"</span><span> </span><span>--threads</span><span> </span><span>%Threads%</span><span> </span><span>--preset</span><span> </span><span>8</span><span>  </span><span>-I</span><span> </span><span>600</span><span> </span><span>-r</span><span> </span><span>4</span><span> </span><span>-b</span><span> </span><span>3</span><span> </span><span>--me</span><span> </span><span>umh</span><span> </span><span>-i</span><span> </span><span>1</span><span> </span><span>--scenecut</span><span> </span><span>60</span><span> </span><span>-f</span><span> </span><span>1:1</span><span> </span><span>--qcomp</span><span> </span><span>0.5</span><span> </span><span>--psy-rd</span><span> </span><span>0.3:0</span><span> </span><span>--aq-mode</span><span> </span><span>2</span><span> </span><span>--aq-strength</span><span> </span><span>0.8</span><span> </span><span>--level</span><span> </span><span>4.1</span><span> </span><span>--level-force</span><span> </span><span>-o</span><span> </span><span>NUL</span><span> </span><span>%fullpath%</span></div></div><div><div><div>21</div></div><div><span>:</span><span>:VBR</span><span> </span><span>第二次压制</span></div></div><div><div><div>22</div></div><div><span>"%MarukoToolbox%\tools\x264_64-8bit.exe"</span><span> </span><span>--pass</span><span> </span><span>2</span><span> </span><span>--bitrate</span><span> </span><span>%BitRate%</span><span> </span><span>--stats</span><span> </span><span>"%MarukoToolbox%\temp\%filename%_vtemp.stats"</span><span> </span><span>--threads</span><span> </span><span>%Threads%</span><span> </span><span>--preset</span><span> </span><span>8</span><span>  </span><span>-I</span><span> </span><span>600</span><span> </span><span>-r</span><span> </span><span>4</span><span> </span><span>-b</span><span> </span><span>3</span><span> </span><span>--me</span><span> </span><span>umh</span><span> </span><span>-i</span><span> </span><span>1</span><span> </span><span>--scenecut</span><span> </span><span>60</span><span> </span><span>-f</span><span> </span><span>1:1</span><span> </span><span>--qcomp</span><span> </span><span>0.5</span><span> </span><span>--psy-rd</span><span> </span><span>0.3:0</span><span> </span><span>--aq-mode</span><span> </span><span>2</span><span> </span><span>--aq-strength</span><span> </span><span>0.8</span><span> </span><span>--level</span><span> </span><span>4.1</span><span> </span><span>--level-force</span><span> </span><span>-o</span><span> </span><span>"%MarukoToolbox%\temp\%filename%_vtemp.mp4"</span><span> </span><span>%fullpath%</span></div></div><div><div><div>23</div></div><div><span>:</span><span>:合并视频与音频</span></div></div><div><div><div>24</div></div><div><span>"%MarukoToolbox%\tools\mp4box.exe"</span><span> </span><span>-add</span><span> </span><span>"%MarukoToolbox%\temp\%filename%_vtemp.mp4::trackID=1:name="</span><span> </span><span>-add</span><span> </span><span>"%MarukoToolbox%\temp\%filename%_atemp.aac::trackID=1:name="</span><span> </span><span>-new</span><span> </span><span>"%OutputDir%\%filename%_x264.mp4"</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span>:</span><span>:清理临时文件</span></div></div><div><div><div>27</div></div><div><span>del</span><span> </span><span>"%MarukoToolbox%\temp\%filename%_atemp.aac"</span></div></div><div><div><div>28</div></div><div><span>del</span><span> </span><span>"%MarukoToolbox%\temp\%filename%_vtemp.stats"</span></div></div><div><div><div>29</div></div><div><span>del</span><span> </span><span>"%MarukoToolbox%\temp\%filename%_vtemp.stats.mbtree"</span></div></div><div><div><div>30</div></div><div><span>del</span><span> </span><span>"%MarukoToolbox%\temp\%filename%_vtemp.mp4"</span></div></div><div><div><div>31</div></div><div>
</div></div><div><div><div>32</div></div><div><span>pause</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2>原理解释<a href="#原理解释"><span>#</span></a></h2><p>其实这个压制命令完全是基于小丸工具箱的预置压制参数，只是在基础上加了<code>--level 4.1 --level-force</code>参数</p>

<table><thead><tr><th>清晰度</th><th>要求大会员</th><th>视频码率</th><th>音频码率</th><th>隐性要求</th></tr></thead><tbody><tr><td>720P</td><td></td><td>&lt;=2000K</td><td>&lt;=192K</td><td>level&lt;=4.1</td></tr><tr><td>1080P</td><td></td><td>&lt;=3000K</td><td>&lt;=192K</td><td>level&lt;=4.1</td></tr><tr><td>1080P+</td><td>√</td><td>&lt;=6000K</td><td>&lt;=320K</td><td></td></tr><tr><td>720P60</td><td>√</td><td>&lt;=3000K</td><td>&lt;=320K</td><td></td></tr><tr><td>1080P60</td><td>√</td><td>&lt;=6000K</td><td>&lt;=320K</td><td></td></tr></tbody></table><p>还有其他条件例如色彩空间、声道之类的要求此处省略</p><p>以上条件仅仅依据官方给出的信息 + 本人实际经验 + 本人猜测，实际上肯定有漏洞，我见过<code>8K30FPS</code>的B站视频，level在<code>6.0</code>，码率<code>20000K</code>，清晰度在<code>1080P</code>档，而且UP主说甚至可以弄到最高<code>144FPS</code>，我不太了解这个是怎么做到的</p><p>至于<code>144FPS</code>据我所知在<code>1080P60FPS</code>档是可以的，不会被二压</p><p>回归正题，根据我多年的实验，不被二压的关键在于<code>level&lt;=4.1</code>（想了解 level 参数你可以看<a href="https://zh.wikipedia.org/wiki/H.264/MPEG-4_AVC#%E8%A8%AD%E8%A8%88" target="_blank">这里</a>）</p><p>因为 1080P60FPS 的<code>level=4.2</code>，超过了二压线，因此会被二压，因此我们要做的仅仅只是让B站“认为”我们上传的视频的 level 只有<code>4.1</code>就好了，而且视频码率控制在<code>3000K</code>内，就不会被二压</p><p>在视频压制时加上<code>--level 4.1 --level-force</code>参数，可以让程序强制把 level 信息写成<code>4.1</code>，由于这个值并不是每次都通过后期计算得出的，而是视频文件信息中写死的，因此B站的视频转码机制并“不知道”我们偷改了这个信息</p><p><img src="/usr/uploads/2018/04/1489093374.png" alt="" /></p></section>
<section><h2>万用方法<a href="#万用方法"><span>#</span></a></h2><p>如果你压制参数与我的傻瓜式批处理脚本不同，你也可以制作适合你自己用的批处理脚本</p><p>步骤：</p><ol>
<li>使用小丸工具箱按照你需要的参数配置好，并进行一次压制（注意码率在<code>3000K</code>以内）</li>
<li>压制完成后不要关闭日志窗口，而是点击左下角的“导出日志”，导出成文件</li>
<li>查看日志文件，找到小丸工具箱调用过的命令，将它们按顺序复制出来</li>
<li>向视频压制相关命令中加入<code>--level 4.1 --level-force</code>参数
不过可能并不是所有编码器都有这个参数，具体我并不了解，你可以自行在命令行中查看编码器的帮助信息</li>
<li>仿造懒人脚本中</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>SET</span><span> </span><span>fullpath=%1</span></div></div><div><div><div>2</div></div><div><span>SET</span><span> </span><span>filename=%~n1</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>的相关使用，将你得到的命令写成一个<code>.bat</code>批处理，这样就能方便的对单个视频文件进行处理了 6. 如果你了解 Windows 的 bat 批处理，你也可以自行改造成能应对多个文件或者目录的批处理（加点判断和for循环的事情，不过因为我自己没有需求所以不会给出示例）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/bt-imagemagick/</id>
      <title type="text">宝塔面板无法安装 ImageMagick 的解决方法</title>
      <published>2018-04-15T15:57:00.000Z</published>
      <updated>2018-12-06T11:42:17.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/bt-imagemagick/"/>
      <summary type="text">更新：宝塔回应这个问题已经被修复</summary>
      <content type="html"><![CDATA[<p>更新：宝塔回应这个问题已经被修复</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=67457908" target="_blank">「バレンタイン」/「まよぎい」[pixiv]</a></p>
<hr />
<p>只是因为缺少依赖而已，而bt不会帮你装</p>
<div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Ubuntu / Debian</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>libmagickwand-dev</span></div></div></code></pre><div><div></div><div></div></div></figure></div>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/block-countries-ips/</id>
      <title type="text">[不再维护] 屏蔽任意一个国家所有IP的一键脚本</title>
      <published>2018-04-10T08:02:00.000Z</published>
      <updated>2019-04-28T09:26:27.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/block-countries-ips/"/>
      <summary type="text">看到那个 lowendtalk 上的帖子，觉得挺好玩的就写成了一个脚本，说不定以后还能派上用场（大概并不会派上用场</summary>
      <content type="html"><![CDATA[<p>看到那个 lowendtalk 上的帖子，觉得挺好玩的就写成了一个脚本，说不定以后还能派上用场（大概并不会派上用场</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=45842864" target="_blank">「ルーミア」/「みなみな」[pixiv]</a></p>
<hr />
<a href="https://github.com/Tsuk1ko/Block-IPs-from-countries" target="_blank"><div><div><div><div></div><div>Tsuk1ko</div></div><div>/</div><div>Block-IPs-from-countries</div></div><div></div></div><div>A linux bash script help you block or unblock IPs from countries</div><div><div>—</div><div>—</div><div>no-license</div><span>Shell</span></div></a>
<p>是看到了 lowendtalk 上的这个帖子
<a href="https://www.lowendtalk.com/discussion/141800/blocking-attack-ips-ddos-ips-from-china" target="_blank">https://www.lowendtalk.com/discussion/141800/blocking-attack-ips-ddos-ips-from-china</a></p>
<p>还行，那就做一个一键脚本玩玩
顺便把最近份的文章水了好腾出时间专心写实验</p>
<section><h2>更新日志<a href="#更新日志"><span>#</span></a></h2><p><strong>2018-04-11</strong></p><ol>
<li>把 IP 数据源换成了 APNIC 的</li>
<li>国家代码不用再区分大小写</li>
</ol></section>
<section><h2>准备<a href="#准备"><span>#</span></a></h2><section><h3>安装 ipset<a href="#安装-ipset"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Debian / Ubuntu</span></div></div><div><div><div>2</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>ipset</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># CentOS系统</span></div></div><div><div><div>5</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>ipset</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>下载脚本<a href="#下载脚本"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>https://raw.githubusercontent.com/Tsuk1ko/Block-IPs-from-countries/master/block-ips.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>使用<a href="#使用"><span>#</span></a></h2><section><h3>屏蔽某国IP<a href="#屏蔽某国ip"><span>#</span></a></h3><p>比如要屏蔽中国IP</p><ol>
<li>添加中国IP到 ipset
添加的时候会自动下载一个IP段集<code>delegated-apnic-latest.txt</code>，请不要删除它</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bash</span><span> </span><span>block-ips.sh</span><span> </span><span>-a</span><span> </span><span>cn</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>屏蔽中国IP</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bash</span><span> </span><span>block-ips.sh</span><span> </span><span>-b</span><span> </span><span>cn</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div></div><div>Warning</div></div><div><p>如果真的要试的话就别屏蔽中国IP了啊，小心屏蔽完了 ssh 上不去（。</p></div></div><p>你可以尝试拿邻国友人<code>jp</code>,<code>kr</code>,<code>sg</code>之类的开刀（x</p><div><div><div></div><div>Note</div></div><div><p>你可以到 <a href="http://doc.chacuo.net/iso-3166-1" target="_blank">http://doc.chacuo.net/iso-3166-1</a> 或者 <a href="https://www.iso.org/obp/ui/" target="_blank">https://www.iso.org/obp/ui/</a> 查看可用的国家代码（二字母），使用的时候大小写无所谓</p></div></div></section><section><h3>解除屏蔽<a href="#解除屏蔽"><span>#</span></a></h3><p>如果要解封中国IP</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bash</span><span> </span><span>block-ips.sh</span><span> </span><span>-u</span><span> </span><span>cn</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>查看你已经屏蔽了哪些国家<a href="#查看你已经屏蔽了哪些国家"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bash</span><span> </span><span>block-ips.sh</span><span> </span><span>-l</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>更新IP列表<a href="#更新ip列表"><span>#</span></a></h3><p>如果你需要更新IP列表，你需要先删除<code>delegated-apnic-latest.txt</code>文件，然后再次使用<code>-a</code>参数添加即可，脚本会自动先清空原 ipset 然后重新添加数据</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>rm</span><span> </span><span>delegated-apnic-latest.txt</span></div></div><div><div><div>2</div></div><div><span>bash</span><span> </span><span>block-ips.sh</span><span> </span><span>-a</span><span> </span><span>cn</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/waifu2x/</id>
      <title type="text">小众软件#6 [waifu2x] 二次元动漫图片放大/降噪黑科技</title>
      <published>2018-04-09T05:44:00.000Z</published>
      <updated>2021-02-06T15:23:57.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/waifu2x/"/>
      <summary type="text">这个工具我默默地使用了两年多，今天发现原来去年9月GUI版更新了而我不知道，一直使用的是老版…… 今天更新了下，顺带给还不知道这个黑科技的朋友们介绍下</summary>
      <content type="html"><![CDATA[<p>这个工具我默默地使用了两年多，今天发现原来去年9月GUI版更新了而我不知道，一直使用的是老版……</p>
<p>今天更新了下，顺带给还不知道这个黑科技的朋友们介绍下</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=64653128" target="_blank">「Miku 8.31」/「Nagisa」[pixiv]</a></p>
<hr />
<p>原核心项目：</p>
<a href="https://github.com/nagadomi/waifu2x" target="_blank"><div><div><div><div></div><div>nagadomi</div></div><div>/</div><div>waifu2x</div></div><div></div></div><div>Image Super-Resolution for Anime-Style Art</div><div><div>—</div><div>—</div><div>MIT</div><span>Lua</span></div></a>
<p>Windows GUI 版：</p>
<a href="https://github.com/lltcggie/waifu2x-caffe" target="_blank"><div><div><div><div></div><div>lltcggie</div></div><div>/</div><div>waifu2x-caffe</div></div><div></div></div><div>waifu2xのCaffe版</div><div><div>—</div><div>—</div><div>MIT</div><span>C++</span></div></a>
<p>下载请直接到<code>lltcggie/waifu2x-caffe</code>的 Releases 页面：
<a href="https://github.com/lltcggie/waifu2x-caffe/releases" target="_blank">https://github.com/lltcggie/waifu2x-caffe/releases</a></p>
<section><h2>粗略介绍<a href="#粗略介绍"><span>#</span></a></h2><p>这个工具的作用是将二次元插画、动漫截图、甚至真实照片使用深度卷积神经网络进行缩放，以取得比通常缩放算法更优的效果，并对图片进行降噪处理（因为放大的时候会使原有的噪点变得更加明显或者产生更多噪点），使得放大后的图片显得更加自然，甚至你会以为这就是原图</p><p><img src="/usr/uploads/2018/04/871300768.png" alt="" /></p></section>
<section><h2>下载解压<a href="#下载解压"><span>#</span></a></h2><p>我们从前面说的 Releases 页面下载好压缩包后解压，打开<code>waifu2x-caffe.exe</code>，可以看到如下界面</p><div><div><div></div><div>Warning</div></div><div><p>如果打不开说明计算机上缺少 <a href="https://www.microsoft.com/zh-cn/download/details.aspx?id=40784" target="_blank">Visual C++ Redistributable Packages for Visual Studio 2013</a>，请点击这个链接跳转到微软官方下载页面下载<code>x64</code>版本安装</p></div></div><p>注：<code>waifu2x-caffe</code>仅支持64位系统</p><p><img src="/usr/uploads/2018/04/2659226957.png" alt="" /></p></section>
<section><h2>使用详解<a href="#使用详解"><span>#</span></a></h2><p>程序自带中文，所以很容易看懂，这里只挑一些值得讲的来说明</p><section><h3>输入和输出设置<a href="#输入和输出设置"><span>#</span></a></h3><p>不需要按“浏览”去手动选择，直接把文件/文件夹拖到“输入”文本框中即可</p></section><section><h3>降噪等级<a href="#降噪等级"><span>#</span></a></h3><p>级别越高，降噪越厉害，但是也会使得画面中的部分细节被破坏，具体哪个级别降噪效果最好你可以分别生成来感受一下</p></section><section><h3>模型<a href="#模型"><span>#</span></a></h3><p>一共有两种处理模式和三种颜色模型</p><ul>
<li><strong>处理模式</strong></li>
<li><strong>2D 插图</strong>
用于二次元插画图，比如从P站下载的图片</li>
<li><strong>照片或动画</strong>
三次元照片或者二次元动画截图</li>
<li><strong>颜色模型</strong></li>
<li><strong>RGB 模型</strong>
对图片的 RGB 都进行变换，正常情况下都用这个模式</li>
<li><strong>UpRGB 模型</strong>
相比 RGB，变换速度更快，结果画质相同并可能更好，但是相对的，需要占用更多的内存或者显存</li>
<li><strong>Y 模型</strong>
仅对亮度进行变换，一般不需要用到这个模型</li>
</ul></section><section><h3>TTA 模式<a href="#tta-模式"><span>#</span></a></h3><p>即 Test-Time Augmentation（数据增强），使用这个模式可能会导致变换过程变慢8倍，但是可以让 PSNR（峰值信噪比）上升<code>0.15</code>左右，你可以简单理解为画质变好</p></section><section><h3>拆分大小<a href="#拆分大小"><span>#</span></a></h3><p>拆分大小越大，处理速度越快，代价是占用更多的内存/显存
如果这个值调的过大会导致内存溢出，程序崩溃，因此请量力而为</p></section><section><h3>应用设置-处理器<a href="#应用设置-处理器"><span>#</span></a></h3><section><h4>CUDA (cuDNN)<a href="#cuda-cudnn"><span>#</span></a></h4><section><h5>关于 CUDA<a href="#关于-cuda"><span>#</span></a></h5><p>CUDA 是英伟达 GPU 才有的一个指令架构，可以用来加速图片处理，因此只有英伟达 GPU 才能选这个</p><p>使用前建议先去下载英伟达的官方驱动更新客户端 <a href="http://www.geforce.cn/geforce-experience/download" target="_blank">GeForce Experience</a>，将显卡驱动更新到最新版本再选这项，<strong>不要用什么鲁大师之类的去更新</strong>，这些第三方驱动更新客户端一般只有相对比较旧版本的驱动</p></section><section><h5>关于 cuDDN<a href="#关于-cuddn"><span>#</span></a></h5><p>可进一步加速图片处理</p><p>如果要使用，必须先下载 cuDDN 的动态链接库，目前<code>waifu2x-caffe v1.2.0.2</code>需要使用 v7.3 以上的<code>cudnn64_7.dll</code>，你可以到 <a href="https://developer.nvidia.com/rdp/cudnn-download" target="_blank">cuDDN 官方下载点</a> 下载，不过需要注册英伟达开发者帐号，然后选<code>v7.x.x</code>的最新版本的对应你 CUDA 版本的进行下载，一般是 CUDA 9</p><p>如果你比较懒，这里也提供 Win10 用的 CUDA 9.0，
<a href="https://mega.nz/folder/thZDXADJ#_Zz4824KexoUaiGSm1N5Gw" target="_blank">MEGA 网盘下载点</a></p><p>下载完后将<code>bin</code>目录中的<code>cudnn64_7.dll</code>扔到 waifu2x-caffe 程序根目录中即可，然后重启程序，在主界面点击“cuDNN 检查”，检查通过后即可使用 cuDNN 处理</p></section></section><section><h4>CPU<a href="#cpu"><span>#</span></a></h4><p>处理速度很慢，如果你不是英伟达显卡只能用这个模式</p></section></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/chinadns/</id>
      <title type="text">[ChinaDNS] 无污染的智能路由 DNS 折腾记</title>
      <published>2018-04-05T11:17:00.000Z</published>
      <updated>2018-12-28T17:41:00.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/chinadns/"/>
      <summary type="text">手上有台去年被京东云骗了买的80多rmb一年的1M小水管机子，闲着也是闲着，就打算用 ChinaDNS 项目部署一个无污染的DNS服务，其中遇到了许多坑，弄清楚了之后我觉得很有必要写一篇教程（特别是在用H大的老毛子固件上的ChinaDNS的朋友们需要看一看），其中涉及到 DNS 污染的问题是重点</summary>
      <content type="html"><![CDATA[<p>手上有台去年被京东云骗了买的80多rmb一年的1M小水管机子，闲着也是闲着，就打算用 ChinaDNS 项目部署一个无污染的DNS服务，其中遇到了许多坑，弄清楚了之后我觉得很有必要写一篇教程（特别是在用H大的老毛子固件上的ChinaDNS的朋友们需要看一看），其中涉及到 DNS 污染的问题是重点</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=67584033" target="_blank">「There is a reason」/「极道寂」[pixiv]</a>
“We’ll always be together”</p>
<hr />
<a href="https://github.com/shadowsocks/ChinaDNS" target="_blank"><div><div><div><div></div><div>shadowsocks</div></div><div>/</div><div>ChinaDNS</div></div><div></div></div><div>Protect yourself against DNS poisoning in China.</div><div><div>—</div><div>—</div><div>GPL-3.0</div><span>C</span></div></a>
<p>最初得知这玩意是用了<a href="http://www.right.com.cn/forum/thread-161324-1-1.html" target="_blank">H大的老毛子固件</a>，不过实际使用的时候还是会发生一些科学无法解释的问题，于是决定拿一个 VPS 手动搭一个 ChinaDNS 的服务器来实验</p>
<section><h2>关于 DNS 污染<a href="#关于-dns-污染"><span>#</span></a></h2><p>搭建这个 ChinaDNS 的首要目的是为了解决 DNS 污染问题</p><div><div><div></div><div>Note</div></div><div><p>什么是 DNS 污染？</p></div></div><p><a href="https://zh.wikipedia.org/wiki/%E5%9F%9F%E5%90%8D%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%BC%93%E5%AD%98%E6%B1%A1%E6%9F%93" target="_blank">https://zh.wikipedia.org/wiki/域名服务器缓存污染</a></p><p>首先我们来使用<code>dig</code>命令测试一下解析</p><p>目前我自己已知的最容易判断的污染是<code>www.pixiv.net</code>，即P站域名</p><section><h3>在大陆 VPS 上测试<a href="#在大陆-vps-上测试"><span>#</span></a></h3><section><h4>114 DNS<a href="#114-dns"><span>#</span></a></h4><p>通过<code>114.114.114.114</code>进行查询：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>root@JDu4e00u53f7:~# dig www.pixiv.net @114.114.114.114</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>; &lt;&lt;&gt;&gt; DiG 9.10.3-P4-Ubuntu &lt;&lt;&gt;&gt; www.pixiv.net @114.114.114.114</span></div></div><div><div><div>4</div></div><div><span>;; global options: +cmd</span></div></div><div><div><div>5</div></div><div><span>;; Got answer:</span></div></div><div><div><div>6</div></div><div><span>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 60508</span></div></div><div><div><div>7</div></div><div><span>;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>;; OPT PSEUDOSECTION:</span></div></div><div><div><div>10</div></div><div><span>; EDNS: version: 0, flags:; udp: 4096</span></div></div><div><div><div>11</div></div><div><span>;; QUESTION SECTION:</span></div></div><div><div><div>12</div></div><div><span>;www.pixiv.net.      IN  A</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>;; ANSWER SECTION:</span></div></div><div><div><div>15</div></div><div><span>www.pixiv.net.    33  IN  A  66.220.158.32</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>;; Query time: 21 msec</span></div></div><div><div><div>18</div></div><div><span>;; SERVER: 114.114.114.114#53(114.114.114.114)</span></div></div><div><div><div>19</div></div><div><span>;; WHEN: Thu Apr 05 17:13:02 CST 2018</span></div></div><div><div><div>20</div></div><div><span>;; MSG SIZE  rcvd: 58</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>我们发现其返回了<code>66.220.158.32</code>这个IP，这是用于污染 DNS 的投毒 IP 之一</p></section><section><h4>OpenDNS<a href="#opendns"><span>#</span></a></h4><p>我们还知道，国外的 DNS 是无污染的，其中比较有名的就是 OpenDNS 和 GoogleDNS，<strong>不过因为谷歌被特殊照顾，你根本无法在大陆内使用<code>8.8.8.8</code></strong>（自己在本机测试下路由追踪就懂了），但是 OpenDNS 是没问题的</p><p>通过 OpenDNS <code>208.67.222.222</code>进行查询：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>root@JDu4e00u53f7:~# dig www.pixiv.net @208.67.222.222</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>; &lt;&lt;&gt;&gt; DiG 9.10.3-P4-Ubuntu &lt;&lt;&gt;&gt; www.pixiv.net @208.67.222.222</span></div></div><div><div><div>4</div></div><div><span>;; global options: +cmd</span></div></div><div><div><div>5</div></div><div><span>;; Got answer:</span></div></div><div><div><div>6</div></div><div><span>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 56655</span></div></div><div><div><div>7</div></div><div><span>;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>;; QUESTION SECTION:</span></div></div><div><div><div>10</div></div><div><span>;www.pixiv.net.      IN  A</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>;; ANSWER SECTION:</span></div></div><div><div><div>13</div></div><div><span>www.pixiv.net.    77  IN  A  66.220.152.17</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>;; Query time: 2 msec</span></div></div><div><div><div>16</div></div><div><span>;; SERVER: 208.67.222.222#53(208.67.222.222)</span></div></div><div><div><div>17</div></div><div><span>;; WHEN: Thu Apr 05 17:49:26 CST 2018</span></div></div><div><div><div>18</div></div><div><span>;; MSG SIZE  rcvd: 47</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>结果是出人意料的（虽然对我来说并不意外XD），结果依然是被污染的</p><p>这是为什么？</p><p>很自然的会想到，<strong>GFW 肯定对 DNS 数据包做了手脚</strong>，因为 OpenDNS 服务器位于国外，从大陆发出的数据包势必要通过 GFW，那么被做点手脚是很容易的事情了</p><p>那么怎么办？</p><p>有一个突破口就在于，<strong>DNS 的端口不一定只能用<code>53</code></strong></p><p>幸运的是，GFW 确实只会检测<code>53</code>端口的 DNS 数据包，而且 OpenDNS 除了<code>53</code>，还提供了<code>443</code>和<code>5353</code>端口的 DNS 服务</p><p>通过<code>208.67.222.222</code>的<code>443</code>端口进行查询：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>root@JDu4e00u53f7:~# dig www.pixiv.net @208.67.222.222 -p 443</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>; &lt;&lt;&gt;&gt; DiG 9.10.3-P4-Ubuntu &lt;&lt;&gt;&gt; www.pixiv.net @208.67.222.222 -p 443</span></div></div><div><div><div>4</div></div><div><span>;; global options: +cmd</span></div></div><div><div><div>5</div></div><div><span>;; Got answer:</span></div></div><div><div><div>6</div></div><div><span>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 6215</span></div></div><div><div><div>7</div></div><div><span>;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>;; OPT PSEUDOSECTION:</span></div></div><div><div><div>10</div></div><div><span>; EDNS: version: 0, flags:; udp: 4096</span></div></div><div><div><div>11</div></div><div><span>;; QUESTION SECTION:</span></div></div><div><div><div>12</div></div><div><span>;www.pixiv.net.      IN  A</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>;; ANSWER SECTION:</span></div></div><div><div><div>15</div></div><div><span>www.pixiv.net.    6  IN  CNAME  pixiv.net.</span></div></div><div><div><div>16</div></div><div><span>pixiv.net.    41  IN  A  210.129.120.42</span></div></div><div><div><div>17</div></div><div><span>pixiv.net.    41  IN  A  210.129.120.41</span></div></div><div><div><div>18</div></div><div><span>pixiv.net.    41  IN  A  210.129.120.44</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span>;; Query time: 108 msec</span></div></div><div><div><div>21</div></div><div><span>;; SERVER: 208.67.222.222#443(208.67.222.222)</span></div></div><div><div><div>22</div></div><div><span>;; WHEN: Thu Apr 05 18:06:33 CST 2018</span></div></div><div><div><div>23</div></div><div><span>;; MSG SIZE  rcvd: 104</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>我们看到，这一次终于返回了正确的 IP 地址结果（Yeah~</p></section></section></section>
<section><h2>为什么使用 ChinaDNS 而不是直接使用 OpenDNS<a href="#为什么使用-chinadns-而不是直接使用-opendns"><span>#</span></a></h2><ol>
<li><strong>我们必须使用非<code>53</code>端口去查询国外 DNS 才能得到没有被 GFW 篡改的正确解析结果</strong>，ChinaDNS 可以自定义使用的 DNS 的端口，而 Windows 系统的 DNS 设置定死了使用<code>53</code>端口</li>
<li>如果通过 OpenDNS 去解析国内网站，那么很可能会得到一个海外 IP（很多大公司都会配备有海外服务器供海外华人使用，例如京东啦淘宝啦B站啦），<strong>这样会导致访问国内网站访问速度很慢</strong>
而 ChinaDNS 可以根据 chnrouter 来判断，如果从国内 DNS 里解析到国内 IP 的话就使用，对于国外网站会过滤掉从国内 DNS 解析得到的被污染的结果，十分完美的解决了这个问题</li>
</ol></section>
<section><h2>在大陆 VPS 上部署 ChinaDNS<a href="#在大陆-vps-上部署-chinadns"><span>#</span></a></h2><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 如果 Linux 上没有安装 make 和 gcc 的话要先安装</span></div></div><div><div><div>2</div></div><div><span># Ubuntu / Debian</span></div></div><div><div><div>3</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>make</span><span> </span><span>gcc</span></div></div><div><div><div>4</div></div><div><span># CentOS</span></div></div><div><div><div>5</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>make</span><span> </span><span>gcc</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 下载 ChinaDNS 源码并解压编译</span></div></div><div><div><div>8</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span>  </span><span>https://github.com/shadowsocks/ChinaDNS/releases/download/1.3.2/chinadns-1.3.2.tar.gz</span></div></div><div><div><div>9</div></div><div><span>tar</span><span> </span><span>-zxvf</span><span> </span><span>chinadns-1.3.2.tar.gz</span></div></div><div><div><div>10</div></div><div><span>cd</span><span> </span><span>chinadns-1.3.2</span></div></div><div><div><div>11</div></div><div><span>./configure</span><span> &amp;&amp; </span><span>make</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 更新 chnrouter（必要，因为源码中自带的 chnrouter 已经很旧了）</span></div></div><div><div><div>14</div></div><div><span>curl</span><span> </span><span>'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest'</span><span> | </span><span>grep</span><span> </span><span>ipv4</span><span> | </span><span>grep</span><span> </span><span>CN</span><span> | </span><span>awk</span><span> </span><span>-F</span><span>\|</span><span> </span><span>'{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }'</span><span> &gt; </span><span>chnroute.txt</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span># 更新黑名单IP列表（推荐）</span></div></div><div><div><div>17</div></div><div><span>rm</span><span> </span><span>-f</span><span> </span><span>iplist.txt</span><span> &amp;&amp; </span><span>wget</span><span> </span><span>--no-check-certificate</span><span>  </span><span>https://raw.githubusercontent.com/Tsuk1ko/ChinaDNS/master/iplist.txt</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span># 启动 ChinaDNS（编译好的程序在 src 目录中）</span></div></div><div><div><div>20</div></div><div><span>src/chinadns</span><span> </span><span>-m</span><span> </span><span>-c</span><span> </span><span>chnroute.txt</span><span> </span><span>-s</span><span> </span><span>114.114.114.114,208.67.222.222:443</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>最后别忘记开放防火墙的<code>53</code>UDP端口，这一步如果你不会的话就自行百度吧（</p><p>需要注意的是，这样直接运行是在前台运行，如果你退出 SSH，程序就会终止
在正式使用场合，你需要使用<code>nohup</code>或者<code>screen</code>或者<code>supervisor</code>让 ChinaDNS 在后台一直运行（后面会讲使用<code>supervisor</code>的方法）</p></section>
<section><h2>重点<a href="#重点"><span>#</span></a></h2><ol>
<li>如果不使用<code>-s</code>参数，那么 ChinaDNS 会默认使用<code>114.114.114.114,208.67.222.222:443,8.8.8.8</code>作为 DNS，这样会导致一个很严重的问题！</li>
</ol><p>前面我们说过，<strong>如果你不通过非<code>53</code>端口去查询国外 DNS，就会得到一个被污染的查询结果</strong>，因此如果你使用<code>53</code>端口的国外 DNS 作为 ChinaDNS 的 DNS，最终就会得到被污染的查询结果，从而无法解决污染问题，而 ChinaDNS 正是默认使用了<code>8.8.8.8</code></p><ol>
<li>使用H大老毛子固件上的 ChinaDNS 的时候也请一定要把<code>8.8.8.8</code>去掉，如果不开酸酸/酸酸乳，那么这个<code>8.8.8.8</code>就会污染你的 ChinaDNS 结果</li>
<li>你可以不用 114DNS 当国内 DNS，但是请注意使用<code>-s</code>参数指定 DNS 的时候，一定要把国内 DNS 写在前面，OpenDNS 写在最后面，否则会出现解析国内网站返回海外 IP 的现象（亲测</li>
</ol><p>另外，不能在墙外的 VPS 上搭建 ChinaDNS：</p><ol>
<li>从墙外 VPS 访问国内 DNS 查询国内网站会得到海外 IP 结果</li>
<li>你从大陆发往墙外 VPS 的 DNS 数据包仍会经过 GFW，这意味着你还是不能使用<code>53</code>端口</li>
</ol></section>
<section><h2>测试 ChinaDNS<a href="#测试-chinadns"><span>#</span></a></h2><p>以下是我在自己家路由器上<code>dig</code>的结果：</p><section><h3>Pixiv<a href="#pixiv"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[MI-3 /opt/home/admin]# dig www.pixiv.net @我自建的ChinaDNS服务器</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>; &lt;&lt;&gt;&gt; DiG 9.11.2 &lt;&lt;&gt;&gt; www.pixiv.net @我自建的ChinaDNS服务器</span></div></div><div><div><div>4</div></div><div><span>;; global options: +cmd</span></div></div><div><div><div>5</div></div><div><span>;; Got answer:</span></div></div><div><div><div>6</div></div><div><span>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 55219</span></div></div><div><div><div>7</div></div><div><span>;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>;; OPT PSEUDOSECTION:</span></div></div><div><div><div>10</div></div><div><span>; EDNS: version: 0, flags:; udp: 4096</span></div></div><div><div><div>11</div></div><div><span>;; QUESTION SECTION:</span></div></div><div><div><div>12</div></div><div><span>;www.pixiv.net.      IN  A</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>;; ANSWER SECTION:</span></div></div><div><div><div>15</div></div><div><span>www.pixiv.net.    39  IN  CNAME  pixiv.net.</span></div></div><div><div><div>16</div></div><div><span>pixiv.net.    39  IN  A  210.129.120.44</span></div></div><div><div><div>17</div></div><div><span>pixiv.net.    39  IN  A  210.129.120.41</span></div></div><div><div><div>18</div></div><div><span>pixiv.net.    39  IN  A  210.129.120.42</span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span>;; Query time: 183 msec</span></div></div><div><div><div>21</div></div><div><span>;; SERVER: 我自建的ChinaDNS服务器#53(我自建的ChinaDNS服务器)</span></div></div><div><div><div>22</div></div><div><span>;; WHEN: Thu Apr 05 18:50:49 CST 2018</span></div></div><div><div><div>23</div></div><div><span>;; MSG SIZE  rcvd: 104</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>解析正常√</p></section><section><h3>Google<a href="#google"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[MI-3 /opt/home/admin]# dig www.google.com @我自建的ChinaDNS服务器</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>; &lt;&lt;&gt;&gt; DiG 9.11.2 &lt;&lt;&gt;&gt; www.google.com @我自建的ChinaDNS服务器</span></div></div><div><div><div>4</div></div><div><span>;; global options: +cmd</span></div></div><div><div><div>5</div></div><div><span>;; Got answer:</span></div></div><div><div><div>6</div></div><div><span>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 25408</span></div></div><div><div><div>7</div></div><div><span>;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>;; OPT PSEUDOSECTION:</span></div></div><div><div><div>10</div></div><div><span>; EDNS: version: 0, flags:; udp: 4096</span></div></div><div><div><div>11</div></div><div><span>;; QUESTION SECTION:</span></div></div><div><div><div>12</div></div><div><span>;www.google.com.      IN  A</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>;; ANSWER SECTION:</span></div></div><div><div><div>15</div></div><div><span>www.google.com.    300  IN  A  172.217.25.4</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>;; Query time: 243 msec</span></div></div><div><div><div>18</div></div><div><span>;; SERVER: 我自建的ChinaDNS服务器#53(我自建的ChinaDNS服务器)</span></div></div><div><div><div>19</div></div><div><span>;; WHEN: Thu Apr 05 18:51:05 CST 2018</span></div></div><div><div><div>20</div></div><div><span>;; MSG SIZE  rcvd: 59</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>解析正常√</p></section><section><h3>B站<a href="#b站"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[MI-3 /opt/home/admin]# dig www.bilibili.com @我自建的ChinaDNS服务器</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>; &lt;&lt;&gt;&gt; DiG 9.11.2 &lt;&lt;&gt;&gt; www.bilibili.com @我自建的ChinaDNS服务器</span></div></div><div><div><div>4</div></div><div><span>;; global options: +cmd</span></div></div><div><div><div>5</div></div><div><span>;; Got answer:</span></div></div><div><div><div>6</div></div><div><span>;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 11000</span></div></div><div><div><div>7</div></div><div><span>;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>;; OPT PSEUDOSECTION:</span></div></div><div><div><div>10</div></div><div><span>; EDNS: version: 0, flags:; udp: 4096</span></div></div><div><div><div>11</div></div><div><span>;; QUESTION SECTION:</span></div></div><div><div><div>12</div></div><div><span>;www.bilibili.com.    IN  A</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span>;; ANSWER SECTION:</span></div></div><div><div><div>15</div></div><div><span>www.bilibili.com.  255  IN  CNAME  bilibili.hdslb.net.</span></div></div><div><div><div>16</div></div><div><span>bilibili.hdslb.net.  134  IN  A  111.231.211.246</span></div></div><div><div><div>17</div></div><div><span>bilibili.hdslb.net.  134  IN  A  140.143.82.138</span></div></div><div><div><div>18</div></div><div><span>bilibili.hdslb.net.  134  IN  A  111.231.212.88</span></div></div><div><div><div>19</div></div><div><span>bilibili.hdslb.net.  134  IN  A  112.117.218.167</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span>;; Query time: 166 msec</span></div></div><div><div><div>22</div></div><div><span>;; SERVER: 我自建的ChinaDNS服务器#53(我自建的ChinaDNS服务器)</span></div></div><div><div><div>23</div></div><div><span>;; WHEN: Thu Apr 05 18:51:14 CST 2018</span></div></div><div><div><div>24</div></div><div><span>;; MSG SIZE  rcvd: 141</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>解析正常√
并且解析到的结果是国内的服务器，没有跑到国外去√</p></section><section><h3>综上<a href="#综上"><span>#</span></a></h3><p>这样的解决方案是可行的（Yeah~</p></section></section>
<section><h2>使用<code>supervisor</code>防止 ChinaDNS 程序挂掉<a href="#使用supervisor防止-chinadns-程序挂掉"><span>#</span></a></h2><p>具体请参考这篇文章中的内容</p><a href="/posts/chinadns-plus-dnsmasq/"><div><div>[ChinaDNS] 无污染的智能路由 DNS 折腾记 #2</div><div>这篇文章算是上一篇文章的完善，教你如何将 ChinaDNS 与 DNSMasq 结合起来用，使其更加稳定并且可以支持 TCP 查询</div><div><span>2018-05-19</span><span>教程</span><span><span>#chinadns</span><span>#dnsmasq</span><span>#dns污染</span><span>#linux</span></span></div></div><div><img src="/usr/uploads/2018/05/1511683458.jpg" alt="" loading="lazy" /></div></a></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/baiduyunshabi/</id>
      <title type="text">IDM + 油猴脚本 实现百度云加速下载</title>
      <published>2018-04-03T15:54:00.000Z</published>
      <updated>2019-12-06T07:45:29.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/baiduyunshabi/"/>
      <summary type="text">临时写的一篇教程，这个方法我早在三年前就已经开始使用了，利用 IDM(Internet Download Manager) + 油猴(Tampermonkey)脚本 解决百度云单线程限速问题，嘛，如果你已经知道了这个方法那么就不需要看这篇文章了XD</summary>
      <content type="html"><![CDATA[<p>临时写的一篇教程，这个方法我早在三年前就已经开始使用了，利用 IDM(Internet Download Manager) + 油猴(Tampermonkey)脚本 解决百度云单线程限速问题，嘛，如果你已经知道了这个方法那么就不需要看这篇文章了XD</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=67014844" target="_blank">「ユニオンっぽいの」/「大気KEN」[pixiv]</a></p>
<hr />
<p>单纯使用 <strong>IDM</strong> 和 <strong>“解决百度云大文件下载限制”油猴脚本</strong> 来加速百度云文件的下载，不再需要使用客户端或者任何第三方直链下载工具</p>
<section><h2>准备工作<a href="#准备工作"><span>#</span></a></h2><section><h3>安装并配置 IDM<a href="#安装并配置-idm"><span>#</span></a></h3><p>直接去 <a href="https://d.idm.party/6.BH%E7%A0%B4%E8%A7%A3%E5%AE%89%E8%A3%85%E7%89%88/" target="_blank">这里</a> 可以下载到 IDM 的破解版，emmmmm，当然如果你有心支持正版那是更好的</p><p>安装完之后打开，如果你用的是 <strong>Chrome</strong> 浏览器，那可能需要安装一个额外的 IDM 支持扩展（会自动提示安装），然后在扩展管理中<strong>勾选“允许访问文件网址”</strong></p><p><img src="/usr/uploads/2018/04/3196094521.png" alt="" /></p><p>安装完后打开主程序，选项-下载，设置“连接类型/速度”为图中的这个，调整线程数为<code>32</code></p><p><img src="/usr/uploads/2018/04/1703574932.png" alt="" /></p></section><section><h3>安装油猴和脚本<a href="#安装油猴和脚本"><span>#</span></a></h3><p>油猴就是 Tampermonkey，一个非常有名的 js 脚本扩展程序</p><p>官网：<a href="https://tampermonkey.net/" target="_blank">https://tampermonkey.net/</a></p><p>根据你的浏览器选择安装对应版本即可</p><p>然后打开 <a href="https://greasyfork.org/zh-CN/scripts/17800-%E8%A7%A3%E5%86%B3%E7%99%BE%E5%BA%A6%E4%BA%91%E5%A4%A7%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E9%99%90%E5%88%B6" target="_blank">解决百度云大文件下载限制</a> 脚本安装页面，安装，一路确定</p></section></section>
<section><h2>如何运用<a href="#如何运用"><span>#</span></a></h2><p>进入网页百度云，找到你需要下载的文件（无论是单个还是多个），<strong>放到一个新建的文件夹中</strong>，然后对着这个文件夹点击下载按钮，以文件夹打包的方式下载</p><p><img src="/usr/uploads/2018/04/4281121180.png" alt="" /></p><p>这样就能摆脱客户端的龟速下载了，正常情况下至少能跑到 5MB/s 以上，但是由于我现在处于校园网环境，网速并不高（已经跑满极速了）</p><p><img src="/usr/uploads/2018/04/4096832864.png" alt="" /></p><div><div><div></div><div>Warning</div></div><div><p>如果你需要下载的文件大小总和超过<code>4GiB</code>，那么可能会发生解压的时候说压缩文件夹损坏的情况，<strong>但是你用 7zip 是可以解压出来的</strong>，而且文件实际上并没有损坏</p></div></div><p>如果你嫌麻烦或者怕产生不测，也可以分小一点控制在<code>4GiB</code>以内，如果是单个超过<code>4GiB</code>的文件，也可以考虑直接点击下载这单个文件而不是通过文件夹打包的方式，不过这样一般下载速度会比打包慢</p><div><div><div></div><div>&gt; <strong>Tips:</strong> 如果是某些热门资源（单个文件），可以考虑在弹出下载框后不要用 IDM 下载，复制 URL 到迅雷中下载，如果有 Hash 相同的(P2P)资源是可以帮助加速下载的，甚至直接高速通道/离线下载</div></div><div></div></div></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/java-array-and-linked/</id>
      <title type="text">[Java] ArrayList 与 LinkedList</title>
      <published>2018-04-03T06:18:00.000Z</published>
      <updated>2018-04-03T06:21:52.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/java-array-and-linked/"/>
      <summary type="text">ArrayList是实现了基于动态数组的数据结构，而LinkedList是基于链表的数据结构。在一次实验中偶然发现并实验了这两者的不同之处，很有意思</summary>
      <content type="html"><![CDATA[<p><code>ArrayList</code>是实现了基于动态数组的数据结构，而<code>LinkedList</code>是基于链表的数据结构。在一次实验中偶然发现并实验了这两者的不同之处，很有意思</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=66704467" target="_blank">「オリジナル」/「100％」[pixiv]</a></p>
<hr />
<p>在写编程实验的时候因为用到了它俩，就突然想测试一下他们的效率，特别是在添加组员这方面</p>
<p>使用学生类作为测试对象</p>
<section><h2>一开始的代码<a href="#一开始的代码"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>public</span><span> </span><span>class</span><span><span> </span><span>StudentList</span><span> </span></span><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>private</span><span> </span><span>ArrayList</span><span>&lt;</span><span>Student</span><span><span>&gt;</span><span> list</span></span><span>;</span></div></div><div><div><div>3</div></div><div><span>  </span><span>//private LinkedList&lt;Student&gt; list;</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>  </span><span>public</span><span> </span><span>StudentList</span><span><span>()</span><span> </span><span>{</span></span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>list </span><span>=</span><span> </span><span>new</span><span> </span><span>ArrayList</span><span>&lt;</span><span>Student</span><span>&gt;();</span></div></div><div><div><div>7</div></div><div><span>    </span><span>//list = new LinkedList&lt;Student&gt;();</span></div></div><div><div><div>8</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span>  </span><span>//添加学生</span></div></div><div><div><div>11</div></div><div><span>  </span><span>public</span><span> </span><span>void</span><span> </span><span>add</span><span>(</span><span>int</span><span><span> </span><span>_id</span><span>,</span></span><span>String</span><span><span> </span><span>_name</span><span>,</span></span><span>int</span><span><span> </span><span>_age</span><span>,</span></span><span>boolean</span><span><span> </span><span>_sex</span><span>,</span></span><span>int</span><span><span> </span><span>_score</span><span>,</span></span><span>int</span><span><span> </span><span>_grade</span><span>)</span><span> </span><span>{</span></span></div></div><div><div><div>12</div></div><div><span>    </span><span>list</span><span>.</span><span>add</span><span>(</span><span>new</span><span> </span><span>Student</span><span>(_id, _name, _age, _sex, _score, _grade));</span></div></div><div><div><div>13</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>14</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>public</span><span> </span><span>class</span><span><span> </span><span>WithStruct</span><span> </span></span><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>private</span><span> </span><span>static</span><span> </span><span>StudentList</span><span> sl </span><span><span>=</span><span> </span></span><span>new</span><span> </span><span>StudentList</span><span><span>()</span><span>;</span></span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>  </span><span>public</span><span> </span><span>static</span><span> </span><span>void</span><span> </span><span>main</span><span>(</span><span>String</span><span><span>[] </span><span>args</span><span>)</span><span> </span><span>{</span></span></div></div><div><div><div>5</div></div><div><span>    </span><span>test</span><span>();</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>  </span><span>private</span><span> </span><span>static</span><span> </span><span>void</span><span> </span><span>test</span><span><span>()</span><span> </span><span>{</span></span></div></div><div><div><div>9</div></div><div><span>    </span><span>//固定随机数种子，生成固定数据方便比较</span></div></div><div><div><div>10</div></div><div><span>    </span><span>Random</span><span><span> </span><span>rd</span><span> </span></span><span><span>=</span><span> </span></span><span>new</span><span> </span><span>Random</span><span>(</span><span>1234567890</span><span>);</span></div></div><div><div><div>11</div></div><div><span>    </span><span>//初始化数据，随机生成学生信息并加入 List</span></div></div><div><div><div>12</div></div><div><span>    </span><span>Timer</span><span><span> </span><span>tm</span><span> </span></span><span><span>=</span><span> </span></span><span>new</span><span> </span><span>Timer</span><span>();  </span><span>//Timer 是自己写的一个很简单的计时器类</span></div></div><div><div><div>13</div></div><div><span>    </span><span>for</span><span>(</span><span>int</span><span><span> </span><span>i</span></span><span>=</span><span>0</span><span><span>;i</span><span>&lt;</span></span><span>1000000</span><span>;i++) {</span></div></div><div><div><div>14</div></div><div><span>      </span><span>sl</span><span>.</span><span>add</span><span>(</span><span>2010000000</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>1000000</span><span>),</span></div></div><div><div><div>15</div></div><div><span>          </span><span>"s."</span><span><span>+</span><span>i, </span></span><span>18</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>4</span><span>),</span></div></div><div><div><div>16</div></div><div><span>          </span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>&gt;</span></span><span>0.5</span><span>?</span><span>true</span><span>:</span><span>false</span><span>,</span></div></div><div><div><div>17</div></div><div><span>          </span><span>100</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>300</span><span>),</span></div></div><div><div><div>18</div></div><div><span>          </span><span>1</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>3</span><span>)</span></div></div><div><div><div>19</div></div><div><span><span>      </span></span><span>);</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>21</div></div><div><span>    </span><span>tm</span><span>.</span><span>stop</span><span>();</span></div></div><div><div><div>22</div></div><div><span>    </span><span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"Initialization: "</span><span>+</span><span>tm</span><span>.</span><span>getTimeMillis</span><span><span>()</span><span>+</span></span><span>"ms"</span><span>);</span></div></div><div><div><div>23</div></div><div><span>    </span><span>//添加1000000名学生</span></div></div><div><div><div>24</div></div><div><span>    </span><span>tm</span><span>.</span><span>start</span><span>();</span></div></div><div><div><div>25</div></div><div><span>    </span><span>for</span><span>(</span><span>int</span><span><span> </span><span>i</span></span><span>=</span><span>1000000</span><span><span>;i</span><span>&lt;</span></span><span>2000000</span><span>;i++) {</span></div></div><div><div><div>26</div></div><div><span>      </span><span>sl</span><span>.</span><span>add</span><span>(</span><span>2010000000</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>1000000</span><span>),</span></div></div><div><div><div>27</div></div><div><span>          </span><span>"sd."</span><span><span>+</span><span>i, </span></span><span>18</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>4</span><span>),</span></div></div><div><div><div>28</div></div><div><span>          </span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>&gt;</span></span><span>0.5</span><span>?</span><span>true</span><span>:</span><span>false</span><span>,</span></div></div><div><div><div>29</div></div><div><span>          </span><span>100</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>300</span><span>),</span></div></div><div><div><div>30</div></div><div><span>          </span><span>1</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>3</span><span>)</span></div></div><div><div><div>31</div></div><div><span><span>      </span></span><span>);</span></div></div><div><div><div>32</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>33</div></div><div><span>    </span><span>tm</span><span>.</span><span>stop</span><span>();</span></div></div><div><div><div>34</div></div><div><span>    </span><span>System</span><span>.</span><span>out</span><span>.</span><span>println</span><span>(</span><span>"Add 10000 students: "</span><span>+</span><span>tm</span><span>.</span><span>getTimeMillis</span><span><span>()</span><span>+</span></span><span>"ms"</span><span>);</span></div></div><div><div><div>35</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>36</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>主要目的就是想测试一下加入成员的时候哪个效率更高，结果如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>ArrayList:</span></div></div><div><div><div>2</div></div><div><span>Initialization: 166ms</span></div></div><div><div><div>3</div></div><div><span>Add 1000000 students: 127ms</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>LinkedList:</span></div></div><div><div><div>6</div></div><div><span>Initialization: 1358ms</span></div></div><div><div><div>7</div></div><div><span>Add 1000000 students: 1302ms</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>一开始看到这个我稍微有点意外，感觉和我想的不太一样……</p><p>因为我觉得链表添加成员，如果是动态数组的话，你需要<code>new</code>一个更大的数组，把原来的数据拷贝过去，然后在末尾将新成员的值拷贝过去；而链表，只需要在末尾加上一个新链就可以了</p><p>（懒得翻他们的源代码，想了想）觉得是因为分配内存空间和拷贝操作的速度是真的远远大于新建链表节点的操作，而且因为链表需要指针，也许指针相关操作也要消耗不少时间，大概只能这样解释</p><p>于是忽然又想到，因为<code>List</code>的<code>add()</code>操作默认是在末尾添加成员，如果是在列首又会如何？</p></section>
<section><h2>修改后的代码<a href="#修改后的代码"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>public</span><span> </span><span>class</span><span><span> </span><span>StudentList</span><span> </span></span><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>//...</span></div></div><div><div><div>3</div></div><div><span>  </span><span>//添加一个指定加入位置的函数</span></div></div><div><div><div>4</div></div><div><span>  </span><span>public</span><span> </span><span>void</span><span> </span><span>add</span><span>(</span><span>int</span><span><span> </span><span>pos</span><span>,</span></span><span>int</span><span><span> </span><span>_id</span><span>,</span></span><span>String</span><span><span> </span><span>_name</span><span>,</span></span><span>int</span><span><span> </span><span>_age</span><span>,</span></span><span>boolean</span><span><span> </span><span>_sex</span><span>,</span></span><span>int</span><span><span> </span><span>_score</span><span>,</span></span><span>int</span><span><span> </span><span>_grade</span><span>)</span><span> </span><span>{</span></span></div></div><div><div><div>5</div></div><div><span>    </span><span>list</span><span>.</span><span>add</span><span>(pos,</span><span>new</span><span> </span><span>Student</span><span>(_id, _name, _age, _sex, _score, _grade));</span></div></div><div><div><div>6</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>7</div></div><div><span>  </span><span>//...</span></div></div><div><div><div>8</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>public</span><span> </span><span>class</span><span><span> </span><span>WithStruct</span><span> </span></span><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>//...</span></div></div><div><div><div>3</div></div><div><span>  </span><span>private</span><span> </span><span>static</span><span> </span><span>void</span><span> </span><span>test</span><span><span>()</span><span> </span><span>{</span></span></div></div><div><div><div>4</div></div><div><span>    </span><span>//初始化过程还是一样的，在末尾插入，并且将实验将数量级调小成 100000，后续因为会很慢</span></div></div><div><div><div>5</div></div><div><span>    </span><span>//...</span></div></div><div><div><div>6</div></div><div><span>    </span><span>//添加100000名学生（数量级调小）</span></div></div><div><div><div>7</div></div><div><span>    </span><span>for</span><span>(</span><span>int</span><span><span> </span><span>i</span></span><span>=</span><span>100000</span><span><span>;i</span><span>&lt;</span></span><span>200000</span><span>;i++) {</span></div></div><div><div><div>8</div></div><div><span>      </span><span>//在首位插入（pos = 0）</span></div></div><div><div><div>9</div></div><div><span>      </span><span>sl</span><span>.</span><span>add</span><span>(</span><span>0</span><span>, </span><span>2010000000</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>1000000</span><span>),</span></div></div><div><div><div>10</div></div><div><span>          </span><span>"sd."</span><span><span>+</span><span>i, </span></span><span>18</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>4</span><span>),</span></div></div><div><div><div>11</div></div><div><span>          </span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>&gt;</span></span><span>0.5</span><span>?</span><span>true</span><span>:</span><span>false</span><span>,</span></div></div><div><div><div>12</div></div><div><span>          </span><span>100</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>300</span><span>),</span></div></div><div><div><div>13</div></div><div><span>          </span><span>1</span><span><span>+</span><span>(</span></span><span>int</span><span>)(</span><span>rd</span><span>.</span><span>nextDouble</span><span><span>()</span><span>*</span></span><span>3</span><span>)</span></div></div><div><div><div>14</div></div><div><span><span>      </span></span><span>);</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>16</div></div><div><span>    </span><span>//...</span></div></div><div><div><div>17</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>18</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>结果：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>ArrayList:</span></div></div><div><div><div>2</div></div><div><span>Initialization: 31ms</span></div></div><div><div><div>3</div></div><div><span>Add 1000000 students: 2028ms</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>LinkedList:</span></div></div><div><div><div>6</div></div><div><span>Initialization: 30ms</span></div></div><div><div><div>7</div></div><div><span>Add 1000000 students: 21ms</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>链表<code>LinkedList</code>的优势瞬间就体现出来了，这次和预想的没有什么偏差</p><p>如果是动态数组，在首位插入的话，就需要<code>new</code>一个数组，然后将原来的数组移过去，<strong>并且每次都要相对往后移一位</strong>，空出首位给新添加的成员，也许就是因为这个移动操作导致效率变得很低
（当然我自己也瞎想过，如果是在拷贝的时候直接就错开一位去拷贝，而不是事后移动，那么会不会更快？那为什么一开始编写这些源码的人没有这样考虑？又或者是因为考虑到系统底层的拷贝操作效率之类的而没有选择这么做？……然而我还要写实验，先饶了自己的大脑，而且也没时间去自己写一个来实验了……）</p><p>如果是链表，那么只需要在头指针处加入一个新节点就好了，不需要进行繁重的遍历赋值工作</p><p>而且我发现，在首位插入和在末尾插入，对<code>LinkedList</code>来说，几乎是一样的，也就是说实际上<code>LinkedList</code>是有两个指针，一个头一个尾？</p><p>有了点想法，于是又稍微改了一下函数来实验</p></section>
<section><h2>修改²后的代码<a href="#修改后的代码-1"><span>#</span></a></h2><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>public</span><span> </span><span>class</span><span><span> </span><span>WithStruct</span><span> </span></span><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>//...</span></div></div><div><div><div>3</div></div><div><span>  </span><span>private</span><span> </span><span>static</span><span> </span><span>void</span><span> </span><span>test</span><span><span>()</span><span> </span><span>{</span></span></div></div><div><div><div>4</div></div><div><span>    </span><span>//...</span></div></div><div><div><div>5</div></div><div><span>    </span><span>//添加10000名学生（数量级再次调小）</span></div></div><div><div><div>6</div></div><div><span>    </span><span>for</span><span>(</span><span>int</span><span><span> </span><span>i</span></span><span>=</span><span>10000</span><span><span>;i</span><span>&lt;</span></span><span>20000</span><span>;i++) {</span></div></div><div><div><div>7</div></div><div><span>      </span><span>//在中间位置插入（pos = i/2）</span></div></div><div><div><div>8</div></div><div><span>      </span><span>sl</span><span>.</span><span>add</span><span><span>(i</span><span>/</span></span><span>2</span><span>, </span><span>//...</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>);</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>11</div></div><div><span>    </span><span>//...</span></div></div><div><div><div>12</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>13</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>结果：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>ArrayList:</span></div></div><div><div><div>2</div></div><div><span>Initialization: 6ms</span></div></div><div><div><div>3</div></div><div><span>Add 10000 students: 12ms</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>LinkedList:</span></div></div><div><div><div>6</div></div><div><span>Initialization: 8ms</span></div></div><div><div><div>7</div></div><div><span>Add 10000 students: 501ms</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这就对了，在中间插入插入的时候，<code>LinkedList</code>要比<code>ArrayList</code>慢上不止一点，比末尾插入还惨很多，而且数量级越大差的也越大，因为<code>LinkedList</code>只有首位有指针，因此在中间插入的时候指针移动造成的时间开销是最大的</p></section>
<section><h2>结论<a href="#结论"><span>#</span></a></h2><p>如果是今后使用的话，也许<code>ArrayList</code>还是首选，从添加/删除数据的角度来说，只要操作的位置不是很靠近头部，<code>ArrayList</code>都具有明显优势；而对于访问数据来说，<code>ArrayList</code>更具有优势，因为<code>LinkedList</code>访问成员需要移动指针</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/acme-le-wc/</id>
      <title type="text">使用 acme.sh 申请 Let&apos;s Encrypt 泛域名SSL证书详细教程</title>
      <published>2018-04-01T15:07:00.000Z</published>
      <updated>2019-05-05T07:10:33.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/acme-le-wc/"/>
      <summary type="text">Let&apos;s Encrypt 泛域名SSL已经出来挺长一段时间了，昨天才有需要，因此尝试了一下部署。 一开始看的是 Leonn 的教程，但不是很详细，自己弄懂了流程之后决定写一篇详细一点的教程（使用 CloudXNS 的 API 添加记录进行验证）。</summary>
      <content type="html"><![CDATA[<p>Let’s Encrypt 泛域名SSL已经出来挺长一段时间了，昨天才有需要，因此尝试了一下部署。</p>
<p>一开始看的是 Leonn 的教程，但不是很详细，自己弄懂了流程之后决定写一篇详细一点的教程（使用 CloudXNS 的 API 添加记录进行验证）。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=67649219" target="_blank">「アビーかわいい！！」/「おみなえし」[pixiv]</a>
阿比我老婆！</p>
<hr />
<a href="https://github.com/Neilpang/acme.sh" target="_blank"><div><div><div><div></div><div>Neilpang</div></div><div>/</div><div>acme.sh</div></div><div></div></div><div>A pure Unix shell script ACME client for SSL / TLS certificate automation</div><div><div>—</div><div>—</div><div>GPL-3.0</div><span>Shell</span></div></a>
<p><code>acme.sh</code>是一个实现了 acme 协议的脚本，可以从 Let’s Encrypt 生成免费的SSL证书</p>
<p>本文只给出配合解析商 API 申请泛域名证书的过程教程，<code>acme.sh</code>还有很多很强大的功能例如配合 Nginx 或者 Apache 等自动申请证书，请自行查看 github 项目 wiki 发掘</p>
<p><a href="https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E" target="_blank">https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E</a></p>
<section><h2>1. 部署 acme.sh<a href="#1-部署-acmesh"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>curl</span><span> </span><span>https://get.acme.sh</span><span> | </span><span>sh</span></div></div><div><div><div>2</div></div><div><span># 或者</span></div></div><div><div><div>3</div></div><div><span>wget</span><span> </span><span>-O-</span><span> </span><span>https://get.acme.sh</span><span> | </span><span>sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装过程不会污染已有的系统任何功能和文件，<code>acme.sh</code>会被自动安装到<code>~/.acme.sh/</code>中</p></section>
<section><h2>2. 获取 CloudXNS 的 API 信息<a href="#2-获取-cloudxns-的-api-信息"><span>#</span></a></h2><p><code>acme.sh</code>目前支持 cloudflare, dnspod, cloudxns, godaddy 以及 ovh 等数十种解析商的 API，可以自动添加 TXT 记录来验证，不需要人工操作，十分便捷</p><p>详细可以看
<a href="https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md" target="_blank">https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md</a></p><p>这里以 CloudXNS 为例，首先登录 CloudXNS，点击右上角帐户名-API管理，创建 API 之后你会得到 API KEY 和 SECRET KEY，记下他们，<strong>并且在“设置API白名单”中加上你服务器的 IP</strong>（其实不加也行，但是如果你在申请的时候出了 API 访问错误就尝试着加一下）</p></section>
<section><h2>3. 开始申请证书<a href="#3-开始申请证书"><span>#</span></a></h2><p>首先设置临时环境变量，配置我们刚才得到的 API 信息</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># CloudXNS</span></div></div><div><div><div>2</div></div><div><span>export</span><span> </span><span>CX_Key</span><span>=</span><span>"你的 API KEY"</span></div></div><div><div><div>3</div></div><div><span>export</span><span> </span><span>CX_Secret</span><span>=</span><span>"你的 SECRET KEY"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>其他解析商的环境变量名是不一样的，详情去这里看
<a href="https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md" target="_blank">https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md</a></p><p>这个临时环境变量只需配置这一次，当成功申请证书后，API 信息会被自动保存在<code>~/.acme.sh/account.conf</code>，下次你使用<code>acme.sh</code>的时候会被自动使用</p><p>接下来正式开始申请泛域名证书，将<code>example.com</code>换成你自己的域名</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>~/.acme.sh/acme.sh --issue --dns dns_cx -d example.com -d </span><span>'*.example.com'</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>--dns dns_cx</code>参数表示使用 CloudXNS 的 API，如果是其他解析商，同样的，从上面那个链接可以看到对应参数</p><p>然后静静等待即可</p><p><img src="/usr/uploads/2018/04/2357973391.png" alt="" /></p></section>
<section><h2>4. 得到证书<a href="#4-得到证书"><span>#</span></a></h2><p>申请完成后屏显会输出证书路径</p><p>证书是<code>fullchain.cer</code>
密匙是<code>example.com.key</code></p><p>由于证书默认（在你没安装宝塔等同样调用 acme 签发证书的面板时）会在 acme 的内部目录<code>~/.acme.sh/</code>中生成，不建议直接使用该路径填写至 nginx 等配置中，而是使用<code>--installcert</code>命令，具体请参考↓</p><p><a href="https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E#3-copy%E5%AE%89%E8%A3%85-%E8%AF%81%E4%B9%A6" target="_blank">https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E#3-copy%E5%AE%89%E8%A3%85-%E8%AF%81%E4%B9%A6</a></p></section>
<section><h2>关于证书续期<a href="#关于证书续期"><span>#</span></a></h2><p>Let’s Encrypt 证书的有效期为三个月，<code>acme.sh</code>会每隔60天自动帮你续期，无需你进行任何干预</p><p>如果你想强制续期或者取消自动续期可以看
<a href="https://github.com/Neilpang/acme.sh#11-how-to-renew-the-certs" target="_blank">https://github.com/Neilpang/acme.sh#11-how-to-renew-the-certs</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/bilibili-rss/</id>
      <title type="text">[bilibili2rss] 用 RSS 订阅你喜欢的B站UP主</title>
      <published>2018-03-31T09:33:00.000Z</published>
      <updated>2018-12-11T10:20:56.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/bilibili-rss/"/>
      <summary type="text">这是一个由黎明余光开发的 PHP 程序，可以让你以 RSS 方式订阅UP主</summary>
      <content type="html"><![CDATA[<p>这是一个由黎明余光开发的 PHP 程序，可以让你以 RSS 方式订阅UP主</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=66001476" target="_blank">「哔哩哔哩2233娘」/「一只柏伯」[pixiv]</a></p>
<hr />
<p>rt，不过只能获取到视频订阅，动态貌似是不行滴</p>
<a href="https://github.com/LiMingYuGuang/bilibili2rss" target="_blank"><div><div><div><div></div><div>LiMingYuGuang</div></div><div>/</div><div>bilibili2rss</div></div><div></div></div><div>利用 RSS 订阅 B 站 UP主</div><div><div>—</div><div>—</div><div>MIT</div><span>PHP</span></div></a>
<p><a href="https://blog.lim-light.com/archives/bilibili-rss.html" target="_blank">作者博客原文</a></p>
<p><strong>New: 建议直接使用新科技</strong></p>
<a href="/posts/rsshub/"><div><div>[RSSHub] 万物皆可RSS</div><div>这是一个轻量、易于扩展的 RSS 生成器，可以给任何奇奇怪怪的内容生成 RSS 订阅源（真好玩耶</div><div><span>2018-05-25</span><span>好东西就应该分享出来</span><span><span>#rsshub</span><span>#rss</span><span>#订阅</span></span></div></div><div><img src="/usr/uploads/2018/05/1821894043.jpg" alt="" loading="lazy" /></div></a>
<section><h2>效果预览<a href="#效果预览"><span>#</span></a></h2><p><img src="/usr/uploads/2018/03/3663657416.png" /></p></section>
<section><h2>用户ID怎么看<a href="#用户id怎么看"><span>#</span></a></h2><p>打开你的B站个人空间，例如我的个人空间网址为</p><p><a href="https://space.bilibili.com/901801/" target="_blank">https://space.bilibili.com/901801/</a></p><p>那么用户ID即为<code>901801</code></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/backup-to-github/</id>
      <title type="text">每日自动将你的网站备份到Github 告别数据丢失</title>
      <published>2018-03-28T15:42:00.000Z</published>
      <updated>2019-01-12T04:32:08.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/backup-to-github/"/>
      <summary type="text">最近听到许多数据丢失的惨况，有人提议为何不用 Github 去备份网站？而且这样还能看到每次 commit 的更改情况，随时任意回档。一拍大腿，亲自试验，做出成品，写下文章，一气呵成（</summary>
      <content type="html"><![CDATA[<p>最近听到许多数据丢失的惨况，有人提议为何不用 Github 去备份网站？而且这样还能看到每次 commit 的更改情况，随时任意回档。一拍大腿，亲自试验，做出成品，写下文章，一气呵成（</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=61995825" target="_blank">「レイマリなプレイマット」/「望月椎那」[pixiv]</a></p>
<hr />
<p>Github 已经允许免费用户创建无限量的私有 repo，皆大欢喜</p>
<p>本文将会给具体实现步骤，以及过程中用到的所有命令的解释</p>
<p>步骤是死的，人是活的，在一些不需要完全遵守的地方（比如各种使用的路径之类的）可以根据自己的需要和习惯自行改变</p>
<section><h2>1. 一点微小的事先准备<a href="#1-一点微小的事先准备"><span>#</span></a></h2><p>首先的首先，你当然需要一个 Github 账户（</p><p>然后接下来是在服务器上的操作：</p><p>进入一个你喜欢的安全的目录，此处直接以<code>/root</code>为例</p><p>参考下命令创建一个 RSA 密匙</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/root</span></div></div><div><div><div>2</div></div><div><span>ssh-keygen</span><span> </span><span>-t</span><span> </span><span>rsa</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后根据提示输入生成密匙的文件名，此处举例输入<code>github</code>，要你输入 passphrase 的时候直接不输入回车就行</p><p>完成后会有类似这样的显示，并且你会在当前目录下得到<code>github</code>和<code>github.pub</code>这两个文件</p><p><img src="/usr/uploads/2018/03/1121566125.png" alt="" /></p><p>接着用<code>cat</code>命令查看<code>github.pub</code>文件的内容，并复制下来</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cat</span><span> </span><span>github.pub</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>还没完，回到你的 Github 页面，点右上角头像，Settings，左边“SSH and GPG keys”，右上角“New SSH key”</p><p>然后将刚才复制的内容粘贴到“Key”输入框中，上方的“Tittle”自己随意输入，然后“Add SSH key”</p><p><img src="/usr/uploads/2018/03/1922402762.png" alt="" /></p><p>这样事前准备就完成了，嗯，其实就是加一个 SSH 密匙到 Github，这样可以方便后续 Github 项目的同步</p></section>
<section><h2>2. 创建一个私密 Github 项目<a href="#2-创建一个私密-github-项目"><span>#</span></a></h2><p>要备份当然首先得有一个 Github 项目啦</p><p>直接右上角新建项目</p><p><img src="/usr/uploads/2018/03/137357443.png" alt="" /></p><p>记得选成私密（Private）就行，不然你整个网站就被别人盗走了……</p></section>
<section><h2>3. 在你的站点目录下初始化你的 Github 项目<a href="#3-在你的站点目录下初始化你的-github-项目"><span>#</span></a></h2><p>进入你的站点所在目录，并执行一系列 git 初始化命令，参考以下代码</p><p>假设我的网站在<code>/www/wwwroot/xxx.com</code>，Github 项目为<code>Tsuk1ko/test</code></p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/www/wwwroot/xxx.com</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>init</span></div></div><div><div><div>3</div></div><div><span>git</span><span> </span><span>remote</span><span> </span><span>add</span><span> </span><span>origin</span><span> </span><span>git@github.com:Tsuk1ko/test.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>第三句的目的是设定当前项目的同步方式为 SSH（是的，我们准备步骤中创建的密匙就是要用在这上面），并指定了仓库地址<code>Tsuk1ko/test</code></p><section><h3>为什么用 SSH 方式而不用 HTTPS 方式？<a href="#为什么用-ssh-方式而不用-https-方式"><span>#</span></a></h3><p>HTTPS 方式是要你输入用户名密码的，虽然你可以直接将用户名密码输入到链接中，像这样<code>https://yourname:password@github.com/name/project.git</code>，但是在链接中明文输入用户名密码是极不安全的，容易被监听窃取</p><p>另外还有一种办法是使用<code>git config --global credential.helper store</code>，这样会在<code>.git</code>中生成一个配置文件来储存你的用户名密码，但是你要意识到你现在所处的目录是一个网站，如果你忘了在网站配置中禁止对<code>.git</code>的访问，那么你的用户名密码也会很容易泄露</p><p>所以，SSH 还是最为稳妥的一种方式</p></section></section>
<section><h2>4. 尝试同步当前站点到 Github 项目<a href="#4-尝试同步当前站点到-github-项目"><span>#</span></a></h2><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/www/wwwroot/xxx.com</span></div></div><div><div><div>2</div></div><div><span>git</span><span> </span><span>add</span><span> </span><span>-A</span></div></div><div><div><div>3</div></div><div><span>git</span><span> </span><span>commit</span><span> </span><span>-m</span><span> </span><span>"backup"</span></div></div><div><div><div>4</div></div><div><span>ssh-agent</span><span> </span><span>bash</span></div></div><div><div><div>5</div></div><div><span>ssh-add</span><span> </span><span>/root/github</span></div></div><div><div><div>6</div></div><div><span>git</span><span> </span><span>push</span><span> </span><span>-u</span><span> </span><span>origin</span><span> </span><span>master</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h3>命令解释<a href="#命令解释"><span>#</span></a></h3><ol>
<li>进入网站目录</li>
<li>把目录下所有文件变化（增、删、改）提交到暂存区
如果你想只增、改而不删，那么可以用<code>git add .</code>命令代替</li>
<li>提交所有更改，这个<code>"backup"</code>可以随意填写，没有影响，其实就是你提交改动的时候的说明，但是 commit 的时候必须要有这个说明</li>
<li>启动 SSH 密钥管理器</li>
<li>将之前我们创建的<code>github</code>密匙文件添加到密匙管理器中</li>
<li>推送所有更改到 Github 项目</li>
</ol><p>执行完后你应该能看到文件上传进度等回显，等待执行完毕，然后去自己的私密项目刷新一下，你的网站是不是整个被上传上去了？（好耶！</p><p><img src="/usr/uploads/2018/03/963492736.png" alt="" /></p></section></section>
<section><h2>5. 设定每天自动同步<a href="#5-设定每天自动同步"><span>#</span></a></h2><p>实际上就是使用 crontab 定时任务每天<code>git push</code>一次，但是操作与上面略有不同，并且有一些需要注意的点</p><p>如果你没有安装 crontab，那么百度一下安装方法自行安装，此处不再赘述</p><p>当然，如果你使用宝塔面板等自带 crontab 管理功能的就更方便了，接下来的步骤请自行灵性应对</p><p>首先找个你喜欢的目录，创建一个脚本例如<code>/root/backup_website.sh</code>，然后写入以下内容并保存</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/bash</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>/www/wwwroot/xxx.com</span></div></div><div><div><div>3</div></div><div><span>git</span><span> </span><span>add</span><span> </span><span>-A</span></div></div><div><div><div>4</div></div><div><span>git</span><span> </span><span>commit</span><span> </span><span>-m</span><span> </span><span>"backup"</span></div></div><div><div><div>5</div></div><div><span>ssh-add</span><span> </span><span>/root/github</span></div></div><div><div><div>6</div></div><div><span>git</span><span> </span><span>push</span><span> </span><span>-u</span><span> </span><span>origin</span><span> </span><span>master</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>接着编辑 crontab 的配置文件，一般是<code>/var/spool/cron/crontabs/root</code>，在最下面加入这行，然后保存退出</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>30 3 * * * ssh-agent bash /root/backup_website.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这条 crontab 命令代表每天凌晨3&lt;30分执行&gt;<code>ssh-agent bash /root/backup_website.sh</code>命令</p><p>接着重启一下 crontab 使新配置文件生效</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># CentOS6 系列及以下</span></div></div><div><div><div>2</div></div><div><span>service</span><span> </span><span>crond</span><span> </span><span>restart</span></div></div><div><div><div>3</div></div><div><span># CentOS7 系列</span></div></div><div><div><div>4</div></div><div><span>systemctl</span><span> </span><span>restart</span><span> </span><span>crond.service</span></div></div><div><div><div>5</div></div><div><span># Ubuntu / Debian 系列</span></div></div><div><div><div>6</div></div><div><span>/etc/init.d/cron</span><span> </span><span>restart</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>搞定，这样每天凌晨3&lt;30的时候就会自动备份你的网站到&gt; Github 了，想改成其他时间也可以，自行更改 crontab 命令即可</p><p>不过这只是备份了网站目录，数据库之类的也要记得勤备份，或者你也可以仿照这样的方式每天自动把数据库导出到一个地方然后同步到另外一个 Github 项目</p><section><h3>注意点解释<a href="#注意点解释"><span>#</span></a></h3><p>细心的你肯定注意到了此步骤和上一步骤中命令的不同，关键就在于<code>ssh-agent</code>上</p><p>我们是使用 SSH 去同步 git 的，因此在同步之前，服务器上也必须先添加 SSH 密匙（<code>ssh-add</code>）才能连接到 Github</p><p>你可以试一下，重开一个 SSH 窗口，直接使用<code>ssh-add /root/github</code>命令，是无法添加密匙的，会报<code>Could not open a connection to your authentication agent.</code>，因为密匙管理器<code>ssh-agent</code>并没有运行</p><p>但是如果你使用以下这样的脚本内容</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/bash</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>/www/wwwroot/xxx.com</span></div></div><div><div><div>3</div></div><div><span>git</span><span> </span><span>add</span><span> </span><span>-A</span></div></div><div><div><div>4</div></div><div><span>git</span><span> </span><span>commit</span><span> </span><span>-m</span><span> </span><span>"backup"</span></div></div><div><div><div>5</div></div><div><span>ssh-agent</span><span> </span><span>bash</span><span>        </span><span>#加上这句</span></div></div><div><div><div>6</div></div><div><span>ssh-add</span><span> </span><span>/root/github</span></div></div><div><div><div>7</div></div><div><span>git</span><span> </span><span>push</span><span> </span><span>-u</span><span> </span><span>origin</span><span> </span><span>master</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后直接<code>bash /root/backup_website.sh</code>运行，你会发现目录切换到了<code>/www/wwwroot/xxx.com</code>，然后，什么事也没发生</p><p>这是为什么呢</p><p>因为当你直接运行<code>ssh-agent bash</code>的时候，实际上是相当于使用<code>ssh-agent</code>新建了一个<code>bash</code>窗口，然后……就没有然后了，后面的命令并没有在这个新建的窗口中运行</p><p>大概像这样</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/bash</span></div></div><div><div><div>2</div></div><div><span># 以下命令在原本的 bash 窗口中运行</span></div></div><div><div><div>3</div></div><div><span>cd</span><span> </span><span>/www/wwwroot/xxx.com</span></div></div><div><div><div>4</div></div><div><span>git</span><span> </span><span>add</span><span> </span><span>-A</span></div></div><div><div><div>5</div></div><div><span>git</span><span> </span><span>commit</span><span> </span><span>-m</span><span> </span><span>"backup"</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># 当运行到这一句的时候，ssh-agent 新建了一个 bash 窗口</span></div></div><div><div><div>8</div></div><div><span># 而你也看到了这个窗口</span></div></div><div><div><div>9</div></div><div><span>ssh-agent</span><span> </span><span>bash</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span># 但是下面这两句仍然是在原本的 bash 窗口中运行的</span></div></div><div><div><div>12</div></div><div><span>ssh-add</span><span> </span><span>/root/github</span></div></div><div><div><div>13</div></div><div><span>git</span><span> </span><span>push</span><span> </span><span>-u</span><span> </span><span>origin</span><span> </span><span>master</span></div></div><div><div><div>14</div></div><div><span># 只是因为你执行完 ssh-agent bash 之后，切换到了新的 bash 窗口</span></div></div><div><div><div>15</div></div><div><span># 所以你并不会看到这两句命令执行的回显</span></div></div><div><div><div>16</div></div><div><span># 实际上 ssh-add 将会因为我前面说过的原因而不能添加密匙</span></div></div><div><div><div>17</div></div><div><span># 所以 git push 自然会因为没有密匙而失败</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>所以我才不在脚本中执行<code>ssh-agent</code>，而是放到了最外层的 crontab 命令上</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ssh-agent</span><span> </span><span>bash</span><span> </span><span>/root/backup_website.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这样执行，相当于用<code>ssh-agent</code>创建了一个<code>bash</code>，而这个<code>bash</code>会接收参数<code>/root/backup_website.sh</code>，运行这个脚本，也就是在<code>ssh-agent</code>运行的情况下执行了后续的<code>ssh-add</code>等命令</p><p>这样才可以成功实现 SSH 访问 git 并同步</p><p>我一开始也是碰到了这个坑，不过弄明白之后感觉对命令行有了更深的理解，总归是没有白忙活</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/cloudreve-docker/</id>
      <title type="text">[Cloudreve] 树洞网络云盘 使用Docker一键部署</title>
      <published>2018-03-26T13:27:00.000Z</published>
      <updated>2019-11-09T03:50:16.000Z</updated>
      <author><name>极光柠檬</name></author>
      <link rel="alternate" href="https://moe.best/posts/cloudreve-docker/"/>
      <summary type="text">Cloudreve 是一款基于 ThinkPHP 构建的网盘系统，由“树洞外链”的作者开发，能够助您以较低成本快速搭建起公私兼备的网盘，并且还有能快速对接目前各家常用云储存等多项特性。 极光柠檬开发了这款网盘系统的 Docker 镜像，本站受邀转载其文章。</summary>
      <content type="html"><![CDATA[<p>Cloudreve 是一款基于 ThinkPHP 构建的网盘系统，由“树洞外链”的作者开发，能够助您以较低成本快速搭建起公私兼备的网盘，并且还有能快速对接目前各家常用云储存等多项特性。</p>
<p><a href="https://blog.ilemonrain.com" target="_blank">极光柠檬</a>开发了这款网盘系统的 Docker 镜像，本站受邀转载其文章。</p>
<hr />
<p><a href="https://cloudreve.org" target="_blank">Cloudreve 官网</a></p>
<p>以下语气均照搬原文，我可没有那么拽啊！（。</p>
<section><h2>几句废话<a href="#几句废话"><span>#</span></a></h2><p>此镜像目前仍然处于开发中的阶段，不建议大量用在生产环境中！</p><p>如果有任何符合如下状况的问题：</p><ul>
<li>确认正确填写启动命令行的前提下，镜像启动过程报错或者执行命令后，超过10分钟依然没有完成部署；</li>
<li>经过检查，确认我写的代码存在致命BUG (主要是<code>Dockerfile</code>和<code>entrypoint.sh</code>)；</li>
<li>部署完成后，访问网盘地址，得到错误提示</li>
</ul><p>请在此文章下留言，或者E-mail到：<code>ilemonrain@ilemonrain.com</code>，并请附带详细的错误信息，接受以下几种形式的信息：</p><ul>
<li>“docker logs [容器ID]” 返回结果；</li>
<li>访问网盘得到的错误信息 (请打开<code>Application/config.php</code>中 debug 开关，以获得详细出错原因)</li>
</ul><p>不接受以下反馈以及E-mail来信：</p><ul>
<li>如何部署（我在 Docker Hub 上写的还不够详细么？不够？我再写点如何？）</li>
<li>为什么部署这么慢（自己找原因，服务器性能不够/服务器网络差/国内服务器/填写错误的参数）</li>
<li>什么时候更新/能不能更新XX功能（随缘，我想写就写点，不想写就咕咕咕，sorry，有技术真的是为所欲为）</li>
</ul></section>
<section><h2>镜像说明<a href="#镜像说明"><span>#</span></a></h2><p>此镜像基于<code>ilemonrain/lamp</code>作为母镜像，进行了修改以适配 Cloudreve 的环境要求（但我知道有些地方还是没优化到位……）。</p><p>到目前为止，此镜像已经集成：</p><ul>
<li>一套LAMP环境，包括：</li>
<li>L：Alpine Linux 3.7.0</li>
<li>A：Apache 2.4.29</li>
<li>M：MariaDB 10.1.28</li>
<li>P：PHP 7.1.15</li>
<li>Cloudreve (使用 Composer+Git 同步官网最新版本)</li>
<li>Google 2FA 组件 (用于支持 Google 两步验证)</li>
<li>启动过程中的日志追踪功能 (<code>docker run -t</code>或者<code>docker logs</code>)</li>
</ul><p>计划中 (也可能鸽掉不做) 的功能：</p><ul>
<li>Apache 2 SSL支持 (目前正在做)</li>
<li>Let’s Encrypt 支持 (用于部署时自动申请SSL证书)</li>
<li>Sendfile 下载支持 (Apache2 的扩展，用于减轻服务器下载压力)</li>
<li>一些 Apache2/PHP7/MariaDB 的性能优化</li>
<li>目前完全是一时冲动（什么鬼）写出来的镜像，所以以后可能会坑掉不写，如果有什么好的建议或者紧急BUG提交，请 Email 到：<code>ilemonrain@ilemonrain.com</code>，谢谢你们的支持！</li>
</ul></section>
<section><h2>部署教程<a href="#部署教程"><span>#</span></a></h2><div><div><div></div><div>Warning</div></div><div><p>由于 Docker 的特殊性(虚拟化要求)，此教程不适用于 OpenVZ 虚拟化架构！OpenVZ 虚拟化的请等待我的后续部署教程！</p></div></div><section><h3>1. 检测你的服务器虚拟化类型！<a href="#1-检测你的服务器虚拟化类型"><span>#</span></a></h3><p>如何检测自己的服务器虚拟化类型：</p><ul>
<li>CentOS/Fedora:</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>virt-what</span><span> </span><span>-y</span></div></div><div><div><div>2</div></div><div><span>virt-what</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>Ubuntu/Debian:</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>virt-what</span><span> </span><span>-y</span></div></div><div><div><div>2</div></div><div><span>virt-what</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>返回以下结果，请继续往下阅读教程：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>KVM</span></div></div><div><div><div>2</div></div><div><span>Xen</span></div></div><div><div><div>3</div></div><div><span>Xen-PV</span></div></div><div><div><div>4</div></div><div><span>Xen-HVM</span></div></div><div><div><div>5</div></div><div><span>VMware</span></div></div><div><div><div>6</div></div><div><span>不显示任何结果 (多数情况下是独服)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>返回以下结果，说明此教程不适合你的服务器：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>OpenVZ</span></div></div><div><div><div>2</div></div><div><span>Docker</span></div></div><div><div><div>3</div></div><div><span>乱七八糟的东西 (virt-what运行报错)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>2. 安装Docker环境<a href="#2-安装docker环境"><span>#</span></a></h3><p>首先，在你的服务器上，执行以下命令，安装 Docker 环境并设为开机自启动：</p><ul>
<li>CentOS/Fedora:</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>docker</span><span> </span><span>-y</span></div></div><div><div><div>2</div></div><div><span>systemctl</span><span> </span><span>enable</span><span> </span><span>docker</span></div></div><div><div><div>3</div></div><div><span>systemctl</span><span> </span><span>start</span><span> </span><span>docker</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>Ubuntu/Debian:</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>docker.io</span></div></div><div><div><div>2</div></div><div><span>systemctl</span><span> </span><span>enable</span><span> </span><span>docker</span></div></div><div><div><div>3</div></div><div><span>systemctl</span><span> </span><span>start</span><span> </span><span>docker</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>之后，运行命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker info</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>来确定你的Docker是否成功启动。如果返回关于你的Docker的相关信息，就像这样：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>[root@docker-host ~]# docker info</span></div></div><div><div><div>2</div></div><div><span>Containers: 0</span></div></div><div><div><div>3</div></div><div><span>Running: 0</span></div></div><div><div><div>4</div></div><div><span>Paused: 0</span></div></div><div><div><div>5</div></div><div><span>Stopped: 0</span></div></div><div><div><div>6</div></div><div><span>Images: 0</span></div></div><div><div><div>7</div></div><div><span>Server Version: 1.13.1</span></div></div><div><div><div>8</div></div><div><span>(.........)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果返回以下信息，则说明你的 Docker 没有正确启动：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>一个我常遇到的问题：selinux 权限限制。</p><p>遇到这种情况，请执行命令：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>setenforce 0</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后再尝试重新启动 Docker 进程，很多时候都会奏效。</p></section><section><h3>3. 下载Docker镜像到本地<a href="#3-下载docker镜像到本地"><span>#</span></a></h3><p>执行以下命令，将 Docker 镜像从 Docker Hub 上拉回本地：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker pull ilemonrain/cloudreve</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>拉取镜像的速度取决于你服务器的国际出口速度。</p><p>一般情况下，美帝的服务器基本上就是秒速拉回来，国内的服务器往往非常慢。</p><p>请参考这里 如何为国内服务器加速 Docker Hub 镜像拉取：</p><p><a href="https://www.docker-cn.com/registry-mirror" target="_blank">https://www.docker-cn.com/registry-mirror</a></p><p>等待拉取结束后，继续部署过程。</p></section><section><h3>4. 启动Docker镜像<a href="#4-启动docker镜像"><span>#</span></a></h3><p>启动命令格式如下：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>docker run [-d/-t] -p 80:80 -e CLOUDREVE_URL="[Cloudreve URL]" -v /cloudreve:/cloudreve --name docker-cloudreve ilemonrain/cloudreve</span></div></div></code></pre><div><div></div><div></div></div></figure></div><section><h4>启动命令行说明：<a href="#启动命令行说明"><span>#</span></a></h4><p><strong>-d/-t</strong>：决定是以后台运行模式启动或是前台监控模式启动。</p><ul>
<li>使用<code>-d</code>参数启动，镜像将不会输出任何日志到你的Console，直接以 Daemon 模式启动。Deamon 模式启动下，可以使用<code>docker logs docker-cloudreve</code>命令显示启动日志。</li>
<li>使用<code>-t</code>参数启动，将会直接 Attach 你的镜像到你的 Console，这个模式启动下，你可以直观的看到镜像的启动过程，适合于初次部署镜像，以及镜像 Debug部署使用。你可以使用 Ctrl+C 将 Docker 镜像转入后台运行，使用 docker logs docker-cloudreve 命令显示启动日志。</li>
</ul><p><strong>-p 80&lt;80&gt;</strong>：暴露你的 Docker 容器内部的 80 端口，到你容器外部的 80 端口。目前由于开发状态原因，不建议修改此端口。</p><p><strong>-e CLOUDREVE_URL=“[Cloudreve URL]“</strong>：Cloudreve 绑定的地址，此参数务必严格填写，不能丢掉 http/https 前缀和结尾的斜杠！</p><ul>
<li>以下的地址是正确的：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>http://cloudreve.example.com/</span></div></div><div><div><div>2</div></div><div><span>https://netdisk.example.com/</span></div></div><div><div><div>3</div></div><div><span>http://123.234.123.234/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>以下的地址是错误的：</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>cloudreve.example.com</span></div></div><div><div><div>2</div></div><div><span>netdisk.example.com/</span></div></div><div><div><div>3</div></div><div><span>http://cloudreve.example.com</span></div></div><div><div><div>4</div></div><div><span>https://netdisk.example.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>将会在后期版本中加入对 HTTPS 的支持，目前请使用 http 进行部署！没有域名的话，可以换成IP！</li>
</ul><p><strong>-v /cloudreve:/cloudreve</strong>：将Docker容器中的<code>/cloudreve</code>目录，映射到宿主机的<code>/cloudreve目录</code>，冒号前面的是映射路径，冒号后的为容器中路径 <strong>(强烈建议进行映射，以确保容器中数据的安全，避免在容器意外崩溃时导致数据丢失)</strong></p><p>容器中可以映射的路径：</p><ul>
<li><code>/cloudreve</code> ： Cloudreve 程序目录以及网盘文件目录</li>
<li><code>/var/lib/mysql</code> ： MariaDB (MySQL)数据库文件目录</li>
</ul><p><strong>—name docker-cloudreve</strong>：Docker容器的名称，可以自行修改</p><p><strong>ilemonrain/cloudreve</strong>：启动的Docker镜像名称，请不要修改！</p></section></section><section><h3>5. 启动过程<a href="#5-启动过程"><span>#</span></a></h3><p>根据我目前设置的<code>entrypoint.sh</code>，目前的启动过程如下：</p><ol>
<li>通过命令行，启动 Docker 容器</li>
<li>【开发中】Apache2 初始化</li>
<li>MariaDB (MySQL) 初始化</li>
<li>安装Cloudreve (通过<code>php composer</code>)</li>
<li>安装 Google 2FA 验证器插件 (通过<code>php composer</code>)</li>
<li>安装 用于Google 2FA 验证器的二维码插件 (通过<code>php composer</code>)</li>
<li>输出容器相关的信息</li>
<li>以前台模式启动 Apache2</li>
</ol></section><section><h3>6. 常见问题 Q&amp;A<a href="#6-常见问题-qa"><span>#</span></a></h3><ul>
<li><strong>Q：Docker安装和启动感觉好吃力，这正常吗？</strong>
A：Docker安装过程中会涉及到selinux的部署，在安装过程中如果卡在container-selinux，请耐心等待(30秒~1分钟)</li>
<li><strong>Q：镜像启动好慢啊……</strong>
A：本身在镜像启动时就要涉及到很多的过程（参考2.5 启动过程章节），尤其是在线安装Cloudreve，更加浪费时间，请耐心等待！如果等不及可以尝试调取启动日志，看看卡在了哪里！</li>
<li><strong>Q：Docker Cloudreve运行起来后，为什么占了这么多内存啊</strong>
A：这个镜像本身就是个LAMP环境，尤其是吃内存大户的MySQL，你说占用能少么？</li>
<li><strong>Q：你打算什么时候支持SSL?</strong>
A：个人学业关系和时间关系，我会尽可能抽时间开发！</li>
</ul></section></section>
<section><h2>联系/打赏作者<a href="#联系打赏作者"><span>#</span></a></h2><ul>
<li>企鹅：<code>942109647</code> (加好友请注明 Docker Cloudreve 技术交流 ，不带任何注明直接拒加好友)</li>
<li>Email：<code>ilemonrain@ilemonrain.com</code></li>
<li>Telegram：<code>@ilemonrain</code> (不会24小时在线，有事情请发E-mail)</li>
<li>打赏通道 (吃土少年求帮助！)：请点击下面的赞赏支持喵
才怪啦，如果要打赏柠檬的话就去下面的<strong>原文链接</strong>中点赞赏吧！</li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/ox163/</id>
      <title type="text">小众软件#5 [OX163] 一键批量下图爬虫软件 可用于Pixiv</title>
      <published>2018-03-24T07:00:00.000Z</published>
      <updated>2021-01-16T14:31:53.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/ox163/"/>
      <summary type="text">这个软件我自己已经用了两三年了，是真心离不开，至于为什么现在才推荐，因为我刚刚才想起来我还有小众软件这个文章系列……</summary>
      <content type="html"><![CDATA[<p>这个软件我自己已经用了两三年了，是真心离不开，至于为什么现在才推荐，因为我刚刚才想起来我还有小众软件这个文章系列……</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=57890506" target="_blank">「DOGYEAR」/「九条だんぼ」[pixiv]</a>
九条画师画风超萌的，特别是是 DOGYEAR 系列的本子（</p>
<hr />
<p>由于 OX163 已暂停维护，推荐尝试我开发的 pxder</p>
<a href="/posts/pxder/"><div><div>[Pxder] Pixiv 插画下载器</div><div>可按根据指定画师 UID 解析并下载插画（包括动图）、一键下载所有你关注的画师的插画或收藏的插画、智能增量更新下载过的画师的插画。 多线程下载，并且支持使用 HTTP 与 SOCKS 代理。</div><div><span>2018-08-24</span><span>个人项目</span><span><span>#pixiv</span><span>#插画</span><span>#下载</span><span>#nodejs</span></span></div></div><div><img src="/usr/uploads/2018/08/3477842073.jpg" alt="" loading="lazy" /></div></a>
<section><h2>简介<a href="#简介"><span>#</span></a></h2><p><a href="http://shj.ugschina.com/163/" target="_blank">OX163官网</a></p><a href="https://github.com/heinsega/OX163" target="_blank"><div><div><div><div></div><div>heinsega</div></div><div>/</div><div>OX163</div></div><div></div></div><div>image downloader</div><div><div>—</div><div>—</div><div>GPL-3.0</div><span>Visual Basic 6.0</span></div></a><p>简单来说，这是一个可以从一个相册页面批量抓取所有图片（甚至视频）并下载的爬虫软件，最初是专为163相册而开发，后来把功能拓展到支持二十多个相册类网站了，包括 Pixiv</p><p>在官网可以下载到程序，是完全免费的</p></section>
<section><h2>支持<a href="#支持"><span>#</span></a></h2><p>图片视频：</p><ul>
<li>trailers.apple.com</li>
<li>wallpaper cool</li>
<li>rosmm(ROSIMM)</li>
<li>RosiYY(ROSIMM)</li>
<li>YOUTUBE</li>
</ul><p>网络相册：</p><ul>
<li>blog.163.com</li>
<li><a href="http://www.pixiv.net" target="_blank">www.pixiv.net</a></li>
<li>pp.sohu.com</li>
<li><a href="http://www.douban.com" target="_blank">www.douban.com</a></li>
<li>picasaweb.google.com</li>
<li>photobucket.com</li>
<li>facebook.com</li>
</ul><p>各类图库：</p><ul>
<li>danbooru.donmai.us</li>
<li>hijiribe.donmai.us</li>
<li>konachan.com</li>
<li>g.e-h**t**.org</li>
<li>gelbooru.com</li>
<li>3d(behoimi.org)</li>
<li>moe.imouto</li>
<li>sankakucomplex.com</li>
<li>booru.org</li>
<li>booru-sys(safe)</li>
<li>booru-sys(loli)</li>
<li>zerochan</li>
</ul><p>在线漫画：</p><ul>
<li><a href="http://www.ggyy8.cc" target="_blank">www.ggyy8.cc</a></li>
<li>comic.sky-fire.com</li>
</ul><p>新闻资讯：</p><ul>
<li>moeyo.com</li>
</ul></section>
<section><h2>基本使用<a href="#基本使用"><span>#</span></a></h2><p>首次使用请先点击 程序设置（齿轮图标）-更新脚本，如果提示有脚本需要更新，直接点击“自动更新”即可</p><p>使用炒鸡简单，以下载P站画师作品为例</p><p>首先打开画师作品页，URL是类似这样的
<code>https://www.pixiv.net/member_illust.php?id=xxxxxxxx</code></p><p>复制这个URL，然后打开 OX163，填在输入框中，然后点击输入框右侧的按钮</p><p><img src="/usr/uploads/2018/03/1435739095.jpg" alt="" /></p><p>此时，如果你是首次使用或者太久不用，就会在下面弹出一个浏览器窗口，找到P站页面右上角的登录，输入你的用户名密码登录后，重新点击输入框右侧的按钮即可</p><div><div><div></div><div>Note</div></div><div><p>因为有些图站例如P站就是，是必须要登录后才能查看图片的，因此需要使用其内置浏览器登录，让程序保存登录的 Cookie 才能爬取图片；如果你是太久没有使用这个程序，有可能会因为 Cookie 过期失效而需要再次登录</p></div></div><p>接着耐心等待，直到弹窗提示分析已完成，然后点击图示保存按钮，接着就自己操作选择保存在哪个文件夹吧~</p><p><img src="/usr/uploads/2018/03/50626395.jpg" alt="" /></p><p>然后 OX163 就会开始自动下载，下载完成会在右下角弹窗提示</p><p>如果是动图，那么会将所有帧下载下来并打包成 zip 格式</p><div><div><div></div><div>Note</div></div><div><p>OX163 有智能去重功能，也就是说，假如你有一次下载某个画师的图片，下载到一半不小心关了，那么你再次去分析相同页面并下载到相同文件夹，OX163 会自动跳过已经下载的图片，前提是你需要在 程序设置-文件目录操作-文件判断 中设置</p></div></div></section>
<section><h2>代理服务器设置<a href="#代理服务器设置"><span>#</span></a></h2><p>我认为只有这一块需要稍微提一下，因此单独讲一讲（其他的功能请自行玩耍XD）</p><p>OX163 支持使用 HTTP 和 SOCKS 代理，不过经我个人测试貌似并不支持 SOCKS5，就很不解，所以如果配合酸酸或者酸酸乳使用的话直接用 HTTP 代理的方式就可以了</p><p>程序设置-代理服务器，这里可以配置代理，有“代理A”和“代理B”两个，“代理A”就是你输入网址后分析的时候使用的代理，“代理B”就是你分析完成后下载图片使用的代理，不过通常情况下我们都会使用同一个代理服务器</p><p>设置完成后，可以在主界面右下角处选择是否开启代理</p><p><img src="/usr/uploads/2018/03/1789111903.jpg" alt="" /></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/tabletdriver/</id>
      <title type="text">[TabletDriver] 专为osu!音游开发的低延迟数位板驱动</title>
      <published>2018-03-23T07:22:00.000Z</published>
      <updated>2019-01-07T14:54:39.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/tabletdriver/"/>
      <summary type="text">rt，不过这个驱动集成了非常优秀的设置界面，可以根据自己的需求精确自定义数位板映射大小、范围、甚至旋转角度，以及去抖动等附加功能，个人认为对于入门级数位板来说要比官方的驱动要好用不少，即使你不玩音游也可以考虑使用</summary>
      <content type="html"><![CDATA[<p>rt，不过这个驱动集成了非常优秀的设置界面，可以根据自己的需求精确自定义数位板映射大小、范围、甚至旋转角度，以及去抖动等附加功能，个人认为对于入门级数位板来说要比官方的驱动要好用不少，即使你不玩音游也可以考虑使用</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=62612491" target="_blank">「いずみさぎり」/「po-palm」[pixiv]</a></p>
<hr />
<a href="https://github.com/hawku/TabletDriver" target="_blank"><div><div><div><div></div><div>hawku</div></div><div>/</div><div>TabletDriver</div></div><div></div></div><div>Description not set</div><div><div>—</div><div>—</div><div>GPL-3.0</div><span>C++</span></div></a>
<section><h2>支持<a href="#支持"><span>#</span></a></h2><p>以下是本文发布为止此驱动支持的数位板，以后可能会添加更多支持</p><p>支持的系统：</p><ul>
<li>Windows 7 64-bit（绝对定位模式无法在多显示器情况下运作）</li>
<li>Windows 8 64-bit</li>
<li>Windows 8.1 64-bit</li>
<li>Windows 10 64-bit</li>
</ul><p>确认支持的数位板：</p><ul>
<li>Wacom CTE-440</li>
<li>Wacom CTL-470</li>
<li>Wacom CTH-470</li>
<li>Wacom CTL-471</li>
<li>Wacom CTL-472</li>
<li>Wacom CTL-480</li>
<li>Wacom CTH-480</li>
<li>Wacom CTL-490</li>
<li>Wacom CTH-490</li>
<li>Wacom CTL-4100 USB</li>
<li>Wacom CTL-4100 Bluetooth</li>
<li>Wacom CTL-671</li>
<li>Wacom CTL-672</li>
<li>Wacom CTL-680</li>
<li>Wacom CTH-680</li>
<li>Wacom CTL-690</li>
<li>Wacom CTH-690</li>
<li>Wacom PTH-660</li>
<li>Wacom PTH-451</li>
<li>Wacom PTH-850</li>
<li>XP-Pen G430（只支持新的 2017+ “Model B”）</li>
<li>XP-Pen G430S</li>
<li>XP-Pen G540 Pro（不支持非 Pro 版）</li>
<li>XP-Pen G640</li>
<li>XP-Pen G640S</li>
<li>XP-Pen Deco 01</li>
<li>XP-Pen Deco 01 v2</li>
<li>Huion 420</li>
<li>Huion H420</li>
<li>Huion H430P</li>
<li>Huion H640P</li>
<li>Huion osu!tablet</li>
<li>Gaomon S56K</li>
<li>VEIKK S640</li>
</ul></section>
<section><h2>下载<a href="#下载"><span>#</span></a></h2><p>到文章开头处给出的 Github 项目中下载</p><p><strong>可能会被 360 之类的杀软误报，下载前请先暂时关闭杀软防护</strong></p></section>
<section><h2>如何安装<a href="#如何安装"><span>#</span></a></h2><ol>
<li>确保你的电脑上安装了以下环境（一般应该都已经有了）</li>
</ol><ul>
<li><a href="https://www.microsoft.com/net/download/dotnet-framework-runtime" target="_blank">https://www.microsoft.com/net/download/dotnet-framework-runtime</a></li>
<li><a href="https://aka.ms/vs/15/release/vc_redist.x86.exe" target="_blank">https://aka.ms/vs/15/release/vc_redist.x86.exe</a></li>
</ul><ol>
<li>把下下来的压缩包解压到一个目录（推荐短一点的路径，例如<code>C:\TabletDriver</code>）</li>
<li>如果你安装了 360 等杀软，请将这个目录添加到信任目录中</li>
<li>卸载你的数位板原本的驱动（友情提醒：卸载前记得备份配置）</li>
<li>进入 TabletDriver 文件夹，运行<code>install_vmulti_driver.bat</code>，等待直到命令提示符窗口中显示驱动安装完成</li>
<li>如果你的数位板是 Huion 或者 Gaomon 的，那么你需要进入 driver_huion 文件夹，运行<code>install_huion_64.bat</code></li>
<li>运行<code>TabletDriverGUI.exe</code>，想怎么设置就怎么设置</li>
</ol><p>以下是给看鸟语头疼的同学准备的渣翻：</p><p><img src="/usr/uploads/2018/03/4138676753.png" alt="" /></p></section>
<section><h2>补充说明<a href="#补充说明"><span>#</span></a></h2><ol>
<li>当你使用这个驱动以后，只有当<code>TabletDriverGUI.exe</code>运行的时候，数位板才能使用，因此如果你经常使用数位板，可以勾选程序右下角的开机自启</li>
<li>最小化后会隐藏到任务栏托盘</li>
<li>使用<code>-hide</code>参数启动 GUI，将会在启动时自动最小化到托盘
<code>TabletDriverGUI.exe -hide</code></li>
<li>FAQ 请查看 <a href="https://github.com/hawku/TabletDriver/wiki/FAQ" target="_blank">https://github.com/hawku/TabletDriver/wiki/FAQ</a></li>
</ol></section>
<section><h2>如果要更新到新版本<a href="#如果要更新到新版本"><span>#</span></a></h2><ol>
<li>解压新版本覆盖原来的版本</li>
<li>运行<code>TabletDriverGUI.exe</code>程序</li>
</ol></section>
<section><h2>卸载<a href="#卸载"><span>#</span></a></h2><ol>
<li>确保你取消了 GUI 的开机自启</li>
<li>运行<code>remove_vmulti_driver.bat</code></li>
<li>如果你做过安装步骤中的第6步，那么同样的，进入 driver_huion 文件夹然后运行<code>remove_huion_64.bat</code></li>
</ol></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/shinelone-boom/</id>
      <title type="text">笔记本去世了的无聊世界</title>
      <published>2018-03-19T09:56:00.000Z</published>
      <updated>2018-03-19T09:59:17.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/shinelone-boom/"/>
      <summary type="text">之前两周没更就是因为这破本 Boom 了，现在终于又复活，心情激动难以言表，特水一文以抒内心之憋屈 T_T</summary>
      <content type="html"><![CDATA[<p>之前两周没更就是因为这破本 Boom 了，现在终于又复活，心情激动难以言表，特水一文以抒内心之憋屈 T_T</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=58312881" target="_blank">「miku 宿醉」/「千夜QYS3」[pixiv]</a></p>
<hr />
<p>整整两个星期度日如年</p>
<p>啊，那这样的话我岂不是老了14岁，心理上的</p>
<section><h2>一切都还得从这破本说起<a href="#一切都还得从这破本说起"><span>#</span></a></h2><p><img src="/usr/uploads/2018/03/2916765127.jpg" alt="" /></p>

<table><thead><tr><th></th><th>炫龙v7（神州旗下子品牌）</th></tr></thead><tbody><tr><td>CPU</td><td>i7-4790K 四核八线程 4.00Ghz（睿频4.40Ghz）</td></tr><tr><td>GPU</td><td>GTX-980m 8G</td></tr><tr><td>RAM</td><td>32G(4x8G) DDR3 1600Mhz</td></tr><tr><td>Disk</td><td>120G M.2 SSD + 240G SSD + 1T HDD</td></tr><tr><td>Screen</td><td>17.3 inch FHD</td></tr><tr><td>I/O</td><td>4×USB3.0 + e-SATA(USB2.0) + HDMI + 2xDisplayPort</td></tr></tbody></table><p>我就是来晒配置的哈哈哈哈哈</p><p>这笔记本已经陪伴了我三年，高考后买的，花了我攒了6年的利是钱（1w5），当时想，高考完就要对自己狠一点嘛，这时候不花钱还有什么时候能花</p><p>这个配置在当时的笔记本里应该算是正常经济水平下的梦幻配置了，我也是打算这四年就靠这本度日了，一切的一切都想的那么完美</p><p>实际上本来还看中了一款未来人类的本，不过到处都没货，无奈之下只能上了神船，毕竟想着高端神船应该没那么容易沉吧</p><p>然，然后就沉了</p></section>
<section><h2>所以怎么沉的<a href="#所以怎么沉的"><span>#</span></a></h2><p>大概是寒假有点使用过度了，因为最近没什么想玩的大游戏，看这 GPU 闲着也是闲着，每天晚上睡觉前都挂去挖矿了</p><p>笔记本去世前一天晚上，我还正好直播打OSU上了5000pp</p><p><img src="/usr/uploads/2018/03/3826698486.png" alt="" /></p><p><img src="/usr/uploads/2018/03/3015351000.png" alt="" /></p><p>好耶！</p><p>然后跟往常一样睡前就把笔记本挂着挖矿就躺了</p><p>然后，我醒来了，笔记本却再也没有醒来</p><p>开机屏幕不亮，键盘三灯狂闪，无奈送修，然后果然是主板去世了</p><p>花了2200换主板，而且笔记本拿回来把配件组装回去之后发现其中一条内存坏了……好在是DDR3，要是是4那我估计哭死在厕所</p><p>所以跟大家讲，别随便拿笔记本去挖矿，会沉的，我试过！！！</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/arukas/</id>
      <title type="text">[Arukas] 樱花免费Docker | 日本原生IP | 部署ss</title>
      <published>2018-02-23T15:35:00.000Z</published>
      <updated>2019-04-24T14:40:18.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/arukas/"/>
      <summary type="text">Arukas 是日本的一家 Docker 服务提供商，其实在挺早之前就已经有了，最近听人提到才知道，于是去薅了羊毛（我™羊毛专业户，既然见到了就没有不薅的道理（大雾</summary>
      <content type="html"><![CDATA[<p>Arukas 是日本的一家 Docker 服务提供商，其实在挺早之前就已经有了，最近听人提到才知道，于是去薅了羊毛（我™羊毛专业户，既然见到了就没有不薅的道理（大雾</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=61894348" target="_blank">「きつね」/「美咲ゆう」[pixiv]</a></p>
<hr />
<p><a href="https://arukas.io" target="_blank">官网 arukas.io</a></p>
<div><div><div></div><div>Caution</div></div><div><p>目前应该是被墙 TCP，请自行配合 KCPTUN 等 UDP 科技使用</p></div></div>
<p>你可以薅到下图所示配置的免费 Docker</p>
<p><img src="/usr/uploads/2018/02/2766418070.png" alt="" /></p>
<p>最后两句的意思是“储存空间不限”和“流量不限”</p>
<p>不过实际上 Docker 本身默认就有储存空间<code>100GB</code>的限制
而且如果你把官网语言切换到 English，就变成限制<code>100GB</code>流量了……</p>
<div><div><div></div><div>Warning</div></div><div><p>目前说是樱花 Docker 处于公测期间，流量无限，等正式运营之后就限制<code>100G</code>流量了</p></div></div>
<p>另外，搭建酸酸的话，速度什么的就不要太指望了，毕竟是免费的东西，上个网玩个手游还行</p>
<p>实测天威联通这边看油管稳定速度在<code>350~550KiB/s</code>，突发速度能达到<code>1MiB/s</code></p>
<section><h2>注册<a href="#注册"><span>#</span></a></h2><p>打开 Arukas 官网，右上角注册流程走一遍，然后你会收到这样一封邮件，接着你只需要等就可以了</p><p><img src="/usr/uploads/2018/02/3544830751.png" alt="" /></p><p>这家注册是需要人工审核的，所以不是即注册即开通的，不过一般都会给过，这时你会收到这样一封邮件</p><p><img src="/usr/uploads/2018/02/1547945095.png" alt="" /></p><p>点击链接完成激活，就可以进入后台了</p><p>然后先别急，你还需要认证信用卡，没有信用卡是不能薅羊毛的（虚拟信用卡不知道能不能过，实体卡是没问题的）
初次登录应该会直接提示你绑定信用卡，如果错过了也可以点左侧小人图标然后点“Billing”进入设置</p><p><img src="/usr/uploads/2018/02/3541760042.png" alt="" /></p><p>这样所有准备工作就完成了，下面开始愉快的薅羊毛</p></section>
<section><h2>创建 Docker<a href="#创建-docker"><span>#</span></a></h2><p>直接点击左侧大大的“Create”按钮，然后填写对应信息：</p><ul>
<li><strong>APP Name</strong>
应用名称，随意</li>
<li><strong>Image</strong>
根据你偏好的系统选一个填写：
（alpine是极轻量版的Linux系统，如果需要搭建ss请勿选择）</li>
<li><code>ilemonrain/alpine-sshd</code></li>
<li><code>ilemonrain/centos-sshd</code></li>
<li><code>ilemonrain/ubuntu-sshd</code></li>
<li><code>ilemonrain/debian-sshd</code></li>
<li><strong>Service Plan</strong>
选第一个免费的那个，没什么好讲的</li>
<li><strong>Instances</strong>
免费 Docker 只能建立一个，不用动</li>
<li><strong>Endpoint</strong>
不知道是啥（。）</li>
<li>虽然说上面写着你可以留空，系统会自动生成，但是我创建的时候如果不填会报错，所以还是自己填上吧</li>
<li>不能使用别人已使用的名字，你输入之后下面会提示这个名字是否可以使用</li>
<li><strong>Port（很关键）</strong>
在这里设置所有你将要使用到的端口
由于 Docker 是一个容器（你可以理解成一台宿主机中的一个虚拟机），同一台宿主机中的所有 Docker 都共用一个公网 IP，因此你所使用的端口都是通过宿主机 NAT 出来的
<strong>注意：</strong></li>
<li><strong>必须添加<code>22</code>的 TCP 端口</strong>（不然你咋ssh叻）</li>
<li>由于 NAT 映射出来的时候，即使是你添加了同一个端口的 TCP 和 UDP，它依然会给你两个不一样的端口分别映射，就像这样：
<img src="/usr/uploads/2018/02/4074507745.png" alt="" />
因此，<strong>如果你是用原版酸酸，你只能使用 TCP 代理</strong>，而不能代理 UDP，因为 TCP 与 UDP 端口不同
<strong>如果你想代理 UDP，那么就用酸酸乳</strong>，因为酸酸乳的 PC 客户端可以自定义 UDP 端口，这样就可以让 TCP 与 UDP 使用两个不同的端口了</li>
<li>最多设置<code>20</code>个端口，而且请一次性设置完，后期不能再修改（如果修改的话需要重启 Docker 才能生效，这就意味着你原来 Docker 上面的数据都会美丽）</li>
<li><strong>ENV</strong>
不勾选，不用动</li>
<li><strong>Command</strong>
Docker 启动后运行的命令，如果你没有需求就留空不用管</li>
</ul><p>然后点下面的“Create Application”，就建立完成了</p><p>此时你需要立即进入 SSH 并更改默认的 SSH 密码</p><p>首先根据 NAT <strong>映射后的端口</strong>进入 Docker 的 SSH，用户名为<code>root</code>，教程所提供的那四个 Docker 的 SSH 密码为系统名（例如 CentOS 系统的密码就是<code>centos</code>，Ubuntu 系统的密码就是<code>ubuntu</code>，以此类推）</p><p>进入后，执行<code>passwd</code>命令，根据提示输入你的新密码</p><section><h3>说明<a href="#说明"><span>#</span></a></h3><p>以上 Docker 镜像均由 <a href="https://blog.ilemonrain.com/" target="_blank">极光柠檬</a> 编写</p><p><a href="https://hub.docker.com/u/ilemonrain/" target="_blank">他的 Docker Hub 个人主页</a></p><p>以下为上述四个 Docker 镜像的地址：</p><ul>
<li><a href="https://hub.docker.com/r/ilemonrain/alpine-sshd/" target="_blank">https://hub.docker.com/r/ilemonrain/alpine-sshd/</a></li>
<li><a href="https://hub.docker.com/r/ilemonrain/centos-sshd/" target="_blank">https://hub.docker.com/r/ilemonrain/centos-sshd/</a></li>
<li><a href="https://hub.docker.com/r/ilemonrain/ubuntu-sshd/" target="_blank">https://hub.docker.com/r/ilemonrain/ubuntu-sshd/</a></li>
<li><a href="https://hub.docker.com/r/ilemonrain/debian-sshd/" target="_blank">https://hub.docker.com/r/ilemonrain/debian-sshd/</a></li>
</ul></section></section>
<section><h2>搭建酸酸<a href="#搭建酸酸"><span>#</span></a></h2><p>首先先安装<code>wget</code>程序，因为 Docker 镜像十分精简，除了<code>sshd</code>之外几乎什么都没装……</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># CentOS</span></div></div><div><div><div>2</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>wget</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># Debian / Ubuntu</span></div></div><div><div><div>5</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>wget</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装会超级慢，因为 Docker 是 0.1vCPU，频率限制的很死……</p><p>耐心等吧</p><div><div><div></div><div>Note</div></div><div><p>下面的脚本都使用的是“秋水逸冰”的一键脚本</p></div></div><section><h3>原版酸酸<a href="#原版酸酸"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>-O</span><span> </span><span>shadowsocks.sh</span><span> </span><span>https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks.sh</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>+x</span><span> </span><span>shadowsocks.sh</span></div></div><div><div><div>2</div></div><div><span>./shadowsocks.sh</span><span> 2&gt;&amp;1 | </span><span>tee</span><span> </span><span>shadowsocks.log</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后根据脚本提示选择酸酸配置</p><p>个人（强烈）建议：
加密：<code>aes-256-gcm</code>或者<code>chacha20-ietf-poly1305</code>，总之使用 AEAD 加密</p></section><section><h3>酸酸乳<a href="#酸酸乳"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocksR.sh</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>+x</span><span> </span><span>shadowsocksR.sh</span></div></div><div><div><div>2</div></div><div><span>./shadowsocksR.sh</span><span> 2&gt;&amp;1 | </span><span>tee</span><span> </span><span>shadowsocksR.log</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后根据脚本提示选择酸酸配置</p><p>个人（强烈）建议：
加密：<code>none</code>
协议：<code>auth_chain_a</code>
混淆：根据你自己的需求，选择<code>plain</code>或者<code>http_simple</code>
个人极其不建议使用<code>tls1.2_ticket_auth</code>系列混淆</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/ilidilid/</id>
      <title type="text">[ilidilid] 哔哩哔哩（真）镜像站</title>
      <published>2018-02-21T14:05:00.000Z</published>
      <updated>2018-02-24T06:21:06.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/ilidilid/"/>
      <summary type="text">跟你们说，这个CSS，敲好玩得（然并卵</summary>
      <content type="html"><![CDATA[<p>跟你们说，这个CSS，敲好玩得（然并卵</p>
<hr />
<p><a href="http://www.ilidilid.com/" target="_blank">http://www.ilidilid.com/</a></p>
<p>前几天这玩意在我各个Q群里轮了一遍</p>
<p>点开一看，确实蛮有意思的，xswl</p>
<p>笑的同时我也很好奇这是怎么做到的，于是耐不住寂寞F12看了一下</p>
<section><h2>研究一下<a href="#研究一下"><span>#</span></a></h2><p>一开始我以为是用js做到的，但是我看了下页面结构，整个页面就<code>&lt;body&gt;</code>里有一个反代b站的<code>&lt;iframe&gt;</code>，下面一段js脚本</p><p>然后稍微看了下js脚本，都是些无关紧要的操作</p><p><img src="/usr/uploads/2018/02/1993399892.png" alt="" /></p><p>瞬间反应过来这应该是CSS，但是我确实没有印象有哪个CSS属性可以做到镜像效果的</p><p>于是看了看<code>&lt;head&gt;</code>部分的CSS，然后马上就注意到了……</p><p><img src="/usr/uploads/2018/02/2089322938.png" alt="" /></p><p>哇哦！负……负1</p><p>只能说自己技艺不精了，写了一年的CSS都没能想到这种操作</p><p>也就是说，实际上这个CSS只是利用X轴缩放比例为<code>-1</code>，把整个<code>&lt;iframe&gt;</code>的左右给反过来了</p><p>关于<code>transform</code>的知识可以看
<a href="https://www.runoob.com/cssref/css3-pr-transform.html" target="_blank">https://www.runoob.com/cssref/css3-pr-transform.html</a></p></section>
<section><h2>实践一下<a href="#实践一下"><span>#</span></a></h2><p>于是紧接着我又加了个<code>scaleY(-1)</code>，这回真的反了</p><p><img src="/usr/uploads/2018/02/1474833785.jpg" alt="" /></p><p><img src="/usr/uploads/2018/02/1940498866.png" alt="" /></p><p>新知识GET</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/2018-new-year-earn-money/</id>
      <title type="text">过年近期赚钱活动收集分享</title>
      <published>2018-02-18T09:51:00.000Z</published>
      <updated>2018-02-18T12:31:43.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/2018-new-year-earn-money/"/>
      <summary type="text">最近过年，挺多软件也是弄了很多活动，其中有些我个人上了车并且觉得受益可观的，分享一下</summary>
      <content type="html"><![CDATA[<p>最近过年，挺多软件也是弄了很多活动，其中有些我个人上了车并且觉得受益可观的，分享一下</p>
<p>Head Pic: 自己P的</p>
<section><h1>ZAKER新闻<a href="#zaker新闻"><span>#</span></a></h1><p>这个 APP 推出的活动是双向受益，个人很推荐并且受益挺大</p><p>注册不绑定手机，所以如果有多台设备甚至可以互刷</p><div><div><div></div><div>Warning</div></div><div><p>这个活动持续到 <code>2018.04.05</code></p></div></div><img src="/usr/uploads/2018/02/1578295618.png" /><section><h2>规则<a href="#规则"><span>#</span></a></h2><section><h3>奖金<a href="#奖金"><span>#</span></a></h3><ol>
<li>邀请好友每位直接先给1元（双方都给）</li>
<li>接下来的每天（包括注册这天），<strong>双方都</strong>看不少于两篇文章（三篇就行），双方都可以获得<code>10元</code>以内的随机奖金*（一开始经常只给1块，坚持几天会出现4块5块的）*</li>
<li>不能断，一断就不给了</li>
</ol></section><section><h3>提现<a href="#提现"><span>#</span></a></h3><ol>
<li>每周四开放提现</li>
<li>最低提现<code>30元</code></li>
</ol></section></section><section><h2>如何参加<a href="#如何参加"><span>#</span></a></h2><ol>
<li>手机打开 <a href="https://huodong.myzaker.com/main/interactive/zaker_invite_2018//share.php?code=f56k9vs5" target="_blank">ZAKER 下载页</a>，点击邀请码的复制，或者直接复制这个邀请码<code>f56k9vs5</code>，然后点下面的“下载ZAKER参与活动”</li>
<li>打开 ZAKER，登陆完以后到“我的-活动中心-邀请有礼”，填入邀请码激活，你就会得到自己的邀请码</li>
<li>将自己的邀请码分享给基友或者拿自己另外的设备互刷</li>
</ol></section></section>
<section><h1>公信宝<a href="#公信宝"><span>#</span></a></h1><p>这是一个数据挖矿赚钱的一个 APP</p><section><h2>如何参加<a href="#如何参加-1"><span>#</span></a></h2><ol>
<li>手机打开 <a href="https://blockcity.dgbndn.cn/#/zARjMRom1Na5SOmQP85002530/v1" target="_blank">这个链接</a>，按提示注册，然后下载 APP，登陆进去就能开挖了</li>
<li>可以通过绑定各种账号和完成任务的方式增加算力</li>
</ol></section></section>
<section><h1>共生币<a href="#共生币"><span>#</span></a></h1><p>这也是一个数据挖矿赚钱的币，但是不会涉及到过于隐私的数据</p><p>主要操作是上网，对就是上网，使用浏览器浏览网页，也就是通过记录你的上网行为数据来给你报酬</p><p>目前正常情况下一天能够挖到一百多共生币，相当于六七八块的样子</p><section><h2>如何参加<a href="#如何参加-2"><span>#</span></a></h2><ol>
<li>打开 <a href="https://lives.uu.me/invite/register?code=zJt7oO" target="_blank">这个链接</a>，在右边注册帐号</li>
<li>根据提示下载挖矿用浏览器（支持PC、安卓、iOS）</li>
<li>正常上网，即可赚钱</li>
</ol></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/pxer/</id>
      <title type="text">[Pxer] 人人可用的 pixiv 批量抓图爬虫</title>
      <published>2018-02-18T06:32:00.000Z</published>
      <updated>2018-03-24T08:58:35.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/pxer/"/>
      <summary type="text">纯客户端 JavaScript 编写的 pixiv.net 多线程爬虫，速度极快，并且拥有高定制度的筛选选项，只要是能安装 Tampermonkey 扩展插件的浏览器（目前大多数主流浏览器）都可以使用！</summary>
      <content type="html"><![CDATA[<p>纯客户端 JavaScript 编写的 pixiv.net 多线程爬虫，速度极快，并且拥有高定制度的筛选选项，只要是能安装 Tampermonkey 扩展插件的浏览器（目前大多数主流浏览器）都可以使用！</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=61447921" target="_blank">「萌百娘」/「DanGo」[pixiv]</a></p>
<hr />
<a href="https://github.com/pea3nut/Pxer" target="_blank"><div><div><div><div></div><div>pea3nut</div></div><div>/</div><div>Pxer</div></div><div></div></div><div>A tool for pixiv.net. 人人可用的P站爬虫</div><div><div>—</div><div>—</div><div>MIT</div><span>JavaScript</span></div></a>
<p><img src="https://github.com/pea3nut/Pxer/raw/dev/src/public/pxer-ui-gif.gif?raw=true" alt="" /></p>
<section><h2>安装步骤<a href="#安装步骤"><span>#</span></a></h2><ol>
<li><a href="http://pxer.pea3nut.org/md/install_1" target="_blank">点此查看 Tempermonkey 扩展安装教程</a></li>
<li><a href="http://pxer.pea3nut.org/md/install_2" target="_blank">点此查看 Pxer 安装教程</a></li>
</ol></section>
<section><h2>如何使用<a href="#如何使用"><span>#</span></a></h2><p>当你打开一些含有画作的页面时，顶部就会显示 Pxer 工具栏，点击上面唯一的按钮之后就可以开始使用了！</p><p>最终结果将会以批量链接的形式展示，就像上面动图中的那样</p><p>如果你不清楚抓取参数的含义，你可以查看 <a href="http://pxer.pea3nut.org/md/use" target="_blank">作者的这篇说明</a></p></section>
<section><h2>个人评价<a href="#个人评价"><span>#</span></a></h2><p>这个爬虫有一个很大的优势就是轻便快速，与浏览器高度结合，并且筛选条件十分丰富，毕竟其是专门针对P站做出来的爬虫</p><p>但是受限于浏览器插件这个运行平台，这个爬虫只能做到“爬”出所有链接，而不能一并下载，这算是比较遗憾的一点，否则我大概一辈子都离不开这个插件了</p><p>因此对于像我一样的懒人，我推荐另一款爬虫软件，它支持面广并且可以直接批量下载、以及跳过已下载的图片</p><a href="/posts/ox163/"><div><div>小众软件#5 [OX163] 一键批量下图爬虫软件 可用于Pixiv</div><div>这个软件我自己已经用了两三年了，是真心离不开，至于为什么现在才推荐，因为我刚刚才想起来我还有小众软件这个文章系列……</div><div><span>2018-03-24</span><span>小众软件</span><span><span>#ox163</span><span>#爬虫</span><span>#下载</span><span>#pixiv</span></span></div></div><div><img src="/usr/uploads/2018/03/3995754229.jpg" alt="" loading="lazy" /></div></a></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/linux-kms-server/</id>
      <title type="text">[KMS] Linux一键搭建KMS激活服务器让PC激活Windows和Office</title>
      <published>2018-02-17T14:52:00.000Z</published>
      <updated>2020-06-19T08:25:09.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/linux-kms-server/"/>
      <summary type="text">Linux 快速搭建 KMS 激活服务器，让 PC 激活 Windows 和 Office 并自动续期，告别网上的来路不明的激活工具，防止意外中毒。</summary>
      <content type="html"><![CDATA[<p>Linux 快速搭建 KMS 激活服务器，让 PC 激活 Windows 和 Office 并自动续期，告别网上的来路不明的激活工具，防止意外中毒。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=65193765" target="_blank">「アズールレーン」/「AO凹君」[pixiv]</a></p>
<hr />
<p>虽然目前已经有各种 PC 用的 KMS 激活程序，例如<code>KMSAuto</code>或者<code>KMS VL ALL</code>之类的，但是他们都会被 Windows Defender 或者普通的杀毒软件认为是病毒。
虽然你“相信”这些软件被报毒是很正常的，直接加入白名单了事，然而你确实不知道你从网上搜索下载的这些激活程序是不是真的经过别人的改造植入了病毒……</p>
<p>因此，我们可以利用自己的 Linux VPS 搭建 KMS 激活服务器给自己的 PC 使用，这样既安全无毒又不怕激活丢失。</p>
<p><a href="/kms/">本站 KMS 服务</a></p>
<section><h2>一键搭建 KMS 服务<a href="#一键搭建-kms-服务"><span>#</span></a></h2><a href="https://github.com/dakkidaze/one-key-kms" target="_blank"><div><div><div><div></div><div>dakkidaze</div></div><div>/</div><div>one-key-kms</div></div><div></div></div><div>在Linux上一键搭建KMS服务器</div><div><div>—</div><div>—</div><div>no-license</div><span>Shell</span></div></a><ol>
<li>下载脚本并运行，根据提示键入<code>y</code>开始安装</li>
</ol><ul>
<li>CentOS / Redhat / Fedora</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>https://raw.githubusercontent.com/dakkidaze/one-key-kms/master/one-key-kms-centos.sh</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>+x</span><span> </span><span>one-key-kms-centos.sh</span><span> &amp;&amp;</span><span>./one-key-kms-centos.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>Debian / Ubuntu / Mint</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>https://raw.githubusercontent.com/dakkidaze/one-key-kms/master/one-key-kms-debian.sh</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>+x</span><span> </span><span>one-key-kms-debian.sh</span><span> &amp;&amp; </span><span>./one-key-kms-debian.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>下载这个作者写的配套脚本来控制启动/停止/重启等</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#下载脚本</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>https://raw.githubusercontent.com/dakkidaze/one-key-kms/master/kms.sh</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>+x</span><span> </span><span>kms.sh</span></div></div><div><div><div>3</div></div><div><span>#启动 KMS 服务</span></div></div><div><div><div>4</div></div><div><span>./kms.sh</span><span> </span><span>start</span></div></div><div><div><div>5</div></div><div><span>#这个脚本可以使用的参数：</span></div></div><div><div><div>6</div></div><div><span># start | stop | restart | status</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>如果你的防火墙默认 DROP，那么需要手动放行<code>1688</code>端口</li>
</ol><ul>
<li>CentOS / Redhat / Fedora</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>iptables</span><span> </span><span>-I</span><span> </span><span>INPUT</span><span> </span><span>-p</span><span> </span><span>tcp</span><span> </span><span>--dport</span><span> </span><span>1688</span><span> </span><span>-j</span><span> </span><span>ACCEPT</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>Debian / Ubuntu / Mint</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#如果有 ufw 的话</span></div></div><div><div><div>2</div></div><div><span>ufw</span><span> </span><span>allow</span><span> </span><span>1688</span></div></div><div><div><div>3</div></div><div><span>#如果没有的话，这么方便的防火墙工具为啥不装一个嘞~</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>激活 Windows<a href="#激活-windows"><span>#</span></a></h2><div><div><div></div><div>Warning</div></div><div><p>再次提醒，只能激活 VL 版的系统，如果不是 VL 可以应用 <a href="https://docs.microsoft.com/en-us/windows-server/get-started/kmsclientkeys" target="_blank">KMS client setup keys</a> 进行转换</p></div></div><p>以管理员身份运行<code>命令提示符</code>或者<code>PowerShell</code>，然后输入以下命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/d</span><span> </span><span>"%SystemRoot%\system32"</span></div></div><div><div><div>2</div></div><div><span>slmgr</span><span> </span><span>/skms</span><span> </span><span>你的KMS服务端主机的IP或者域名</span></div></div><div><div><div>3</div></div><div><span>slmgr</span><span> </span><span>/ato</span></div></div><div><div><div>4</div></div><div><span>slmgr</span><span> </span><span>/xpr</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>成功的话你应该会看到这样的提示：
<img src="/usr/uploads/2018/02/1228267868.jpg" alt="" /></p><p>这样，每过 7 天，系统都会自动与你的 KMS 服务器通信来激活续期，每次激活有效时间为 180 天</p><p>当然，你也可以随时通过<code>slmgr /skms</code>这条命令来更换你的 KMS 服务器地址</p></section>
<section><h2>激活 Office<a href="#激活-office"><span>#</span></a></h2><div><div><div></div><div>Warning</div></div><div><p>只能激活 VL 版的 Office，如果是零售版，百度一下有很多将零售版转换为 VL 版的方法和批处理脚本；如果你比较懒，也可以直接利用<code>KMSAuto</code>工具来转换</p></div></div><p>首先确定你的 Office 版本所对应的目录名称：</p>

<table><thead><tr><th>版本</th><th>目录名称</th></tr></thead><tbody><tr><td>2016</td><td><code>Office16</code></td></tr><tr><td>2013</td><td><code>Office15</code></td></tr><tr><td>2010</td><td><code>Office14</code></td></tr></tbody></table><ul>
<li>如果你的 Office 是 32 位的，那么目录就在
<code>C:\Program Files (x86)\Microsoft Office\目录名称</code></li>
<li>如果是 64 位，那么在
<code>C:\Program Files\Microsoft Office\目录名称</code></li>
</ul><p>接下来以管理员身份运行<code>命令提示符</code>或者<code>PowerShell</code>，然后输入以下命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#以 64 位的 Office2016 为例，进入 Office 目录</span></div></div><div><div><div>2</div></div><div><span>cd</span><span> </span><span>"C:\Program Files\Microsoft Office\Office16"</span></div></div><div><div><div>3</div></div><div><span>cscript</span><span> </span><span>ospp.vbs</span><span> </span><span>/sethst:你的KMS服务端主机的IP或者域名</span></div></div><div><div><div>4</div></div><div><span>cscript</span><span> </span><span>ospp.vbs</span><span> </span><span>/act</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>成功的话你应该会看到类似这样的执行输出：
<img src="/usr/uploads/2018/02/3176822191.jpg" alt="" /></p><p>由于我电脑上还安装了 Visio，因此有两次激活</p></section>
<section><h2>其他说明<a href="#其他说明"><span>#</span></a></h2><section><h3>开机自启<a href="#开机自启"><span>#</span></a></h3><p>如果只是想简单的让 KMS 服务在 Linux 上开机自启，那么编辑<code>/etc/rc.local</code>文件，在<code>exit 0</code>（如果有）前面加上一句</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#假设之前下载的那个 kms.sh 脚本位于 /root/kms.sh</span></div></div><div><div><div>2</div></div><div><span>/root/kms.sh</span><span> </span><span>start</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后保存即可</p></section><section><h3>守护进程<a href="#守护进程"><span>#</span></a></h3><p>如果你有很高的要求，想让 KMS 服务以守护进程的方式运行，防止服务意外终止</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#Debian / Ubuntu / Mint 使用 apt-get 来安装 supervisor</span></div></div><div><div><div>2</div></div><div><span>#CentOS / Redhat / Fedora 使用 yum 来安装 supervisor</span></div></div><div><div><div>3</div></div><div><span>#这里以 Debian 系统为例</span></div></div><div><div><div>4</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>supervisor</span><span> </span><span>-y</span></div></div><div><div><div>5</div></div><div><span>echo</span><span> </span><span>"[program:kms]</span></div></div><div><div><div>6</div></div><div><span>command=/usr/local/kms/vlmcsd -L 0.0.0.0:1688</span></div></div><div><div><div>7</div></div><div><span>autorestart=true</span></div></div><div><div><div>8</div></div><div><span>autostart=true</span></div></div><div><div><div>9</div></div><div><span>user=root"</span><span> &gt; </span><span>/etc/supervisor/conf.d/kms.conf</span></div></div><div><div><div>10</div></div><div><span>/etc/init.d/supervisor</span><span> </span><span>restart</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果你使用守护进程方式运行 KMS 服务，那么就不需要在<code>/etc/rc.local</code>中写入开机启动命令</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/2018-happy-new-year/</id>
      <title type="text">[2018] 祝大家新年快乐呀~</title>
      <published>2018-02-15T16:42:00.000Z</published>
      <updated>2018-02-18T06:09:14.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/2018-happy-new-year/"/>
      <summary type="text">点进来看一下总没什么坏处的~</summary>
      <content type="html"><![CDATA[<p>点进来看一下总没什么坏处的~</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=67014121" target="_blank">「ユニコーンちゃん」/「marmoset」[pixiv]</a></p>
<hr />
<p>感谢大家往日的赞赏√</p>
<p><img src="/usr/uploads/2018/02/3313151992.jpg" alt="" /></p>
<p>(红包已经没啦)</p>
<p><a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=66789143" target="_blank">「☆あけおめ☆」/「紺菓」[pixiv]</a></p>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/web-get-post/</id>
      <title type="text">[Node.js] 笔记#1 Web 模块 | 收发 GET/POST</title>
      <published>2018-02-11T08:17:00.000Z</published>
      <updated>2018-02-11T08:23:32.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/web-get-post/"/>
      <summary type="text">最近开始学 Node.js 了，写一写笔记，稍微记一下菜鸟教程上没有细讲的内容以及自己摸索的经验来巩固一下 这篇笔记包含 Web 模块的基本使用以及收发 GET/POST 请求的方法</summary>
      <content type="html"><![CDATA[<p>最近开始学 Node.js 了，写一写笔记，稍微记一下菜鸟教程上没有细讲的内容以及自己摸索的经验来巩固一下</p>
<p>这篇笔记包含 Web 模块的基本使用以及收发 GET/POST 请求的方法</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=47842393" target="_blank">「無題」/「かるまゆ」[pixiv]</a></p>
<hr />
<section><h2>作服务端，接收请求<a href="#作服务端接收请求"><span>#</span></a></h2><section><h3>GET<a href="#get"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>var</span><span><span> </span><span>http</span><span> </span></span><span>=</span><span> </span><span>require</span><span>(</span><span>"http"</span><span>);</span></div></div><div><div><div>2</div></div><div><span>var</span><span><span> </span><span>url</span><span> </span></span><span>=</span><span> </span><span>require</span><span>(</span><span>"url"</span><span>);</span></div></div><div><div><div>3</div></div><div><span>var</span><span><span> </span><span>util</span><span> </span></span><span>=</span><span> </span><span>require</span><span>(</span><span>"util"</span><span>);</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>//                     req请求  res返回</span></div></div><div><div><div>6</div></div><div><span>http</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>.</span><span>createServer</span><span>(</span><span>function</span><span><span> (</span><span>req</span><span>, </span><span>res</span><span>) {</span></span></div></div><div><div><div>8</div></div><div><span>    </span><span>//writeHeader(状态码,响应头属性)</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>res</span><span>.</span><span>writeHeader</span><span>(</span><span>200</span><span>, { </span><span>"Content-Type"</span><span>:</span><span> </span><span>"text/html;charset=UTF-8"</span><span> });</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>    </span><span>//解析 url 参数</span></div></div><div><div><div>12</div></div><div><span>    </span><span>//parse() 将字符串转成对象，例如 req.url="/?url=123&amp;name=321"</span></div></div><div><div><div>13</div></div><div><span>    </span><span>//true：params 将是一个含有属性的对象{url:"123",name:"321"}</span></div></div><div><div><div>14</div></div><div><span>    </span><span>//false：params 将是字符串"url=123&amp;name=321"</span></div></div><div><div><div>15</div></div><div><span>    </span><span>var</span><span><span> </span><span>params</span><span> </span></span><span>=</span><span><span> </span><span>url</span><span>.</span></span><span>parse</span><span><span>(</span><span>req</span><span>.</span></span><span>url</span><span>, </span><span>true</span><span>).</span><span>query</span><span>;</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>    </span><span>//使用 write() 向返回页面中输出内容</span></div></div><div><div><div>18</div></div><div><span><span>    </span></span><span>res</span><span>.</span><span>write</span><span><span>(</span><span>params</span><span>.</span></span><span>url</span><span>);</span></div></div><div><div><div>19</div></div><div><span><span>    </span></span><span>res</span><span>.</span><span>write</span><span>(</span><span>"&lt;br&gt;"</span><span>);</span></div></div><div><div><div>20</div></div><div><span><span>    </span></span><span>res</span><span>.</span><span>write</span><span><span>(</span><span>params</span><span>.</span></span><span>name</span><span>);</span></div></div><div><div><div>21</div></div><div>
</div></div><div><div><div>22</div></div><div><span>    </span><span>//使用 end() 结束输出，必须要有 end()</span></div></div><div><div><div>23</div></div><div><span>    </span><span>//可以带上参数：end("xxxxxx")，表示输出此内容之后结束输出</span></div></div><div><div><div>24</div></div><div><span><span>    </span></span><span>res</span><span>.</span><span>end</span><span>();</span></div></div><div><div><div>25</div></div><div><span><span>  </span></span><span>})</span></div></div><div><div><div>26</div></div><div><span><span>  </span></span><span>.</span><span>listen</span><span>(</span><span>8080</span><span>); </span><span>//监听端口</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>POST<a href="#post"><span>#</span></a></h3><p>接收 POST 请求与 GET 请求不一样的一点就是，接收 POST 必须通过请求(req)的<code>data</code>事件来获取 POST 数据，然后通过<code>end</code>事件的回调函数来处理余下的任务</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>var</span><span><span> </span><span>http</span><span> </span></span><span>=</span><span> </span><span>require</span><span>(</span><span>"http"</span><span>);</span></div></div><div><div><div>2</div></div><div><span>var</span><span><span> </span><span>querystring</span><span> </span></span><span>=</span><span> </span><span>require</span><span>(</span><span>"querystring"</span><span>);</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>http</span></div></div><div><div><div>5</div></div><div><span><span>  </span></span><span>.</span><span>createServer</span><span>(</span><span>function</span><span><span> (</span><span>req</span><span>, </span><span>res</span><span>) {</span></span></div></div><div><div><div>6</div></div><div><span>    </span><span>//暂存请求体信息</span></div></div><div><div><div>7</div></div><div><span>    </span><span>var</span><span><span> </span><span>body</span><span> </span></span><span>=</span><span> </span><span>""</span><span>;</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span>    </span><span>//每当接收到请求体数据，累加到post中</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>req</span><span>.</span><span>on</span><span>(</span><span>"data"</span><span>, </span><span>function</span><span><span> (</span><span>chunk</span><span>) {</span></span></div></div><div><div><div>11</div></div><div><span>      </span><span>//一定要使用+=，如果body=chunk，因为请求favicon.ico，body会等于{}</span></div></div><div><div><div>12</div></div><div><span><span>      </span></span><span>body</span><span> </span><span>+=</span><span><span> </span><span>chunk</span><span>;</span></span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>    </span><span>//数据接受完后，通过 querystring.parse 将 post 解析为真正的 POST 请求格式</span></div></div><div><div><div>16</div></div><div><span><span>    </span></span><span>req</span><span>.</span><span>on</span><span>(</span><span>"end"</span><span>, </span><span>function</span><span> () {</span></div></div><div><div><div>17</div></div><div><span>      </span><span>//将一个字符串反序列化为一个对象</span></div></div><div><div><div>18</div></div><div><span><span>      </span></span><span>body</span><span> </span><span>=</span><span><span> </span><span>querystring</span><span>.</span></span><span>parse</span><span><span>(</span><span>body</span><span>);</span></span></div></div><div><div><div>19</div></div><div>
</div></div><div><div><div>20</div></div><div><span><span>      </span></span><span>res</span><span>.</span><span>writeHead</span><span>(</span><span>200</span><span>, { </span><span>"Content-Type"</span><span>:</span><span> </span><span>"text/html;charset=utf8"</span><span> });</span></div></div><div><div><div>21</div></div><div><span>      </span><span>if</span><span><span> (</span><span>body</span><span>.</span></span><span>name</span><span> </span><span>&amp;&amp;</span><span><span> </span><span>body</span><span>.</span></span><span>url</span><span>) {</span></div></div><div><div><div>22</div></div><div><span>        </span><span>// 输出提交的数据</span></div></div><div><div><div>23</div></div><div><span><span>        </span></span><span>res</span><span>.</span><span>write</span><span><span>(</span><span>body</span><span>.</span></span><span>name</span><span>);</span></div></div><div><div><div>24</div></div><div><span><span>        </span></span><span>res</span><span>.</span><span>write</span><span>(</span><span>"&lt;br&gt;"</span><span>);</span></div></div><div><div><div>25</div></div><div><span><span>        </span></span><span>res</span><span>.</span><span>write</span><span><span>(</span><span>body</span><span>.</span></span><span>url</span><span>);</span></div></div><div><div><div>26</div></div><div><span><span>      </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>27</div></div><div><span><span>        </span></span><span>res</span><span>.</span><span>write</span><span>(</span><span>"xxxxxxx"</span><span>);</span></div></div><div><div><div>28</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>29</div></div><div><span><span>      </span></span><span>res</span><span>.</span><span>end</span><span>();</span></div></div><div><div><div>30</div></div><div><span><span>    </span></span><span>});</span></div></div><div><div><div>31</div></div><div><span><span>  </span></span><span>})</span></div></div><div><div><div>32</div></div><div><span><span>  </span></span><span>.</span><span>listen</span><span>(</span><span>8080</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section>
<section><h2>作为客户端，发送请求并获取返回<a href="#作为客户端发送请求并获取返回"><span>#</span></a></h2><section><h3>GET<a href="#get-1"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>//如果需要发送 HTTPS 请求，则需要 require('https')</span></div></div><div><div><div>2</div></div><div><span>var</span><span><span> </span><span>http</span><span> </span></span><span>=</span><span> </span><span>require</span><span>(</span><span>"http"</span><span>);</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>//发送 GET 请求  get(URL,回调函数)</span></div></div><div><div><div>5</div></div><div><span><span>http</span><span>.</span></span><span>get</span><span>(</span><span>"http://xxx.xx"</span><span>, </span><span>function</span><span><span> (</span><span>res</span><span>) {</span></span></div></div><div><div><div>6</div></div><div><span>  </span><span>//储存返回的 HTML 内容</span></div></div><div><div><div>7</div></div><div><span>  </span><span>var</span><span><span> </span><span>html</span><span> </span></span><span>=</span><span> </span><span>""</span><span>;</span></div></div><div><div><div>8</div></div><div><span>  </span><span>//每收到一段数据就 += 一次</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>res</span><span>.</span><span>on</span><span>(</span><span>"data"</span><span>, </span><span>function</span><span><span> (</span><span>data</span><span>) {</span></span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>html</span><span> </span><span>+=</span><span><span> </span><span>data</span><span>;</span></span></div></div><div><div><div>11</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>  </span><span>//收到所有 HTML 内容后</span></div></div><div><div><div>14</div></div><div><span><span>  </span></span><span>res</span><span>.</span><span>on</span><span>(</span><span>"end"</span><span>, </span><span>function</span><span> () {</span></div></div><div><div><div>15</div></div><div><span>    </span><span>//TODO</span></div></div><div><div><div>16</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>17</div></div><div><span>});</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>POST<a href="#post-1"><span>#</span></a></h3><p>实际上上面的 GET 请求也可以用这里 POST 请求的方式来写，即使用<code>http.request()</code>而不是<code>http.get()</code>，但是直接用<code>get()</code>会简单很多</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>//如果需要发送 HTTPS 请求，则需要 require('https')</span></div></div><div><div><div>2</div></div><div><span>var</span><span><span> </span><span>http</span><span> </span></span><span>=</span><span> </span><span>require</span><span>(</span><span>"http"</span><span>);</span></div></div><div><div><div>3</div></div><div><span>var</span><span><span> </span><span>querystring</span><span> </span></span><span>=</span><span> </span><span>require</span><span>(</span><span>"querystring"</span><span>);</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>//POST 参数，直接写成一个对象</span></div></div><div><div><div>6</div></div><div><span>var</span><span><span> </span><span>contents</span><span> </span></span><span>=</span><span><span> </span><span>querystring</span><span>.</span></span><span>stringify</span><span>({</span></div></div><div><div><div>7</div></div><div><span>  </span><span>name</span><span>:</span><span> </span><span>"Jindai Kirin"</span><span>,</span></div></div><div><div><div>8</div></div><div><span>  </span><span>email</span><span>:</span><span> </span><span>"jindaikirin@ykilin.moe"</span><span>,</span></div></div><div><div><div>9</div></div><div><span>  </span><span>address</span><span>:</span><span> </span><span>"lolico.moe"</span><span>,</span></div></div><div><div><div>10</div></div><div><span>});</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>//请求选项</span></div></div><div><div><div>13</div></div><div><span>var</span><span><span> </span><span>options</span><span> </span></span><span>=</span><span> {</span></div></div><div><div><div>14</div></div><div><span>  </span><span>host</span><span>:</span><span> </span><span>"lolico.moe"</span><span>,</span></div></div><div><div><div>15</div></div><div><span>  </span><span>path</span><span>:</span><span> </span><span>"/xxx/xxx"</span><span>,</span></div></div><div><div><div>16</div></div><div><span>  </span><span>method</span><span>:</span><span> </span><span>"POST"</span><span>,</span></div></div><div><div><div>17</div></div><div><span>  </span><span>headers</span><span>:</span><span> {</span></div></div><div><div><div>18</div></div><div><span>    </span><span>"Content-Type"</span><span>:</span><span> </span><span>"application/x-www-form-urlencoded"</span><span>,</span></div></div><div><div><div>19</div></div><div><span>    </span><span>"Content-Length"</span><span>:</span><span><span> </span><span>contents</span><span>.</span></span><span>length</span><span>,</span></div></div><div><div><div>20</div></div><div><span><span>  </span></span><span>},</span></div></div><div><div><div>21</div></div><div><span>};</span></div></div><div><div><div>22</div></div><div>
</div></div><div><div><div>23</div></div><div><span>var</span><span><span> </span><span>req</span><span> </span></span><span>=</span><span><span> </span><span>http</span><span>.</span></span><span>request</span><span><span>(</span><span>options</span><span>, </span></span><span>function</span><span><span> (</span><span>res</span><span>) {</span></span></div></div><div><div><div>24</div></div><div><span>  </span><span>var</span><span><span> </span><span>html</span><span> </span></span><span>=</span><span> </span><span>""</span><span>;</span></div></div><div><div><div>25</div></div><div><span><span>  </span></span><span>res</span><span>.</span><span>setEncoding</span><span>(</span><span>"utf8"</span><span>);</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span><span>  </span></span><span>res</span><span>.</span><span>on</span><span>(</span><span>"data"</span><span>, </span><span>function</span><span><span> (</span><span>data</span><span>) {</span></span></div></div><div><div><div>28</div></div><div><span><span>    </span></span><span>html</span><span> </span><span>+=</span><span><span> </span><span>data</span><span>;</span></span></div></div><div><div><div>29</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>30</div></div><div>
</div></div><div><div><div>31</div></div><div><span><span>  </span></span><span>res</span><span>.</span><span>on</span><span>(</span><span>"end"</span><span>, </span><span>function</span><span> () {</span></div></div><div><div><div>32</div></div><div><span>    </span><span>//TODO</span></div></div><div><div><div>33</div></div><div><span><span>  </span></span><span>});</span></div></div><div><div><div>34</div></div><div><span>});</span></div></div><div><div><div>35</div></div><div>
</div></div><div><div><div>36</div></div><div><span>//发送请求</span></div></div><div><div><div>37</div></div><div><span><span>req</span><span>.</span></span><span>write</span><span><span>(</span><span>contents</span><span>);</span></span></div></div><div><div><div>38</div></div><div><span><span>req</span><span>.</span></span><span>end</span><span>;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/easy-ftp-server/</id>
      <title type="text">小众软件#4 [简单FTP Server] 随开随用的 FTP 服务器 局域网内轻松互传文件x2</title>
      <published>2018-02-02T10:22:00.000Z</published>
      <updated>2018-02-02T11:46:16.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/easy-ftp-server/"/>
      <summary type="text">rt，不需要过多的说明，和上一期的 hfs 性质有点类似，上次讲了简易 HTTP 服务器，这次就轮到 FTP 啦~ 这是一个可以一键部署建议 FTP 服务器的工具，方便在局域网内批量传输文件。相比上期的 hfs，优势就在于这个批量，可以直接传输文件夹，毕竟 FTP 嘛</summary>
      <content type="html"><![CDATA[<p>rt，不需要过多的说明，和上一期的 hfs 性质有点类似，上次讲了简易 HTTP 服务器，这次就轮到 FTP 啦~</p>
<p>这是一个可以一键部署建议 FTP 服务器的工具，方便在局域网内批量传输文件。相比上期的 hfs，优势就在于这个批量，可以直接传输文件夹，毕竟 FTP 嘛</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=61650942" target="_blank">「ぼくのフレンド。」/「UGUME」のイラスト [pixiv]</a></p>
<p>哇，你是萌萌哒的friends呢！（x</p>
<hr />
<p>一听这名字就炒鸡简单（。</p>
<p>单文件程序，大小仅400多K</p>
<p>下载方式：</p>
<ul>
<li><a href="https://www.baidu.com/s?ie=UTF-8&amp;wd=%E7%AE%80%E5%8D%95FTP%20Server" target="_blank">直接百度</a></li>
<li><a href="https://files.lolico.moe/%E8%BD%AF%E4%BB%B6/FTPServer.zip" target="_blank">本站提供下载</a></li>
</ul>
<section><h2>软件截图<a href="#软件截图"><span>#</span></a></h2><p><img src="/usr/uploads/2018/02/3433651888.png" alt="" /></p></section>
<section><h2>用法<a href="#用法"><span>#</span></a></h2><p>就是截图上这么简单哒~</p><p>可以设定访问用户名密码，设置权限，自定义端口，限制最大连接数</p><p>共享目录即为 FTP 根目录</p><p>开启后右上角“×”关掉即可最小化到任务栏图标</p><p>然后访问<code>ftp://你的内网IP:服务端口</code>即可，如果服务端口是默认的<code>21</code>，那么直接访问<code>ftp://你的内网IP</code>即可</p><p>建议在资源管理器中访问，这样就可以直接跟在本地复制粘贴一样，批量下载文件</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/vultr-bare-metal/</id>
      <title type="text">[Vultr] 免费一个月 Bare Metal 独服以及 dd 安装 Windows</title>
      <published>2018-01-29T07:53:00.000Z</published>
      <updated>2020-02-21T12:00:50.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/vultr-bare-metal/"/>
      <summary type="text">其实 Vultr 推出这个 Bare Metal 系列独服已经有一段时间了，最近朋友提到才想起来有这回事，于是去研究了一下，并且为了省去 18 刀每月的 Windows 授权费用制作了专用于 Bare Metal 的 Windows Server 2016 的dd镜像。新老用户都可以获得 100 刀的试用额度，大概能用25天左右。</summary>
      <content type="html"><![CDATA[<p>其实 Vultr 推出这个 Bare Metal 系列独服已经有一段时间了，最近朋友提到才想起来有这回事，于是去研究了一下，并且为了省去 18 刀每月的 Windows 授权费用制作了专用于 Bare Metal 的 Windows Server 2016 的dd镜像。新老用户都可以获得 100 刀的试用额度，大概能用25天左右。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=52957849" target="_blank">「Isotext」/「かんざき」のイラスト [pixiv]</a></p>
<hr />
<section><h2>100 刀试用额度领取方法<a href="#100-刀试用额度领取方法"><span>#</span></a></h2><section><h3>新用户<a href="#新用户"><span>#</span></a></h3><p><a href="https://www.vultr.com/promo/baremetal/?ref=7200579" target="_blank">点击此处</a> 进入下图所示注册页面，注册成功即可获得</p><p><img src="/usr/uploads/2018/01/774759534.jpg" alt="" /></p></section><section><h3>老用户<a href="#老用户"><span>#</span></a></h3><p>直接发TK到“Billing Questions”部门，说我想要试用 Bare Metal，然后客服就会给你 100 刀试用额度</p><p><img src="/usr/uploads/2018/01/2044626013.png" alt="" /></p><p>不过注意一下你账号的月付限额是否足够，虽然这个扣费是扣试用额度的，不过这款独服要 120 刀/月，所以你的帐号月限额必须高于 120 刀</p><p>通常情况下会自动帮你把限额提到 125 刀/月，但是如果你有不止 5 刀的其他机子，那么你可能还需要继续发TK申请提高限额</p></section></section>
<section><h2>这款独服怎么样？<a href="#这款独服怎么样"><span>#</span></a></h2><p>其实个人并不是很看好 Vultr 新推出的这个系列独服</p><ol>
<li>价格昂贵，打 6 折都要 120 刀</li>
<li>机器的亮点只有 240G SSD × 2，32G 的 DDR4 2400MHz 内存，以及万兆网卡，其他配置都比较平庸</li>
</ol><p>更详细的评测可以看看 <a href="https://blog.ilemonrain.com/archives/16/" target="_blank">这里</a></p><p>不过既然是羊毛，就没有不薅的道理了，拿来玩一个月也不是什么坏事</p><div><div><div></div><div>Warning</div></div><div><p>不过要记得在免费额度用完之前删掉机子，不然是会欠费的……</p></div></div></section>
<section><h2>如何免费 dd 安装 Windows<a href="#如何免费-dd-安装-windows"><span>#</span></a></h2><p>因为如果你直接开 Windows 机器的话，是要交 18 刀/月的正版授权费的，会加在机器价格中以小时为单位计算费用，因此如果你自己有正版Key（那当然是最好），或者想直接用 KMS 激活，那么就可以采取这种方法</p><div><div><div></div><div>Note</div></div><div><p>由于使用盗版 Windows 如果被发现，会违反TOS，被如何处置就不知道了，因此还请低调使用</p></div></div><section><h3>1. 开台机器<a href="#1-开台机器"><span>#</span></a></h3><p>推荐开洛杉矶或者新加坡，相对来说到国内的网络会比其他地区的好一点（嘛，其实 Vultr 的机器除了日本的以外到国内都好不到哪里去，而且独服没有日本机房）</p><p>系统选<code>Ubuntu 16.04 x64</code>或者<code>Debian 8 x64</code>，至于选哪个没有太大所谓，反正都是要变成 Windows 的（。</p><p>Disk Configuration 选“No RAID”</p></section><section><h3>2. 开始一键 dd 安装 Windows<a href="#2-开始一键-dd-安装-windows"><span>#</span></a></h3><p>SSH 连上机器，然后直接执行以下命令</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>-qO</span><span> </span><span>InstallNET.sh</span><span> </span><span>'https://moeclub.org/attachment/LinuxShell/InstallNET.sh'</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>a+x</span><span> </span><span>InstallNET.sh</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>InstallNET.sh</span><span> </span><span>-dd</span><span> </span><span>'https://files.lolico.moe/down/dd/win2016-standard-vultr-bare-metal.gz'</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后静静等待，直到你在 VNC 上看到系统进入了 Windows 桌面，然后就可以远程桌面连接了</p><p>系　统：<code>Windows Server 2016 Standard</code>
用户名：<code>Administrator</code>
密　码：<code>lolico.moe123</code></p><p>关于这里用到的一键 dd 脚本：</p><a href="/posts/dd-win-vicer/"><div><div>[Linux] 一键全自动 dd 安装 Windows</div><div>在 Linux 机器上一键全自动安装 Windows 系统，突破没有 VNC，没有救援模式，内存比 dd 包小的限制。使用 Debian Live CD 中的 busybox 做中间媒介，经过复杂的处理，使得即使没有 DHCP 能够让 Windows 获取网络参数，也能让 Windows 操作系统在开机的第一时间能够连通网络。</div><div><span>2017-11-27</span><span>教程</span><span><span>#windows</span><span>#linux</span><span>#dd</span><span>#系统重装</span></span></div></div><div><img src="/usr/uploads/2017/11/239625258.jpg" alt="" loading="lazy" /></div></a></section><section><h3>3. 其他说明<a href="#3-其他说明"><span>#</span></a></h3><p>此 dd 包中的 Bare Metal 所需驱动由 <a href="https://blog.ilemonrain.com/" target="_blank">极光星空</a> 帮忙提取，十分感谢</p><section><h4>进入系统后请马上<a href="#进入系统后请马上"><span>#</span></a></h4><p><strong>控制面板 → 管理工具 → 磁盘管理 → 右击C盘分区 → 扩展卷 → 一路确定</strong></p><p>因为 dd 之后磁盘大小实际上是 VHD 镜像的大小，我在制作镜像的时候只留了不到1G的剩余空间，第一次装好开机自后硬盘会直接爆满掉……</p><p>所幸并没有什么太大的问题，因此我也懒得扩容 VHD 了，家里 3Mbps 上传小水管，传一次镜像到服务器上真是要了命</p></section><section><h4>激活 Windows<a href="#激活-windows"><span>#</span></a></h4><p>可以使用<a href="/kms/">本站提供的 KMS 服务</a>进行激活</p></section></section></section>
<section><h2>如果你想自己制作 dd 镜像<a href="#如果你想自己制作-dd-镜像"><span>#</span></a></h2><p>请参考教程：</p><a href="/posts/dd-diy/"><div><div>[教程] 自制 Linux 可用的 Windows dd包</div><div>不折腾不舒服星人（比如我）可以自己动手丰衣足食_(:3」」</div><div><span>2017-12-03</span><span>教程</span><span><span>#windows</span><span>#dd</span><span>#镜像制作</span><span>#无人值守</span><span>#虚拟化</span></span></div></div><div><img src="/usr/uploads/2017/12/3003598251.jpg" alt="" loading="lazy" /></div></a><p><strong>不过和制作一般的用于 VPS 的 dd 包略的过程有不同，请注意：</strong></p><ol>
<li>由于这次做的是独服的 dd 包，并不是 KVM/OVZ/XEN 之类的虚拟化环境，因此虚拟化环境驱动是不需要导入的</li>
<li>相对的，必须要导入独服所需的一些驱动，特别是网卡驱动，并且这个驱动并不包含在 Win10 的自带驱动中，因此什么驱动都不导入直接上是不行的，会导致进入系统后无法联网</li>
</ol><p>那么这些驱动应该如何获取？你可以先开一台 Bare Metal 的 Windows 机器，然后使用 <a href="http://www.chuyu.me/zh-Hans/index.html" target="_blank">DISM++</a> 提取所有驱动，拉回自己的电脑上，然后导入到 dd 镜像中，然后别忘了尽快删除你创建的 Windows 机器，毕竟是小时付的……</p><ol>
<li>需要注意的是，上述驱动是不可以在不同的 Windows 版本中使用的，已经尝试过，Vultr 的 Windows Server 2016 独服网卡驱动只能用于 2016，甚至不能用于 Win10，因此就更别说其他系统了……
Vultr 只提供了 2008 和 2016 的 Windows 系统，所以大概只能制作出 2008 和 2016 的镜像
(╯—﹏—)╯（┷━━━┷</li>
</ol></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/hfs/</id>
      <title type="text">小众软件#3 [hfs] 简易http文件服务器 局域网内轻松互传文件</title>
      <published>2018-01-25T09:47:00.000Z</published>
      <updated>2018-02-02T11:39:35.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/hfs/"/>
      <summary type="text">好久没写点实用性推荐文章了，因为最近不管是碧蓝还是废狗都是肝度满满…… 这次介绍一个有用的单文件程序——hfs，一个简易的 HTTP 文件服务器，可以让你在局域网环境内方便的分享文件或者接收文件。当然，如果你有公网IP甚至也可以直接分享到外网环境。</summary>
      <content type="html"><![CDATA[<p>好久没写点实用性推荐文章了，因为最近不管是碧蓝还是废狗都是肝度满满……</p>
<p>这次介绍一个有用的单文件程序——hfs，一个简易的 HTTP 文件服务器，可以让你在局域网环境内方便的分享文件或者接收文件。当然，如果你有公网IP甚至也可以直接分享到外网环境。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=66819724" target="_blank">「ニコラス」/「Kätzchen」のイラスト [pixiv]</a></p>
<hr />
<p><a href="http://www.rejetto.com/hfs/?f=dl" target="_blank">官网下载（英文版）</a></p>
<p><a href="https://files.lolico.moe/%E8%BD%AF%E4%BB%B6/hfs.zip" target="_blank">本站提供下载（中文版）</a></p>
<section><h2>软件截图<a href="#软件截图"><span>#</span></a></h2><p><img src="/usr/uploads/2018/01/1284111164.png" alt="" /></p><p><img src="/usr/uploads/2018/01/2165393158.png" alt="" /></p></section>
<section><h2>基本使用方法<a href="#基本使用方法"><span>#</span></a></h2><p>直接把文件/文件夹拖到左边的“虚拟文件系统”即可，如果是文件夹的话会让你选是“真实目录”还是“虚拟目录”，一般情况下选真实就行</p><p>然后你就可以访问<code>http://你的内网IP:端口</code>来管理文件了，如果是默认的<code>80</code>端口则直接访问<code>http://你的内网IP</code>即可。</p><p>如果访问不了，那么请检查一下防火墙是不是没开放你要使用的端口，嫌更改防火墙规则麻烦的话直接关闭防火墙也行</p><p>在程序中右击一个目录，属性，你可以设置访问用户名、密码，以及访问者的操作权限</p><p>一开始的简易模式下只会给出很基础的设置项，你可以切换到专家模式来查看和使用更多的进阶设置项</p></section>
<section><h2>主要进阶功能<a href="#主要进阶功能"><span>#</span></a></h2><ol>
<li>直接指定根目录的文件路径</li>
<li>限制速度、全局并发连接数、单IP并发连接数、禁止多线程下载</li>
<li>设置IP黑名单、防盗链</li>
<li>设定只监听某个IP而不是全部</li>
<li>自定义网页前端模板</li>
<li>将 hfs 当做 nginx 那样的网站服务器来临时使用，实际上直接在文件夹中放上<code>index.html</code>之后通过 hfs 去访问文件夹，确实是可以显示网页的
如果想自定义默认首页的话，右击文件夹，属性，里面可以设置</li>
</ol><p>更多功能，可以自行在程序菜单中寻找摸索</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/recent-20180118/</id>
      <title type="text">近期发生的二三事</title>
      <published>2018-01-18T10:20:00.000Z</published>
      <updated>2020-02-19T09:38:27.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/recent-20180118/"/>
      <summary type="text">大概就是讲讲自己最近发生的一些事，宣泄一下（</summary>
      <content type="html"><![CDATA[<p>大概就是讲讲自己最近发生的一些事，宣泄一下（</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=51281553" target="_blank">「夏コミ受かりました！」/「ぺこ／かにビーム」のイラスト [pixiv]</a></p>
<p>在我的博客里，不管是多水的文章，头图都不会少滴</p>
<hr />
<section><h2>期末考试<a href="#期末考试"><span>#</span></a></h2><p>一天预习一本书的感觉真是太刺激了</p><p><img src="/usr/uploads/2017/09/2684621544.jpg" alt="" /></p><p>分析了一下也是自己作死，这学期专业选修课选的太多了，大作业又有很多是那种吃力不讨好的，结果搞到考试前一个周末才正式做完所有选修的大作业</p><p><img src="/usr/uploads/2018/01/2978187976.gif" alt="" /></p><p>然后开始一天预习一本书</p><p><img src="/usr/uploads/2018/01/3434057954.gif" alt="" /></p><p>结果可想而知（反正常微分已经光荣挂科）</p><p>这也是我前面停更了两周的原因</p><p>然后要选下学期的课，我为了能尽量早点毕业……又选了一堆选修</p><p>看看下学期我会死得多惨</p></section>
<section><h2>考完试也不闲<a href="#考完试也不闲"><span>#</span></a></h2><p>为什么？</p><p>因为我赶大作业和复习考试的那两周，刚好碰上了下面两大事件：</p><p><img src="https://view.fate-go.jp/wp-content/uploads/2018/re_counterfeit_jdri8/top_banner.png" alt="" /></p><p><img src="/usr/uploads/2018/01/3430473824.jpg" alt="" /></p><p>为了学业当然还是忍一忍专心复习的，考完试之后嘛……</p><p><img src="/usr/uploads/2018/01/198813614.jpg" alt="" /></p><p>这活动真不会挑时间，不过还好我有两部手机，双游齐肝，到今天为止基本肝完了</p></section>
<section><h2>这个假期打算要做的事情<a href="#这个假期打算要做的事情"><span>#</span></a></h2><ol>
<li>打理一下B站的 Nekopara 萌化主题</li>
<li>学 Python，开发一个寻图QQ机器人</li>
</ol></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/2017owari/</id>
      <title type="text">2017年度萌化小总结~</title>
      <published>2017-12-31T19:58:00.000Z</published>
      <updated>2018-01-18T10:23:31.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/2017owari/"/>
      <summary type="text">不知不觉这一年就又过去咯 (*ﾟ∀ﾟ*) 以前没写过这种总结文，干脆连以前的份一起写了吧，总结一下以前做过的各种萌化，算是个交代。</summary>
      <content type="html"><![CDATA[<p>不知不觉这一年就又过去咯 (*ﾟ∀ﾟ*)
以前没写过这种总结文，干脆连以前的份一起写了吧，总结一下以前做过的各种萌化，算是个交代。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=58409932" target="_blank">「リルーっ!!」/「あっきー人」のイラスト [pixiv]</a>
芬里尔真踏吗萌（虽然没玩过神女控</p>
<section><h1>2013~2017 萌化之路<a href="#20132017-萌化之路"><span>#</span></a></h1><p>总的来说2017年可以说是对我影响最大的一年。</p><section><h2>2013<a href="#2013"><span>#</span></a></h2><section><h3>安卓萌化魔改<a href="#安卓萌化魔改"><span>#</span></a></h3><p>13年我还在上高一的时候，终于有了安卓手机，辣鸡酷派v699，然后突然就开始做安卓相关的萌化了（？？？）</p><section><h4>微博<a href="#微博"><span>#</span></a></h4><p>最开始做的是微博皮肤的萌化，由于 root 了之后可以用幸运破解器破解安卓内核，使得系统可以无视签名验证安装应用，因此可以找到微博皮肤安装包然后修改里面的图片，这大概算是我萌化生涯的处女作了……</p><p><img src="http://ww1.sinaimg.cn/large/71785a53tw1e72u4u9x4oj208w0dcjsv.jpg" alt="" /></p></section><section><h4>系统<a href="#系统"><span>#</span></a></h4><p>后来起了雄心壮志励志要萌化安卓系统（我以前到底是哪里来的信心）</p><p><img src="/usr/uploads/2017/09/3604398256.jpg" alt="" /></p><p>查阅了各种资料并且实验了很久之后终于成功做到了把安卓系统的默认纯黑背景界面给换成图片</p><p><img src="http://ww1.sinaimg.cn/large/71785a53jw1ekx7a5ulfxj20dc0m8q61.jpg" alt="" /></p><p>但是实际上实现起来非常困难而且这么做之后好像会有些莫名其妙导致系统死机的bug，因此最后还是放弃了这个计划。</p></section></section></section><section><h2>2014<a href="#2014"><span>#</span></a></h2><section><h3>jubeat plus<a href="#jubeat-plus"><span>#</span></a></h3><p>高二的时候我才正式开始做一些萌化相关的东西，同时也是刚入坑音游一段时间以后，最开始是做了几款 jubeat plus 的萌化皮肤并且发在贴吧上了。</p><p>合集：<a href="https://pan.baidu.com/s/1kUHkTQf" target="_blank">https://pan.baidu.com/s/1kUHkTQf</a></p><section><h4>2014年1月<a href="#2014年1月"><span>#</span></a></h4><p><a href="https://tieba.baidu.com/p/2829463848?pid=44873403124" target="_blank">jubeat plus自制皮肤 変态王子と笑わない猫</a></p><p><img src="/usr/uploads/2018/01/2852848392.jpg" alt="" /></p><p>以及 R17 福利版</p><p><img src="/usr/uploads/2018/01/2612143864.jpg" alt="" /></p></section><section><h4>2014年7月<a href="#2014年7月"><span>#</span></a></h4><p><a href="https://tieba.baidu.com/p/3167134885?pid=53801597825" target="_blank">jubeat plus自制皮肤 琪露诺</a></p><p><img src="/usr/uploads/2018/01/1322548139.jpg" alt="" /></p></section></section></section><section><h2>2015<a href="#2015"><span>#</span></a></h2><section><h3>Windows 主题<a href="#windows-主题"><span>#</span></a></h3><p>再后来，大概是2015年左右，我开始不满足于这些简单的P图萌化，于是尝试去做了 Windows 主题。</p><p>当时我使用的还是 Win7，因此是做了一款 Win7 的主题，但是由于当时主题制作时的很多参数对我来说还没法理解（特别是文字颜色那块），经验不足，因此拿了一个色调相似的雪初音主题，硬是改成了琪露诺主题……
（吐槽：结果不还是变成了P图萌化嘛！）</p><p><img src="/usr/uploads/2018/01/926410100.png" alt="" /></p><p>当时还是相当有激情的，三天基本啥也没干就做主题了。</p><p>成品：<a href="https://files.lolico.moe/Windows%E5%A4%96%E8%A7%82%E7%9B%B8%E5%85%B3/%E8%90%8C%E5%8C%96%E4%BD%9C%E5%93%81%E9%BB%91%E5%8E%86%E5%8F%B2/%E7%90%AA%E9%9C%B2%E8%AF%BAWin7%E4%B8%BB%E9%A2%98v2.0_by%E7%A5%9E%E4%BB%A3%E7%BB%AE%E5%87%9B.exe" target="_blank">https://files.lolico.moe/Windows外观相关/萌化作品黑历史/琪露诺Win7主题v2.0_by神代绮凛.exe</a></p><p>当时由于工具软件的一些bug的原因导致这个主题虽然完成了但是仍然存在着很小的一个bug，导致某些萌化效果显示不出来，成为了我多年的心结。</p><p><img src="/usr/uploads/2018/01/374244458.jpg" alt="" /></p><p>由于年代太久远了，我记得在微博晒过图然而搜不到了，我也不记得我当时自己说了些啥，所以就不放图了。</p><p><img src="/usr/uploads/2018/01/284721690.jpg" alt="" /></p><p>好像在这之后就没干什么事……</p><p>**后话：**后来我换了 Win10 之后打算把这主题重制一遍，并且也重新找到了合适的主题修改工具，大概断断续续做了三天左右，由于 Win10 的主题还是有着太多的样式与外观问题，做出来的效果并不满意，并且产生了很多新的bug，最终还是把这个项目给坑了_(&lt;3&gt;」」</p><p><img src="/usr/uploads/2018/01/2617278291.png" alt="" /></p></section><section><h3>jubeat<a href="#jubeat"><span>#</span></a></h3><p>纪念一下去香港打了 jubeat prop</p><p><img src="/usr/uploads/2018/01/650836613.jpg" alt="" /></p></section><section><h3>手绘<a href="#手绘"><span>#</span></a></h3><p>当时一时兴起接触了一下手绘，一开始临摹了很多作品，不过后来还是意识到自己没有创作天赋，因此弃了。</p><p>一开始的临摹作品：基本不能看，现在看了都觉得……死了算了</p><p><img src="/usr/uploads/2018/01/2091537995.png" alt="" /></p><p>大概也就那个真白还算能看，毕竟用爱临摹的老婆</p><p><img src="/usr/uploads/2018/01/374244458.jpg" alt="" /></p><p>退坑前的最后一幅临摹，自我感觉算是能看一点，长达两张A4纸的超大临摹</p><p><img src="/usr/uploads/2018/01/3729722632.png" alt="" /></p></section></section><section><h2>2016<a href="#2016"><span>#</span></a></h2><p>前半年好像没做什么事情一直在摸鱼，一直就是打打手游网游补番度日的感觉，也一直跟一些老圈子的人交流，平淡无奇，基本沉浸在自己的电脑啊手机啊之类的自用萌化中，没做出过什么作品来。</p><section><h3>osu!<a href="#osu"><span>#</span></a></h3><p>沉迷 Nekopara，于是趁着放假用了三天时间做了个 osu 皮肤……</p><p><img src="/usr/uploads/2018/01/3720183014.jpg" alt="" /></p><a href="/posts/osu-nekopara/"><div><div>[osu] Nekopara V3.1</div><div>osu! Skin - Nekopara 说明 这是一个我东拼西凑并自己魔改部分样式的 osu 皮肤。</div><div><span>2017-09-01</span><span>萌化项目</span><span><span>#osu</span><span>#nekopara</span><span>#皮肤</span><span>#萌化</span></span></div></div><div><img src="/usr/uploads/2017/09/2389650833.jpg" alt="" loading="lazy" /></div></a></section><section><h3>Photoshop<a href="#photoshop"><span>#</span></a></h3><p>萌化哪能少的了ps</p><a href="/posts/ps2017-fu/"><div><div>[Photoshop CC 2017] 启动界面萌化</div><div>Ps CC 2017 启动界面 - 芙 说明 这是一个Photoshop CC 2017的启动界面萌化。</div><div><span>2017-09-01</span><span>萌化项目</span><span><span>#photoshop</span><span>#启动界面</span><span>#萌化</span></span></div></div><div><img src="/usr/uploads/2017/09/925604231.jpg" alt="" loading="lazy" /></div></a></section><section><h3>css<a href="#css"><span>#</span></a></h3><p>在2016年年末我刚开始接触 css 一类的关于网页的东西，目的也是为了做萌化。</p><p>契机是我在无意间知道了有一个叫做 Stylish 的插件，可以自定义网页的样式，于是一拍大腿，这不是可以拿来做萌化么</p><p><img src="/usr/uploads/2018/01/3378271588.jpg" alt="" /></p><p>然后经过了一周的摸索，边做边学，完成了我的第一个 css 萌化样式作品：</p><a href="/posts/baidu-moe/"><div><div>[Stylish] 百度萌化样式</div><div>百度萌化样式 此早期黑历史已经停止维护 简介 此Stylish样式为百度系列的萌化，优化了部分显示效果，屏蔽了一些无用元素及广告推广。 背景图片可以自行设置。</div><div><span>2017-09-01</span><span>萌化项目</span><span><span>#百度</span><span>#萌化</span><span>#stylish</span><span>#css</span></span></div></div><div><img src="/usr/uploads/2017/09/2735501547.jpg" alt="" loading="lazy" /></div></a><p>大概是因为本来专业也就是写代码，html 和 css 这块对我来说都很好理解，学的也很快（呸，其实是对萌化的爱啦）</p><p><img src="/usr/uploads/2018/01/3222937670.jpg" alt="" /></p><p>后来我开坑了至今为止最大的一个萌化项目，也是我第二个 css 萌化样式作品：</p><a href="/posts/bilibili-nekopara/"><div><div>[已完结] 哔哩哔哩 Nekopara B站网页萌化主题</div><div>終わりました。</div><div><span>2017-09-01</span><span>萌化项目</span><span><span>#bilibili</span><span>#萌化</span><span>#nekopara</span><span>#stylus</span><span>#css</span></span></div></div><div><img src="/usr/uploads/2021/12/2404136611.png" alt="" loading="lazy" /></div></a><p>目前也仍在维护和更新中。</p></section><section><h3>Wallpaper Engine<a href="#wallpaper-engine"><span>#</span></a></h3><p>这个软件当时爆火，于是自己也去 Steam 买来用了。
然后萌化之心顿起……然后就……</p><a href="/posts/we-okita-souji/"><div><div>[Wallpaper Engine 动态壁纸] FGO - 沖田総司 飘雪 1080P(waifu2x) 60fps</div><div>WE 动态壁纸 冲田总司 说明 这是一个我自制自用的Wallpaper Engine动态壁纸</div><div><span>2017-09-01</span><span>萌化项目</span><span><span>#wallpaper engine</span><span>#动态壁纸</span><span>#fgo</span><span>#冲田总司</span></span></div></div><div><img src="/usr/uploads/2017/09/1750154548.jpg" alt="" loading="lazy" /></div></a><p>不过这个作品出来了之后其传播之广还是吓了我一跳，实际上没什么太大的技术含量，就是用 AE 做的一个稍微有点特效的视频壁纸，简洁风，主要是给自己用的（我一直用的都是自己做的这个壁纸，没换过其他的，自己做的才有成就感嘛）。</p><p><img src="/usr/uploads/2018/01/652264389.png" alt="" /></p><p>当然，现在已经几乎看不到订阅增长了，已经饱和了，而且更优秀的作品越来越多，我这个简单的作品已经算不上什么了。</p></section></section><section><h2>2017<a href="#2017"><span>#</span></a></h2><section><h3>建站之路<a href="#建站之路"><span>#</span></a></h3><p>分为两个阶段</p><section><h4>上半年<a href="#上半年"><span>#</span></a></h4><p>一开始是将我家里的小米路由器3刷了老毛子固件然后当成服务器使了，一开始想折腾这块主要也是为了宣传自己的萌化作品。</p><p>由于毕竟是路由器，WP都跑不动的那种，于是弄了个 z-blog 勉强用着，并且也用了自己学到的 css 进行了一波魔改。
而且当时家里虽然有公网IP，但是运营商都封80端口，因此一开始拿的是非80端口跑站。再后来，研究了下SSL，上了证书就用443了，算是舒服了很多。</p><p>至于站点的样子，当时截了图但是找不到了，而且原站已经被我连数据库一起删了，旧的不去新的不来嘛，算了，就让这个历史站点淹没在黑历史中吧~</p><p><img src="/usr/uploads/2018/01/2741222619.jpg" alt="" /></p></section><section><h4>下半年<a href="#下半年"><span>#</span></a></h4><p>我是大概在9月份的时候才开始真正入手 VPS 并且真正的接触建站这块，契机大概是大三开学时候的 Linux 基础课程。
我是属于比较懒的人，现在过的好就可以了的那种感觉，如果没有学校组织的 Linux 课程我可能还是处在用路由器建站的阶段……</p><p>由于机器条件好了，于是就寻思找个更好的博客程序，z-blog 还是有点不太好用，然后就找到了现在在用的 Typecho。</p><p>接着就是找主题，找了无数主题之后还是决定买了目前在用的 handsome 主题，接着经过大量的魔改，就成了现在这副样子。</p><p><img src="/usr/uploads/2018/01/4089928216.jpg" alt="" /></p><p>也多亏目前的建站经历，认识了更多的人，生活也有了更多乐趣。</p></section></section></section></section>
<section><h1>2018<a href="#2018"><span>#</span></a></h1><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Year</span><span> newYear </span><span><span>=</span><span> </span></span><span>new</span><span> </span><span>Year</span><span>(</span><span>2018</span><span><span>)</span><span>;</span></span></div></div><div><div><div>2</div></div><div><span>while</span><span><span>(</span><span>!</span></span><span>newYear</span><span>.</span><span>isEnd</span><span><span>()</span><span>){</span></span></div></div><div><div><div>3</div></div><div><span>  </span><span>try</span><span>(){</span></div></div><div><div><div>4</div></div><div><span>    </span><span>newYear</span><span>.</span><span>learn</span><span>();</span></div></div><div><div><div>5</div></div><div><span>    </span><span>newYear</span><span>.</span><span>enjoy</span><span>();</span></div></div><div><div><div>6</div></div><div><span>    </span><span>newYear</span><span>.</span><span>createHappiness</span><span>();</span></div></div><div><div><div>7</div></div><div><span><span>  </span></span><span>}</span><span>catch</span><span>(</span><span>UnhappyException</span><span><span> </span><span>e</span><span>){</span></span></div></div><div><div><div>8</div></div><div><span>    </span><span>e</span><span>.</span><span>consume</span><span>();</span></div></div><div><div><div>9</div></div><div><span><span>  </span></span><span>}</span><span>finally</span><span>(){</span></div></div><div><div><div>10</div></div><div><span>    </span><span>newYear</span><span>.</span><span>gain</span><span>();</span></div></div><div><div><div>11</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>12</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/spacesniffer/</id>
      <title type="text">小众软件#2 [SpaceSniffer] 文件夹大小统计 找出侵占磁盘空间的罪魁祸首</title>
      <published>2017-12-22T05:25:00.000Z</published>
      <updated>2019-04-29T15:38:50.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/spacesniffer/"/>
      <summary type="text">你是否看着磁盘容量一天天减少而不知所措？手动翻找清理却又身心俱疲并且成效不高？SpaceSniffer 能直观的以矩形图的方式告诉你哪些文件夹占了大量空间，并且支持各种条件的筛选，与资源管理器一样简单的文件操作，和垃圾文件说拜拜~</summary>
      <content type="html"><![CDATA[<p>你是否看着磁盘容量一天天减少而不知所措？手动翻找清理却又身心俱疲并且成效不高？SpaceSniffer 能直观的以矩形图的方式告诉你哪些文件夹占了大量空间，并且支持各种条件的筛选，与资源管理器一样简单的文件操作，和垃圾文件说拜拜~</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=53839886" target="_blank">「賢者の弟子を名乗る賢者」/「藤原」のイラスト [pixiv]</a></p>
<hr />
<p>软件主页：<a href="http://www.uderzo.it/main_products/space_sniffer/" target="_blank">http://www.uderzo.it/main_products/space_sniffer/</a>
官方英文版下载：<a href="http://www.fosshub.com/SpaceSniffer.html" target="_blank">http://www.fosshub.com/SpaceSniffer.html</a></p>
<p>本站提供中文版下载：<a href="https://files.lolico.moe/show/software/SpaceSniffer_v1.3.0.2_CHS.zip" target="_blank">SpaceSniffer v1.3.0.2 CHS</a></p>
<p>绿色单文件软件，大小仅有 2 MB，解压后直接使用</p>
<section><h2>使用<a href="#使用"><span>#</span></a></h2><p>运行后弹出窗口选择需要分析的盘符，此时你可以点击选择某个盘符，或按住“ctrl”同时点选多个盘符，也可以点击“Path:”选择指定文件夹。点击“Start”后 SpaceSniffer 会以极快的速度检索磁盘，并将所有文件夹以矩形图的形式显示出来，可以直观的看出各个文件夹的占用情况。</p><p><img src="/usr/uploads/2017/12/660178397.gif" alt="" /></p><p>你还可以点击图中的矩形，程序会进一步将这个矩形分割，显示出内部文件/文件夹的占用情况，也可以直接点击工具栏中的按钮调整整体显示精度。</p><p>更强大的是，SpaceSniffer 支持多种条件的筛选，比如设定<code>&gt;50mb</code>就会筛选出体积大于 50 MB 的文件夹，设定<code>&lt;3months</code>可以找出 3 个月内的文件夹等。更多筛选规则可通过 help -&gt; filtering help 查看。</p><p><img src="/usr/uploads/2017/12/2021218936.gif" alt="" /></p><p>SpaceSniffer 集成了与资源管理器同样的文件操作方式，在矩形上点击右键就会弹出熟悉的右键菜单，你可以直接在程序中对相应的文件/文件夹进行移动或者删除等操作，右键菜单中按住“Shift”再点击删除即可永久删除的操作也是和在资源管理器中完全一样的。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/rufus/</id>
      <title type="text">小众软件#1 [rufus] 轻便强大的U盘格式化/刻录工具</title>
      <published>2017-12-18T17:04:00.000Z</published>
      <updated>2018-01-18T10:25:04.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/rufus/"/>
      <summary type="text">讲到U盘刻录估计一般第一时间想到的都是老牌免费软件 UltraISO，这个软件刻录光盘还是不错的，但是刻录U盘就显得有些捉襟见肘……而这次介绍的免费软件 rufus，体积只有不到 1MB，单文件，但是却能拥有绝大多数U盘刻录需要的功能。</summary>
      <content type="html"><![CDATA[<p>讲到U盘刻录估计一般第一时间想到的都是老牌免费软件 UltraISO，这个软件刻录光盘还是不错的，但是刻录U盘就显得有些捉襟见肘……而这次介绍的免费软件 rufus，体积只有不到 1MB，单文件，但是却能拥有绝大多数U盘刻录需要的功能。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=10415176" target="_blank">「Angel Beats!」/「茨乃」のイラスト [pixiv]</a>
很怀念，AB是入宅作</p>
<hr />
<p>软件主页：<a href="http://rufus.akeo.ie/" target="_blank">http://rufus.akeo.ie/</a>
Github：<a href="https://github.com/pbatard/rufus" target="_blank">https://github.com/pbatard/rufus</a></p>
<p>本站提供下载：<a href="https://files.lolico.moe/%E8%BD%AF%E4%BB%B6/rufus-2.18.zip" target="_blank">rufus v2.18</a></p>
<section><h2>软件界面<a href="#软件界面"><span>#</span></a></h2><p><img src="/usr/uploads/2017/12/130366982.png" alt="" /></p></section>
<section><h2>重要功能<a href="#重要功能"><span>#</span></a></h2><ul>
<li>多国语言，支持中文</li>
<li>支持USB可移动磁盘甚至移动硬盘</li>
<li>有多种分区方案可供选择
<img src="/usr/uploads/2017/12/420674605.png" alt="" /></li>
<li>自由选择刻录后U盘的文件系统（再也不用手动转啦）
<img src="/usr/uploads/2017/12/958462660.png" alt="" /></li>
<li>不仅能刻录普通 ISO 镜像，还能刻录 DD 镜像</li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/ssh-abort-solution/</id>
      <title type="text">[ssh] 解决提示 Software caused connection abort 并无法连接的问题</title>
      <published>2017-12-12T16:09:53.000Z</published>
      <updated>2017-12-12T16:09:53.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/ssh-abort-solution/"/>
      <summary type="text">ssh 一连接就会直接卡住并提示“Software caused connection abort”的解决方法</summary>
      <content type="html"><![CDATA[<p>ssh 一连接就会直接卡住并提示“Software caused connection abort”的解决方法</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=62818023" target="_blank">「抗えないほどの睡魔に襲われてる…」/「うさ城まに」のイラスト [pixiv]</a>
可爱的幼年纱雾w</p>
<hr />
<p>有好几种情况会出现这个提示，一般都是 ssh 长时间无操作然后导致的，这种情况十分好解决，在 ssh 客户端中设置隔一定时间发送空包保持连接即可。</p>
<p><strong>但是我遇到的是另一种情况。</strong></p>
<p>一打开 ssh 客户端进行连接，然后客户端就会卡住，等待几秒钟之后提示<code>Software caused connection abort</code>，根本无法正常的连接。</p>
<p>这种现象一般出现于更改了 ssh 端口之后（这是我经历过最多的……）</p>
<section><h2>解决方法<a href="#解决方法"><span>#</span></a></h2><p>其实异常的简单，但是首先你必须是主机面板用户（例如宝塔面板），或者具有足以修改系统文件权限的 FTP 账户，因为你已经没办法通过 ssh 登录，WinSCP 也就理所当然无法使用。</p><ol>
<li>编辑<code>/etc/hosts.allow</code>文件</li>
<li>在末尾加上一行<code>sshd: all</code>，保存</li>
</ol><p>好了，现在你应该能正常连接 ssh 了
(╯—□—)╯（┷━━━┷</p><p>很迷</p><p>至于为什么会出现这种情况，我也不是太能理解，自己的 IP 在<code>hosts.deny</code>中并没有被阻止，防火墙也没有任何问题，并且一开始在端口尚未修改的时候是可以正常连接的。</p><p>不过总归是把问题解决了（。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/typecho-head-cache/</id>
      <title type="text">[Typecho] Gravatar &amp; Qlogo 评论头像缓存</title>
      <published>2017-12-10T17:35:00.000Z</published>
      <updated>2020-08-12T07:29:34.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/typecho-head-cache/"/>
      <summary type="text">支持 Handsome 4.2.0 修改主题获取头像的函数，使得评论头像能够缓存在本地并加载，而不用每次都由来访者从 Gravator 和 Qlogo 加载，节省加载时间。</summary>
      <content type="html"><![CDATA[<div><div><div></div><div>Tip</div></div><div><p>支持 Handsome 4.2.0</p></div></div>
<p>修改主题获取头像的函数，使得评论头像能够缓存在本地并加载，而不用每次都由来访者从 Gravator 和 Qlogo 加载，节省加载时间。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=58291689" target="_blank">「ウォーロックジータちゃん」/「konomi★きのこのみ」のイラスト [pixiv]</a></p>
<hr />
<p>2017-12-05：随 Handsome 4.1.1 主题同步更新
2017-12-11：增加一个检测头像下载失败重新下载的功能</p>
<section><h2>说明<a href="#说明"><span>#</span></a></h2><p>这次魔改是针对 <strong>handsome主题</strong> 的，即本站所使用的主题。实际上是从“Gravatar 头像缓存插件”获得的启发，也参考了其代码。如果这个插件（Github项目地址在最后）不支持你所使用的主题，比如 handsome主题，那么你也可以试试仿照着魔改一下。</p><p><strong>2017-10-21</strong> 修复一个 Qlogo 默认头像不能识别的 bug</p></section>
<section><h2>思路<a href="#思路"><span>#</span></a></h2><ul>
<li>以一个每个邮箱独有的标志命名每个缓存文件，例如 Gravator 就是邮箱的 md5，Qlogo 就是QQ号。</li>
<li>如果不存在已经缓存的头像，或者超出设定的缓存时限，则将头像下载到服务器本地。</li>
<li>下载成功，则返回本地缓存图片路径。</li>
<li>下载失败，或者得到的为 Gravator 或者 Qlogo 的默认头像，则返回自己设定的默认头像。</li>
<li>如果存在已经缓存的头像，那么直接返回缓存的图片路径。</li>
</ul></section>
<section><h2>魔改代码<a href="#魔改代码"><span>#</span></a></h2><p>如果是 handsome 主题则直接修改<code>/(网站根目录)/usr/themes/handsome/libs/Utils.php</code>
在此文件的类的末端（即最后一个右大括号<code>}</code>之前）加上如下4个函数：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>//缓存Qlogo头像</span></div></div><div><div><div>2</div></div><div><span>public</span><span> </span><span>static</span><span> </span><span>function</span><span> </span><span>getQlogoCache</span><span>(</span><span>$avatar</span><span>,</span><span>$nk</span><span>){</span></div></div><div><div><div>3</div></div><div><span>    </span><span>//setting-start</span></div></div><div><div><div>4</div></div><div><span>    </span><span>$options</span><span><span> </span><span>=</span><span> </span></span><span>mget</span><span>();</span></div></div><div><div><div>5</div></div><div><span>    </span><span>$default</span><span><span> </span><span>=</span><span> </span></span><span>''</span><span>;</span></div></div><div><div><div>6</div></div><div><span>    </span><span>if</span><span> (</span><span>strlen</span><span>(</span><span>$options</span><span>-&gt;</span><span>defaultAvator</span><span><span>) </span><span>&gt;</span><span> </span></span><span>0</span><span>){</span></div></div><div><div><div>7</div></div><div><span>        </span><span>$default</span><span><span> </span><span>=</span><span> </span></span><span>$options</span><span>-&gt;</span><span>defaultAvator</span><span>;</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>9</div></div><div><span>    </span><span>//缓存时间，单位秒，1209600秒=14天</span></div></div><div><div><div>10</div></div><div><span>    </span><span>$timeCache</span><span><span> </span><span>=</span><span> </span></span><span>1209600</span><span>;</span></div></div><div><div><div>11</div></div><div><span>    </span><span>//头像缓存目录</span></div></div><div><div><div>12</div></div><div><span>    </span><span>$tempDir</span><span><span> </span><span>=</span><span> </span></span><span>"/usr/uploads/qlogoCache/"</span><span>;</span></div></div><div><div><div>13</div></div><div><span>    </span><span>//setting-end</span></div></div><div><div><div>14</div></div><div>
</div></div><div><div><div>15</div></div><div><span>    </span><span>$host</span><span><span> </span><span>=</span><span> </span></span><span>"https://q.qlogo.cn"</span><span>;</span></div></div><div><div><div>16</div></div><div><span>    </span><span>$imgName</span><span><span> </span><span>=</span><span> </span></span><span>$nk</span><span> </span><span>.</span><span> </span><span>".jpg"</span><span>;</span></div></div><div><div><div>17</div></div><div><span>    </span><span>$localImgFile</span><span><span> </span><span>=</span><span> </span></span><span>__TYPECHO_ROOT_DIR__</span><span> </span><span>.</span><span> </span><span>$tempDir</span><span> </span><span>.</span><span> </span><span>$imgName</span><span>;</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>    </span><span>if</span><span><span>(</span><span>!</span></span><span>self</span><span>::</span><span>mkdirs</span><span>(</span><span>dirname</span><span>(</span><span>$localImgFile</span><span>))){</span></div></div><div><div><div>20</div></div><div><span>        </span><span>throw</span><span> </span><span>new</span><span> </span><span>exception</span><span>(</span><span>'GravatarCache 缓存目录创建失败，请检查指定的目录是否可写'</span><span><span> </span><span>);</span></span></div></div><div><div><div>21</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>22</div></div><div><span>    </span><span>if</span><span><span>(</span><span>!</span></span><span>file_exists</span><span>(</span><span>$localImgFile</span><span><span>) </span><span>||</span><span> (</span></span><span>time</span><span><span>() </span><span>-</span><span> </span></span><span>filemtime</span><span>(</span><span>$localImgFile</span><span><span>)) </span><span>&gt;</span><span> </span></span><span>$timeCache</span><span>){</span></div></div><div><div><div>23</div></div><div><span>        </span><span>if</span><span><span>(</span><span>!</span></span><span>self</span><span>::</span><span>download</span><span>(</span><span>$avatar</span><span>, </span><span>$host</span><span>, </span><span>$localImgFile</span><span>)) </span><span>return</span><span> </span><span>$default</span><span>;</span></div></div><div><div><div>24</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>25</div></div><div>
</div></div><div><div><div>26</div></div><div><span>    </span><span>$fileSize</span><span><span> </span><span>=</span><span> </span></span><span>filesize</span><span>(</span><span>$localImgFile</span><span>);</span></div></div><div><div><div>27</div></div><div><span>    </span><span>if</span><span>(</span><span>$fileSize</span><span><span> </span><span>&lt;</span><span> </span></span><span>1</span><span>){</span></div></div><div><div><div>28</div></div><div><span>        </span><span>if</span><span><span>(</span><span>!</span></span><span>self</span><span>::</span><span>download</span><span>(</span><span>$avatar</span><span>, </span><span>$host</span><span>, </span><span>$localImgFile</span><span>)) </span><span>return</span><span> </span><span>$default</span><span>;</span></div></div><div><div><div>29</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>30</div></div><div><span>    </span><span>if</span><span>(</span><span>$fileSize</span><span><span> </span><span>==</span><span> </span></span><span>1512</span><span><span> </span><span>||</span><span> </span></span><span>$fileSize</span><span><span> </span><span>==</span><span> </span></span><span>971</span><span>) </span><span>return</span><span> </span><span>$default</span><span>;</span></div></div><div><div><div>31</div></div><div>
</div></div><div><div><div>32</div></div><div><span>    </span><span>return</span><span> </span><span>$tempDir</span><span> </span><span>.</span><span> </span><span>$imgName</span><span>;</span></div></div><div><div><div>33</div></div><div><span>}</span></div></div><div><div><div>34</div></div><div><span>//缓存Gravator头像</span></div></div><div><div><div>35</div></div><div><span>public</span><span> </span><span>static</span><span> </span><span>function</span><span> </span><span>getGravatorCache</span><span>(</span><span>$email</span><span>,</span><span>$host</span><span>){</span></div></div><div><div><div>36</div></div><div><span>    </span><span>//setting-start</span></div></div><div><div><div>37</div></div><div><span>    </span><span>$options</span><span><span> </span><span>=</span><span> </span></span><span>mget</span><span>();</span></div></div><div><div><div>38</div></div><div><span>    </span><span>$default</span><span><span> </span><span>=</span><span> </span></span><span>''</span><span>;</span></div></div><div><div><div>39</div></div><div><span>    </span><span>if</span><span> (</span><span>strlen</span><span>(</span><span>$options</span><span>-&gt;</span><span>defaultAvator</span><span><span>) </span><span>&gt;</span><span> </span></span><span>0</span><span>){</span></div></div><div><div><div>40</div></div><div><span>        </span><span>$default</span><span><span> </span><span>=</span><span> </span></span><span>$options</span><span>-&gt;</span><span>defaultAvator</span><span>;</span></div></div><div><div><div>41</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>42</div></div><div><span>    </span><span>//缓存时间，单位秒，1209600秒=14天</span></div></div><div><div><div>43</div></div><div><span>    </span><span>$timeCache</span><span><span> </span><span>=</span><span> </span></span><span>1209600</span><span>;</span></div></div><div><div><div>44</div></div><div><span>    </span><span>//头像缓存目录</span></div></div><div><div><div>45</div></div><div><span>    </span><span>$tempDir</span><span><span> </span><span>=</span><span> </span></span><span>"/usr/uploads/avatarCache/"</span><span>;</span></div></div><div><div><div>46</div></div><div><span>    </span><span>//setting-end</span></div></div><div><div><div>47</div></div><div>
</div></div><div><div><div>48</div></div><div><span>    </span><span>$url</span><span><span> </span><span>=</span><span> </span></span><span>'/'</span><span>;</span><span>//自定义头像目录,一般保持默认即可</span></div></div><div><div><div>49</div></div><div><span>    </span><span>$size</span><span><span> </span><span>=</span><span> </span></span><span>'40'</span><span>;</span><span>//自定义头像大小</span></div></div><div><div><div>50</div></div><div><span>    </span><span>$rating</span><span><span> </span><span>=</span><span> </span></span><span>Helper</span><span>::</span><span>options</span><span>()-&gt;</span><span>commentsAvatarRating</span><span>;</span></div></div><div><div><div>51</div></div><div><span>    </span><span>$hash</span><span><span> </span><span>=</span><span> </span></span><span>md5</span><span>(</span><span>strtolower</span><span>(</span><span>$email</span><span>));</span></div></div><div><div><div>52</div></div><div><span>    </span><span>$avatar</span><span><span> </span><span>=</span><span> </span></span><span>$host</span><span> </span><span>.</span><span> </span><span>$url</span><span> </span><span>.</span><span> </span><span>$hash</span><span> </span><span>.</span><span> </span><span>'?s='</span><span> </span><span>.</span><span> </span><span>$size</span><span> </span><span>.</span><span> </span><span>'&amp;r='</span><span> </span><span>.</span><span> </span><span>$rating</span><span> </span><span>.</span><span> </span><span>'&amp;d='</span><span> </span><span>.</span><span> </span><span>urlencode</span><span>(</span><span>$default</span><span>);</span></div></div><div><div><div>53</div></div><div><span>    </span><span>$imgName</span><span><span> </span><span>=</span><span> </span></span><span>$hash</span><span> </span><span>.</span><span> </span><span>".jpg"</span><span>;</span></div></div><div><div><div>54</div></div><div><span>    </span><span>$localImgFile</span><span><span> </span><span>=</span><span> </span></span><span>__TYPECHO_ROOT_DIR__</span><span> </span><span>.</span><span> </span><span>$tempDir</span><span> </span><span>.</span><span> </span><span>$imgName</span><span>;</span></div></div><div><div><div>55</div></div><div>
</div></div><div><div><div>56</div></div><div><span>    </span><span>if</span><span><span>(</span><span>!</span></span><span>self</span><span>::</span><span>mkdirs</span><span>(</span><span>dirname</span><span>(</span><span>$localImgFile</span><span>))){</span></div></div><div><div><div>57</div></div><div><span>        </span><span>throw</span><span> </span><span>new</span><span> </span><span>exception</span><span>(</span><span>'GravatarCache 缓存目录创建失败，请检查指定的目录是否可写'</span><span><span> </span><span>);</span></span></div></div><div><div><div>58</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>59</div></div><div><span>    </span><span>if</span><span><span>(</span><span>!</span></span><span>file_exists</span><span>(</span><span>$localImgFile</span><span><span>) </span><span>||</span><span> (</span></span><span>time</span><span><span>() </span><span>-</span><span> </span></span><span>filemtime</span><span>(</span><span>$localImgFile</span><span><span>)) </span><span>&gt;</span><span> </span></span><span>$timeCache</span><span>){</span></div></div><div><div><div>60</div></div><div><span>        </span><span>if</span><span><span>(</span><span>!</span></span><span>self</span><span>::</span><span>download</span><span>(</span><span>$avatar</span><span>, </span><span>$host</span><span>, </span><span>$localImgFile</span><span>)) </span><span>return</span><span> </span><span>$default</span><span>;</span></div></div><div><div><div>61</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>62</div></div><div>
</div></div><div><div><div>63</div></div><div><span>  </span><span>$fileSize</span><span><span> </span><span>=</span><span> </span></span><span>filesize</span><span>(</span><span>$localImgFile</span><span>);</span></div></div><div><div><div>64</div></div><div><span>    </span><span>if</span><span>(</span><span>$fileSize</span><span><span> </span><span>&lt;</span><span> </span></span><span>1</span><span>){</span></div></div><div><div><div>65</div></div><div><span>        </span><span>if</span><span><span>(</span><span>!</span></span><span>self</span><span>::</span><span>download</span><span>(</span><span>$avatar</span><span>, </span><span>$host</span><span>, </span><span>$localImgFile</span><span>)) </span><span>return</span><span> </span><span>$default</span><span>;</span></div></div><div><div><div>66</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>67</div></div><div>
</div></div><div><div><div>68</div></div><div><span>    </span><span>return</span><span> </span><span>$tempDir</span><span> </span><span>.</span><span> </span><span>$imgName</span><span>;</span></div></div><div><div><div>69</div></div><div><span>}</span></div></div><div><div><div>70</div></div><div><span>//递归建立目录</span></div></div><div><div><div>71</div></div><div><span>public</span><span> </span><span>static</span><span> </span><span>function</span><span> </span><span>mkdirs</span><span>(</span><span>$dir</span><span>){</span></div></div><div><div><div>72</div></div><div><span>    </span><span>return</span><span> </span><span>is_dir</span><span>(</span><span>$dir</span><span><span>) </span><span>or</span><span> (</span></span><span>self</span><span>::</span><span>mkdirs</span><span>(</span><span>dirname</span><span>(</span><span>$dir</span><span><span>)) </span><span>and</span><span> </span></span><span>mkdir</span><span>(</span><span>$dir</span><span><span>,</span><span> </span></span><span>0777</span><span>));</span></div></div><div><div><div>73</div></div><div><span>}</span></div></div><div><div><div>74</div></div><div><span>//下载头像</span></div></div><div><div><div>75</div></div><div><span>public</span><span> </span><span>static</span><span> </span><span>function</span><span> </span><span>download</span><span>( </span><span>$url</span><span>, </span><span>$referer</span><span>, </span><span>$imagePath</span><span> ){</span></div></div><div><div><div>76</div></div><div><span>    </span><span>$fpLocal</span><span><span> </span><span>=</span><span> </span><span>@</span></span><span>fopen</span><span><span>(</span><span> </span></span><span>$imagePath</span><span><span>,</span><span> </span></span><span>'w'</span><span><span> </span><span>);</span></span></div></div><div><div><div>77</div></div><div><span>    </span><span>if</span><span><span>( </span><span>!</span></span><span>$fpLocal</span><span> ) {</span></div></div><div><div><div>78</div></div><div><span>        </span><span>return</span><span> </span><span>false</span><span>;</span></div></div><div><div><div>79</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>80</div></div><div><span>    </span><span>if</span><span>( </span><span>is_callable</span><span>(</span><span>'curl_init'</span><span>) ) {</span></div></div><div><div><div>81</div></div><div><span>        </span><span>$ch</span><span><span> </span><span>=</span><span> </span></span><span>curl_init</span><span>();</span></div></div><div><div><div>82</div></div><div><span>        </span><span>curl_setopt</span><span><span>(</span><span> </span></span><span>$ch</span><span><span>,</span><span> </span></span><span>CURLOPT_URL</span><span><span>,</span><span> </span></span><span>$url</span><span><span> </span><span>);</span></span></div></div><div><div><div>83</div></div><div><span>        </span><span>curl_setopt</span><span><span>(</span><span> </span></span><span>$ch</span><span><span>,</span><span> </span></span><span>CURLOPT_REFERER</span><span><span>,</span><span> </span></span><span>$referer</span><span><span> </span><span>);</span></span></div></div><div><div><div>84</div></div><div><span>        </span><span>curl_setopt</span><span><span>(</span><span> </span></span><span>$ch</span><span><span>,</span><span> </span></span><span>CURLOPT_CONNECTTIMEOUT</span><span><span>,</span><span> </span></span><span>10</span><span><span> </span><span>);</span></span></div></div><div><div><div>85</div></div><div><span>        </span><span>curl_setopt</span><span><span>(</span><span> </span></span><span>$ch</span><span><span>,</span><span> </span></span><span>CURLOPT_FOLLOWLOCATION</span><span><span>,</span><span> </span></span><span>1</span><span><span> </span><span>);</span></span></div></div><div><div><div>86</div></div><div><span>        </span><span>curl_setopt</span><span><span>(</span><span> </span></span><span>$ch</span><span><span>,</span><span> </span></span><span>CURLOPT_HEADER</span><span><span>,</span><span> </span></span><span>0</span><span><span> </span><span>);</span></span></div></div><div><div><div>87</div></div><div><span>        </span><span>curl_setopt</span><span><span>(</span><span> </span></span><span>$ch</span><span><span>,</span><span> </span></span><span>CURLOPT_FILE</span><span><span>,</span><span> </span></span><span>$fpLocal</span><span><span> </span><span>);</span></span></div></div><div><div><div>88</div></div><div><span>        </span><span>if</span><span><span>( </span><span>!</span></span><span>curl_exec</span><span>(</span><span>$ch</span><span>) ) {</span></div></div><div><div><div>89</div></div><div><span>            </span><span>fclose</span><span><span>(</span><span> </span></span><span>$fpLocal</span><span><span> </span><span>);</span></span></div></div><div><div><div>90</div></div><div><span>            </span><span>curl_close</span><span><span>(</span><span> </span></span><span>$ch</span><span><span> </span><span>);</span></span></div></div><div><div><div>91</div></div><div><span>            </span><span>return</span><span> </span><span>false</span><span>;</span></div></div><div><div><div>92</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>93</div></div><div><span>        </span><span>curl_close</span><span><span>(</span><span> </span></span><span>$ch</span><span><span> </span><span>);</span></span></div></div><div><div><div>94</div></div><div><span><span>    </span></span><span>}</span><span>else</span><span> {</span></div></div><div><div><div>95</div></div><div><span>        </span><span>$opts</span><span><span> </span><span>=</span><span> </span></span><span>array</span><span>(</span></div></div><div><div><div>96</div></div><div><span>            </span><span>'http'</span><span> =&gt; </span><span>array</span><span>(</span></div></div><div><div><div>97</div></div><div><span>                </span><span>'method'</span><span> =&gt; </span><span>"GET"</span><span>,</span></div></div><div><div><div>98</div></div><div><span>                </span><span>'header'</span><span> =&gt; </span><span>"Referer: </span><span>$referer</span><span>\r\n</span><span>"</span></div></div><div><div><div>99</div></div><div><span><span>            </span></span><span>)</span></div></div><div><div><div>100</div></div><div><span><span>        </span></span><span>);</span></div></div><div><div><div>101</div></div><div><span>            </span><span>$context</span><span><span> </span><span>=</span><span> </span></span><span>stream_context_create</span><span><span>(</span><span> </span></span><span>$opts</span><span><span> </span><span>);</span></span></div></div><div><div><div>102</div></div><div><span>        </span><span>$fpRemote</span><span><span> </span><span>=</span><span> </span><span>@</span></span><span>fopen</span><span><span>(</span><span> </span></span><span>$url</span><span><span>,</span><span> </span></span><span>'r'</span><span><span>,</span><span> </span></span><span>false</span><span><span>,</span><span> </span></span><span>$context</span><span><span> </span><span>);</span></span></div></div><div><div><div>103</div></div><div><span>        </span><span>if</span><span><span>( </span><span>!</span></span><span>$fpRemote</span><span> ) {</span></div></div><div><div><div>104</div></div><div><span>            </span><span>fclose</span><span><span>(</span><span> </span></span><span>$fpLocal</span><span><span> </span><span>);</span></span></div></div><div><div><div>105</div></div><div><span>            </span><span>return</span><span> </span><span>false</span><span>;</span></div></div><div><div><div>106</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>107</div></div><div><span>            </span><span>while</span><span><span>( </span><span>!</span></span><span>feof</span><span><span>(</span><span> </span></span><span>$fpRemote</span><span><span> </span><span>) ) {</span></span></div></div><div><div><div>108</div></div><div><span>            </span><span>fwrite</span><span><span>(</span><span> </span></span><span>$fpLocal</span><span><span>,</span><span> </span></span><span>fread</span><span>(</span><span>$fpRemote</span><span><span>,</span><span> </span></span><span>8192</span><span><span>)</span><span> </span><span>);</span></span></div></div><div><div><div>109</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>110</div></div><div><span>        </span><span>fclose</span><span><span>(</span><span> </span></span><span>$fpRemote</span><span><span> </span><span>);</span></span></div></div><div><div><div>111</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>112</div></div><div><span>        </span><span>fclose</span><span><span>(</span><span> </span></span><span>$fpLocal</span><span><span> </span><span>);</span></span></div></div><div><div><div>113</div></div><div><span>    </span><span>return</span><span> </span><span>true</span><span>;</span></div></div><div><div><div>114</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>接着，找到<code>getAvator($email)</code>函数，修改其中的3行：</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>public</span><span> </span><span>static</span><span> </span><span>function</span><span> </span><span>getAvator</span><span>(</span><span>$email</span><span>){</span></div></div><div><div><div>2</div></div><div><span>    </span><span>$options</span><span><span> </span><span>=</span><span> </span></span><span>mget</span><span>();</span></div></div><div><div><div>3</div></div><div><span>    </span><span>$cdnUrl</span><span><span> </span><span>=</span><span> </span></span><span>$options</span><span>-&gt;</span><span>CDNURL</span><span>;</span></div></div><div><div><div>4</div></div><div><span>    </span><span>if</span><span><span> (</span><span>@</span><span> </span></span><span>in_array</span><span>(</span><span>'emailToQQ'</span><span>,</span><span>$options</span><span>-&gt;</span><span>featuresetup</span><span>)){</span></div></div><div><div><div>5</div></div><div><span>        </span><span>$str</span><span><span> </span><span>=</span><span> </span></span><span>explode</span><span>(</span><span>'@'</span><span><span>,</span><span> </span></span><span>$email</span><span>);</span></div></div><div><div><div>6</div></div><div><span>        </span><span>if</span><span><span> (</span><span>@</span></span><span>$str</span><span>[</span><span>1</span><span><span>] </span><span>==</span><span> </span></span><span>'qq.com'</span><span>) {</span></div></div><div><div><div>7</div></div><div><span>            </span><span>$avatorSrc</span><span><span> </span><span>=</span><span> </span></span><span>'https://q.qlogo.cn/g?b=qq&amp;nk='</span><span>.</span><span>$str</span><span>[</span><span>0</span><span>]</span><span>.</span><span>'&amp;s=40'</span><span>;</span></div></div><div><div><div>8</div></div><div><span>            </span><span>$avatorSrc</span><span><span> </span><span>=</span><span> </span></span><span>self</span><span>::</span><span>getQlogoCache</span><span>(</span><span>$avatorSrc</span><span>,</span><span>$str</span><span>[</span><span>0</span><span>]);</span><span>//修改1：直接加这一句</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>}</span><span>else</span><span>{</span></div></div><div><div><div>10</div></div><div><span>            </span><span>$avatorSrc</span><span><span> </span><span>=</span><span> </span></span><span>Utils</span><span>::</span><span>getGravatorCache</span><span>(</span><span>$email</span><span>,</span><span>$cdnUrl</span><span>);</span><span>//修改2：改函数名</span></div></div><div><div><div>11</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>12</div></div><div><span><span>    </span></span><span>}</span><span>else</span><span>{</span></div></div><div><div><div>13</div></div><div><span>        </span><span>$avatorSrc</span><span><span> </span><span>=</span><span> </span></span><span>Utils</span><span>::</span><span>getGravatorCache</span><span>(</span><span>$email</span><span>,</span><span>$cdnUrl</span><span>);</span><span>//修改3：改函数名</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>15</div></div><div><span>    </span><span>return</span><span> </span><span>$avatorSrc</span><span>;</span></div></div><div><div><div>16</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2>后记<a href="#后记"><span>#</span></a></h2><p>这样折腾其实还不如直接用好一点的 gravatar 镜像</p></section>
<section><h2>参考<a href="#参考"><span>#</span></a></h2><p>这次魔改参考了 <a href="http://www.byends.com/" target="_blank">羽飞</a> 的 <a href="https://github.com/byends/GravatarCache" target="_blank">Gravatar 头像缓存插件 For Typecho</a>，参考了其部分代码，省了很多事还学到了点新姿势（。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/hbase/</id>
      <title type="text">[教程] 在 Linux 上部署 HBase 的详细配置过程</title>
      <published>2017-12-09T10:46:00.000Z</published>
      <updated>2017-12-09T11:36:43.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/hbase/"/>
      <summary type="text">HBase 是一个分布式的、面向列的开源数据库，详细的也不再多讲。之所以有这篇文章是因为博主在学业上需要用到这一软件，因此自己摸索并记录下部署过程。</summary>
      <content type="html"><![CDATA[<p>HBase 是一个分布式的、面向列的开源数据库，详细的也不再多讲。之所以有这篇文章是因为博主在学业上需要用到这一软件，因此自己摸索并记录下部署过程。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=51752089" target="_blank">「HAPPY BIRTHDAY ほのかちゃん」/「ぱち@c93落選しました」のイラスト [pixiv]</a></p>
<blockquote><p>在我心中，这个女团永远不会过气</p></blockquote>
<hr />
<section><h2>1. 准备 JDK<a href="#1-准备-jdk"><span>#</span></a></h2><p>由于 HBase 是基于 Java 开发的，所以其依赖于 JDK 运行。</p><p>首先打开 <a href="http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html" target="_blank">Java SE Development Kit 8</a> 的下载页面，找到对应你的 Linux 系统位数的版本，然后下载下来并解压。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr</span></div></div><div><div><div>2</div></div><div><span>mkdir</span><span> </span><span>java</span></div></div><div><div><div>3</div></div><div><span>cd</span><span> </span><span>java</span></div></div><div><div><div>4</div></div><div><span># 在 oracle 下载 jdk 前必须先同意协议，并且复制点开链接后的带 AuthParam 参数的 URL 来下载</span></div></div><div><div><div>5</div></div><div><span>wget</span><span> </span><span>http://download.oracle.com/otn-pub/java/jdk/8u152-b16/aa0333dd3019491ca4f6ddbe78cdb6d0/jdk-8u152-linux-x64.tar.gz?AuthParam=1512813306_6a463d0f5669caf4fa723bc2f6fce52a</span></div></div><div><div><div>6</div></div><div><span>tar</span><span> </span><span>-xzvf</span><span> </span><span>jdk-8u152-linux-x64.tar.gz</span></div></div><div><div><div>7</div></div><div><span># 删除原压缩包</span></div></div><div><div><div>8</div></div><div><span>rm</span><span> </span><span>-f</span><span> </span><span>jdk-8u152-linux-x64.tar.gz</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>2. 部署 HBase<a href="#2-部署-hbase"><span>#</span></a></h2><ol>
<li>进入 <a href="http://www.apache.org/dyn/closer.cgi/hbase/" target="_blank">HBase 官网</a>，选择一个比较快的源（国内建议用 HTTP 那几个，国外建议用 BACKUP SITES 那几个），然后找到你需要的 HBase 版本的压缩包并下载（我选择的是 1.2.6 稳定版）</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr</span></div></div><div><div><div>2</div></div><div><span>wget</span><span> </span><span>http://mirror.bit.edu.cn/apache/hbase/1.2.6/hbase-1.2.6-bin.tar.gz</span></div></div><div><div><div>3</div></div><div><span>tar</span><span> </span><span>-xzvf</span><span> </span><span>hbase-1.2.6-bin.tar.gz</span></div></div><div><div><div>4</div></div><div><span># 删除原压缩包</span></div></div><div><div><div>5</div></div><div><span>rm</span><span> </span><span>-f</span><span> </span><span>hbase-1.2.6-bin.tar.gz</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>配置 HBase 数据储存目录，如果不配置的话，重启HBase 后数据库中的内容都会消失
以下是配置示例</li>
<li>创建数据目录</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>/usr/hbase-1.2.6</span></div></div><div><div><div>2</div></div><div><span>mkdir</span><span> </span><span>data</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>编辑 HBase 目录中的<code>conf/hbase-site.xml </code></li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;</span><span>configuration</span><span>&gt;</span></div></div><div><div><div>2</div></div><div><span><span>      </span></span><span>&lt;</span><span>property</span><span>&gt;</span></div></div><div><div><div>3</div></div><div><span><span>        </span></span><span>&lt;</span><span>name</span><span>&gt;hbase.rootdir&lt;/</span><span>name</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>        </span></span><span>&lt;</span><span>value</span><span>&gt;file:///usr/hbase-1.2.6/data&lt;/</span><span>value</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>      </span></span><span>&lt;/</span><span>property</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span>&lt;/</span><span>configuration</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>将 HBase 的 bin 文件夹的路径添加到<code>PATH</code>环境变量，将 JDK 的路径添加到<code>JAVA_HOME</code>环境变量</li>
<li>编辑<code>/etc/profile</code>文件，在最末端添加</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>export</span><span> </span><span>PATH</span><span>=</span><span>$PATH</span><span>:/</span><span>usr</span><span>/</span><span>hbase-1</span><span>.</span><span>2</span><span>.</span><span>6</span><span>/</span><span>bin</span></div></div><div><div><div>2</div></div><div><span>export</span><span> </span><span>JAVA_HOME</span><span><span>=</span><span>/</span></span><span>usr</span><span>/</span><span>java</span><span>/</span><span>jdk1</span><span>.</span><span>8</span><span>.</span><span>0_152</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>重载系统配置</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>source</span><span> </span><span>/etc/profile</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>开启 HBase 服务</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bash</span><span> </span><span>start-hbase.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>至此所有配置已经完成，可以开始使用 HBase 了</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>hbase</span><span> </span><span>shell</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/dd-diy/</id>
      <title type="text">[教程] 自制 Linux 可用的 Windows dd包</title>
      <published>2017-12-03T04:49:00.000Z</published>
      <updated>2018-12-04T11:04:36.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/dd-diy/"/>
      <summary type="text">不折腾不舒服星人（比如我）可以自己动手丰衣足食_(:3」」</summary>
      <content type="html"><![CDATA[<p>不折腾不舒服星人（比如我）可以自己动手丰衣足食_(&lt;3&gt;」」</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=64766869" target="_blank">「夕立」/「大腿外側(太もも」のイラスト [pixiv]</a></p>
<hr />
<p>由于自己想 dd 的时候并没有 Server 2008 R2 中文版的 dd 包，而用英文包再安装中文语言之后仍会出现一些莫名其妙的 bug，因此自己做了一份，并且将过程在此文中记录下来</p>
<p>相关教程：</p>
<a href="/posts/dd-win-vicer/"><div><div>[Linux] 一键全自动 dd 安装 Windows</div><div>在 Linux 机器上一键全自动安装 Windows 系统，突破没有 VNC，没有救援模式，内存比 dd 包小的限制。使用 Debian Live CD 中的 busybox 做中间媒介，经过复杂的处理，使得即使没有 DHCP 能够让 Windows 获取网络参数，也能让 Windows 操作系统在开机的第一时间能够连通网络。</div><div><span>2017-11-27</span><span>教程</span><span><span>#windows</span><span>#linux</span><span>#dd</span><span>#系统重装</span></span></div></div><div><img src="/usr/uploads/2017/11/239625258.jpg" alt="" loading="lazy" /></div></a>
<section><h2>准备工作<a href="#准备工作"><span>#</span></a></h2><ol>
<li>Windows 原版镜像，可以在 <a href="https://msdn.itellyou.cn/" target="_blank">MSDN</a> 下载</li>
<li><a href="http://www.chuyu.me/zh-Hans/index.html" target="_blank">DISM++</a>，用于 DIY 以及优化 wim 镜像</li>
<li>虚拟化驱动</li>
</ol><ul>
<li><a href="https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" target="_blank">VirtIO</a>（KVM 驱动）</li>
<li><a href="https://xenbits.xen.org/pvdrivers/win/" target="_blank">Xen 驱动</a></li>
</ul><ol>
<li>下载 <a href="http://gnuwin32.sourceforge.net/downlinks/gzip-bin-zip.php" target="_blank">gunzip for windows</a>　<a href="https://moeclub.org/get-gzip-win" target="_blank">备用下载点</a>
或者你也可以直接去安装 Cmder（<a href="http://cmder.net/" target="_blank">官网</a>），其自带有 gzip（顺便安利一下这个可以在 Win 下执行大多数 Linux 命令的超好用的命令行程序）</li>
<li>在计算机上安装 Hyper-V（<a href="https://jingyan.baidu.com/article/15622f24017461fdfdbea554.html" target="_blank">Win8/10 开启 Hyper-V 教程</a>），准备用于对制作好的 vhd 映像进行测试</li>
</ol></section>
<section><h2>开始制作<a href="#开始制作"><span>#</span></a></h2><section><h3>1. 制作可用的镜像文件<a href="#1-制作可用的镜像文件"><span>#</span></a></h3><ol>
<li>首先需要取出准备好的 WIndows 原版镜像中的<code>\sources\install.wim</code>文件，直接解压ISO或挂载虚拟光驱都行，把这个文件复制出来，比如复制到<code>E:\install.wim</code></li>
<li>在D盘创建一个文件夹<code>D:\MOUNT</code>，打开 DISM++
点击：文件–&gt;挂载映像–&gt;点第一个浏览，找到<code>E:\install.wim</code>–&gt;点第二个浏览，找到<code>D:\MOUNT</code>–&gt;<strong>不选中</strong>只读模式–&gt;确定
<strong>点击确定之前顺便记一下映像的展开大小</strong></li>
<li>创建一个 vhd 虚拟磁盘
示例：盘符为<code>V</code>，路径为<code>D:\win.vhd</code>，大小为<code>8192M</code>（这个大小比上面你记住的映像展开大小大 1GB 左右即可，例如我在本例中制作的 2008R2 的展开大小为 6.9GB，因此我将 vhd 大小设置为 8GB）
首先<strong>以管理员身份</strong>运行<strong>命令提示符</strong>或者 <strong>PowerShell</strong>，然后执行以下命令</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>diskpart</span></div></div><div><div><div>2</div></div><div><span># 以下命令实际上可以复制粘贴一次性执行，无需分条</span></div></div><div><div><div>3</div></div><div><span>CREATE</span><span> </span><span>VDISK</span><span> </span><span>FILE="D:\win.vhd"</span><span> </span><span>TYPE=FIXED</span><span> </span><span>MAXIMUM=</span><span>8192</span></div></div><div><div><div>4</div></div><div><span>SELECT</span><span> </span><span>VDISK</span><span> </span><span>FILE="D:\win.vhd"</span></div></div><div><div><div>5</div></div><div><span>ATTACH</span><span> </span><span>VDISK</span></div></div><div><div><div>6</div></div><div><span>CLEAN</span></div></div><div><div><div>7</div></div><div><span>CREATE</span><span> </span><span>PARTITION</span><span> </span><span>PRIMARY</span></div></div><div><div><div>8</div></div><div><span>FORMAT</span><span> </span><span>FS=NTFS</span><span> </span><span>QUICK</span></div></div><div><div><div>9</div></div><div><span>ASSIGN</span><span> </span><span>LETTER=V</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>回到 DISM++，进行系统设置优化（建议关闭 UAC）、安装语言包、添加先前下载好的虚拟化驱动等</li>
<li>完成后，点文件–&gt;另存为映像–&gt;保存在<code>D:\install.wim</code>，等待任务完成</li>
<li>点击：文件–&gt;释放映像–&gt;点第一个浏览，找到<code>D:\install.wim</code>–&gt;点第二个浏览，找到<code>V:</code>–&gt;只选中<strong>添加引导</strong>和<strong>格式化</strong>–&gt;确定–&gt;在弹出的“引导修复-BIOS”对话框中点击“更多”–&gt;找到盘符为 V 的磁盘分区–&gt;确定</li>
<li>等待完成</li>
</ol></section><section><h3>2. 设置系统的注册表<a href="#2-设置系统的注册表"><span>#</span></a></h3><div><div><div></div><div>Note</div></div><div><p>新版 Dism++ 会自动帮你挂载当前映像的注册表，可以不用再按照前几步手动加载配置单元了</p></div></div><ol>
<li>在自己的电脑上打开注册表编辑器<code>regedit</code>，选中<code>HKEY_LOCAL_MACHINE</code>分支，点击：文件-&gt;加载配置单元</li>
<li>在文件浏览器中选择<code>V:\Windows\System32\config\SYSTEM</code>，项名称填一个好找又不和目前项相同的，例如<code>A_SYSTEM</code>
然后更改如下键值以开启远程桌面服务</li>
</ol><table><tbody><tr><th></th><th>RegKey <code>HKEY_LOCAL_MACHINE\A_SYSTEM\ControlSet001</code></th><th>Value</th><th>Type</th><th>Data</th></tr><tr><td>打开远程桌面服务</td><td>\Control\Terminal Server</td><td>fDenyTSConnections</td><td>REG_DWORD</td><td>0</td></tr><tr><td>设置远程桌面端口</td><td>\Control\Terminal Server\Wds\rdpwd\Tds\tcp</td><td>PortNumber</td><td>REG_DWORD</td><td>d3d</td></tr><tr><td></td><td>\Control\Terminal Server\WinStations\RDP-Tcp</td><td>PortNumber</td><td>REG_DWORD</td><td>d3d</td></tr><tr><td>设置不验证用户级别</td><td>\Control\Terminal Server\WinStations\RDP-Tcp</td><td>UserAuthentication</td><td>REG_DWORD</td><td>0</td></tr><tr><td>防火墙允许远程桌面</td><td>\services\SharedAccess\Parameters\FirewallPolicy\FirewallRules</td><td>RemoteDesktop-In-TCP</td><td>REG_SZ</td><td>把其中的Active=<code>FALSE</code>改为<code>TRUE</code></td></tr><tr><td></td><td>同上</td><td>RemoteDesktop-UserMode-In-TCP</td><td>同上</td><td>同上</td></tr></tbody></table><ol>
<li>继续按照先前步骤加载配置单元<code>V:\Windows\System32\config\SOFTWARE</code>，项为<code>A_SOFTWARE</code>
然后更改如下键值以关闭 Ctrl+Alt+Del 登陆</li>
</ol><table><tbody><tr><th>RegKey  <code>HKEY_LOCAL_MACHINE\A_SOFTWARE\Microsoft</code></th><th>Value</th><th>Type</th><th>Data</th></tr><tr><td>\Windows\CurrentVersion\Policies\System</td><td>disablecad</td><td>REG_DWORD</td><td>1</td></tr><tr><td>\Windows NT\CurrentVersion\Winlogon</td><td>DisableCAD</td><td>REG_DWORD</td><td>1</td></tr></tbody></table><ol>
<li>选中我们加载的配置单元，点击：文件-&gt;卸载配置单元，将<code>A_SYSTEM</code>和<code>A_SOFTWARE</code>卸载</li>
</ol></section><section><h3>3. 制作预应答文件<a href="#3-制作预应答文件"><span>#</span></a></h3><ol>
<li>下载 <a href="https://www.microsoft.com/zh-cn/download/details.aspx?id=5753" target="_blank">Microsoft Windows AIK</a></li>
</ol><div><div><div></div><div>Warning</div></div><div><p>创建编录文件的时候会自动挂载镜像到系统盘，请确保系统盘有大于映像展开大小的剩余空间。</p></div></div><p>貌似仅适用于制作 Windows 7 以及 Server 2008 R2 的，如果是其他系统不知能不能制作，也可以尝试直接照搬我提供的预应答文件</p><ol>
<li>安装完成后，打开“Windows 系统映像管理器”，点击：文件-&gt;选择 Windows 映像，然后选择我们已经在前面的步骤中优化好的 wim 文件，然后会提示你需要创建编录文件，选是即可</li>
<li>等待加载完成，然后仿照 <a href="/usr/uploads/2017/12/3648354536.zip">这个预应答文件</a> 进行制作（文件内容见附录）
这个预应答文件将会设置用户名<code>Administrator</code>的密码为<code>lolico.moe123</code>。
我给出的这个预应答文件可以直接用于 Win7/10 x64。
软件的具体使用方法可以百度一下有很多范例，讲起来比较复杂，理解能力强的人看一看就会用，因此此处不再赘述
如果你要制作的是 <strong>Win7 或者 Server2008R2 的 64 位</strong> 系统，也可以使用此软件打开，然后在这个文件的基础上进行修改</li>
<li>制作完成之后保存预应答文件为<code>unattend.xml</code>，然后放在<code>V:\Windows\Panther</code>目录下（如果没有目录就自行新建）</li>
<li>在我的电脑中右击V盘，弹出</li>
</ol></section><section><h3>3. 对制作好的 dd 包进行测试<a href="#3-对制作好的-dd-包进行测试"><span>#</span></a></h3><ol>
<li>先将你制作好的 vhd 复制一份，用复制的这份来测试，这样的话如果出现了错误就不用再重新制作，可以继续修改</li>
<li>打开 Hyper-V，点击：操作-&gt;新建-&gt;虚拟机</li>
<li>名称和位置随便选，指定代数选择“第一代”，内存分配你觉得足以启动系统即可，配置网络不用管；
连接虚拟硬盘选择“使用现有虚拟磁盘”，接着指定我们刚才制作的 vhd 虚拟磁盘，之后的设置都维持默认即可</li>
<li>启动虚拟机，观察是否有进行自动安装等操作，成功的话就可以关掉虚拟机并删掉使用过的 vhd 了</li>
</ol></section><section><h3>4. 将 dd 包部署在服务器上<a href="#4-将-dd-包部署在服务器上"><span>#</span></a></h3><ol>
<li>使用 gunzip 工具压缩打包压缩<code>D:\win.vhd</code></li>
</ol><ul>
<li><strong>使用 gunzip for windows</strong>
将 gunzip 程序目录中的<code>bin</code>目录里的所有文件复制到<code>%WINDIR%/SYSTEM32</code>，接着在命令提示符内进入 vhd 所在目录，执行<code>gzip.exe -k9 win.vhd</code></li>
<li><strong>使用 cmder 自带 gunzip</strong>
在 cmder 中进入 vhd 所在目录，执行<code>gzip -k9 win.vhd</code></li>
</ul><p>然后耐心等待压缩完成
这样我们就得到了一个可以用来脚本一键 dd 的包</p><ol>
<li>将这个压缩包传到可用 HTTP 直接下载的地方，最好不要包含跳转，然后就可以拿来使用 <a href="/posts/dd-win-vicer/">[Linux] 一键全自动 dd 安装 Windows</a> 脚本一键 dd 了</li>
</ol></section></section>
<section><h2>附录：预应答文件内容及说明<a href="#附录预应答文件内容及说明"><span>#</span></a></h2><p>存放目录：<code>%WINDIR%/Panther/unattemd.xml</code></p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;!-- Windows Server 2008 R2 x64 预应答文件示例 --&gt;</span></div></div><div><div><div>2</div></div><div><span>&lt;?</span><span>xml</span><span> version</span><span>=</span><span>"1.0"</span><span> encoding</span><span>=</span><span>"utf-8"</span><span>?&gt;</span></div></div><div><div><div>3</div></div><div><span>&lt;</span><span>unattend</span><span> </span><span>xmlns</span><span>=</span><span>"urn:schemas-microsoft-com:unattend"</span><span>&gt;</span></div></div><div><div><div>4</div></div><div><span><span>    </span></span><span>&lt;</span><span>settings</span><span> </span><span>pass</span><span>=</span><span>"specialize"</span><span>&gt;</span></div></div><div><div><div>5</div></div><div><span><span>        </span></span><span>&lt;</span><span>component</span><span> </span><span>name</span><span>=</span><span>"Microsoft-Windows-Deployment"</span><span> </span><span>processorArchitecture</span><span>=</span><span>"amd64"</span><span> </span><span>publicKeyToken</span><span>=</span><span>"31bf3856ad364e35"</span><span> </span><span>language</span><span>=</span><span>"neutral"</span><span> </span><span>versionScope</span><span>=</span><span>"nonSxS"</span><span> </span><span>xmlns:wcm</span><span>=</span><span>"http://schemas.microsoft.com/WMIConfig/2002/State"</span><span> </span><span>xmlns:xsi</span><span>=</span><span>"http://www.w3.org/2001/XMLSchema-instance"</span><span>&gt;</span></div></div><div><div><div>6</div></div><div><span><span>            </span></span><span>&lt;</span><span>RunSynchronous</span><span>&gt;</span></div></div><div><div><div>7</div></div><div><span>                </span><span>&lt;!-- 启用 Administrator 账户 --&gt;</span></div></div><div><div><div>8</div></div><div><span><span>                </span></span><span>&lt;</span><span>RunSynchronousCommand</span><span> </span><span>wcm:action</span><span>=</span><span>"add"</span><span>&gt;</span></div></div><div><div><div>9</div></div><div><span><span>                    </span></span><span>&lt;</span><span>Order</span><span>&gt;1&lt;/</span><span>Order</span><span>&gt;</span></div></div><div><div><div>10</div></div><div><span><span>                    </span></span><span>&lt;</span><span>Path</span><span>&gt;net user Administrator /active:Yes&lt;/</span><span>Path</span><span>&gt;</span></div></div><div><div><div>11</div></div><div><span><span>                </span></span><span>&lt;/</span><span>RunSynchronousCommand</span><span>&gt;</span></div></div><div><div><div>12</div></div><div><span><span>            </span></span><span>&lt;/</span><span>RunSynchronous</span><span>&gt;</span></div></div><div><div><div>13</div></div><div><span><span>        </span></span><span>&lt;/</span><span>component</span><span>&gt;</span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>&lt;/</span><span>settings</span><span>&gt;</span></div></div><div><div><div>15</div></div><div><span><span>    </span></span><span>&lt;</span><span>settings</span><span> </span><span>pass</span><span>=</span><span>"oobeSystem"</span><span>&gt;</span></div></div><div><div><div>16</div></div><div><span>        </span><span>&lt;!-- 设置语言 --&gt;</span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>&lt;</span><span>component</span><span> </span><span>name</span><span>=</span><span>"Microsoft-Windows-International-Core"</span><span> </span><span>processorArchitecture</span><span>=</span><span>"amd64"</span><span> </span><span>publicKeyToken</span><span>=</span><span>"31bf3856ad364e35"</span><span> </span><span>language</span><span>=</span><span>"neutral"</span><span> </span><span>versionScope</span><span>=</span><span>"nonSxS"</span><span> </span><span>xmlns:wcm</span><span>=</span><span>"http://schemas.microsoft.com/WMIConfig/2002/State"</span><span> </span><span>xmlns:xsi</span><span>=</span><span>"http://www.w3.org/2001/XMLSchema-instance"</span><span>&gt;</span></div></div><div><div><div>18</div></div><div><span><span>            </span></span><span>&lt;</span><span>InputLocale</span><span>&gt;007f:00000804&lt;/</span><span>InputLocale</span><span>&gt;</span></div></div><div><div><div>19</div></div><div><span><span>            </span></span><span>&lt;</span><span>SystemLocale</span><span>&gt;zh-CN&lt;/</span><span>SystemLocale</span><span>&gt;</span></div></div><div><div><div>20</div></div><div><span><span>            </span></span><span>&lt;</span><span>UILanguage</span><span>&gt;zh-CN&lt;/</span><span>UILanguage</span><span>&gt;</span></div></div><div><div><div>21</div></div><div><span><span>            </span></span><span>&lt;</span><span>UILanguageFallback</span><span>&gt;zh-CN&lt;/</span><span>UILanguageFallback</span><span>&gt;</span></div></div><div><div><div>22</div></div><div><span><span>            </span></span><span>&lt;</span><span>UserLocale</span><span>&gt;zh-CN&lt;/</span><span>UserLocale</span><span>&gt;</span></div></div><div><div><div>23</div></div><div><span><span>        </span></span><span>&lt;/</span><span>component</span><span>&gt;</span></div></div><div><div><div>24</div></div><div><span><span>        </span></span><span>&lt;</span><span>component</span><span> </span><span>name</span><span>=</span><span>"Microsoft-Windows-Shell-Setup"</span><span> </span><span>processorArchitecture</span><span>=</span><span>"amd64"</span><span> </span><span>publicKeyToken</span><span>=</span><span>"31bf3856ad364e35"</span><span> </span><span>language</span><span>=</span><span>"neutral"</span><span> </span><span>versionScope</span><span>=</span><span>"nonSxS"</span><span> </span><span>xmlns:wcm</span><span>=</span><span>"http://schemas.microsoft.com/WMIConfig/2002/State"</span><span> </span><span>xmlns:xsi</span><span>=</span><span>"http://www.w3.org/2001/XMLSchema-instance"</span><span>&gt;</span></div></div><div><div><div>25</div></div><div><span>            </span><span>&lt;!-- 设置自动登录 --&gt;</span></div></div><div><div><div>26</div></div><div><span><span>            </span></span><span>&lt;</span><span>AutoLogon</span><span>&gt;</span></div></div><div><div><div>27</div></div><div><span><span>                </span></span><span>&lt;</span><span>Password</span><span>&gt;</span></div></div><div><div><div>28</div></div><div><span><span>                    </span></span><span>&lt;</span><span>Value</span><span>&gt;bABvAGwAaQBjAG8ALgBtAG8AZQAxADIAMwBQAGEAcwBzAHcAbwByAGQA&lt;/</span><span>Value</span><span>&gt;</span></div></div><div><div><div>29</div></div><div><span><span>                    </span></span><span>&lt;</span><span>PlainText</span><span>&gt;false&lt;/</span><span>PlainText</span><span>&gt;</span></div></div><div><div><div>30</div></div><div><span><span>                </span></span><span>&lt;/</span><span>Password</span><span>&gt;</span></div></div><div><div><div>31</div></div><div><span><span>                </span></span><span>&lt;</span><span>Enabled</span><span>&gt;true&lt;/</span><span>Enabled</span><span>&gt;</span></div></div><div><div><div>32</div></div><div><span><span>                </span></span><span>&lt;</span><span>LogonCount</span><span>&gt;9999999&lt;/</span><span>LogonCount</span><span>&gt;</span></div></div><div><div><div>33</div></div><div><span><span>                </span></span><span>&lt;</span><span>Username</span><span>&gt;Administrator&lt;/</span><span>Username</span><span>&gt;</span></div></div><div><div><div>34</div></div><div><span><span>            </span></span><span>&lt;/</span><span>AutoLogon</span><span>&gt;</span></div></div><div><div><div>35</div></div><div><span>            </span><span>&lt;!-- 隐藏安装时的配置界面以及跳过部分配置 --&gt;</span></div></div><div><div><div>36</div></div><div><span><span>            </span></span><span>&lt;</span><span>OOBE</span><span>&gt;</span></div></div><div><div><div>37</div></div><div><span><span>                </span></span><span>&lt;</span><span>HideEULAPage</span><span>&gt;true&lt;/</span><span>HideEULAPage</span><span>&gt;</span></div></div><div><div><div>38</div></div><div><span><span>                </span></span><span>&lt;</span><span>HideWirelessSetupInOOBE</span><span>&gt;true&lt;/</span><span>HideWirelessSetupInOOBE</span><span>&gt;</span></div></div><div><div><div>39</div></div><div><span><span>                </span></span><span>&lt;</span><span>NetworkLocation</span><span>&gt;Work&lt;/</span><span>NetworkLocation</span><span>&gt;</span></div></div><div><div><div>40</div></div><div><span><span>                </span></span><span>&lt;</span><span>ProtectYourPC</span><span>&gt;3&lt;/</span><span>ProtectYourPC</span><span>&gt;</span></div></div><div><div><div>41</div></div><div><span><span>                </span></span><span>&lt;</span><span>SkipMachineOOBE</span><span>&gt;true&lt;/</span><span>SkipMachineOOBE</span><span>&gt;</span></div></div><div><div><div>42</div></div><div><span><span>                </span></span><span>&lt;</span><span>SkipUserOOBE</span><span>&gt;true&lt;/</span><span>SkipUserOOBE</span><span>&gt;</span></div></div><div><div><div>43</div></div><div><span><span>            </span></span><span>&lt;/</span><span>OOBE</span><span>&gt;</span></div></div><div><div><div>44</div></div><div><span>            </span><span>&lt;!-- 设置 Administrator 的密码 --&gt;</span></div></div><div><div><div>45</div></div><div><span><span>            </span></span><span>&lt;</span><span>UserAccounts</span><span>&gt;</span></div></div><div><div><div>46</div></div><div><span><span>                </span></span><span>&lt;</span><span>AdministratorPassword</span><span>&gt;</span></div></div><div><div><div>47</div></div><div><span>                    </span><span>&lt;!-- 密码在 xml 文件中为 Base64 加密，在程序中编辑时是明文 --&gt;</span></div></div><div><div><div>48</div></div><div><span><span>                    </span></span><span>&lt;</span><span>Value</span><span>&gt;bABvAGwAaQBjAG8ALgBtAG8AZQAxADIAMwBBAGQAbQBpAG4AaQBzAHQAcgBhAHQAbwByAFAAYQBzAHMAdwBvAHIAZAA=&lt;/</span><span>Value</span><span>&gt;</span></div></div><div><div><div>49</div></div><div><span><span>                    </span></span><span>&lt;</span><span>PlainText</span><span>&gt;false&lt;/</span><span>PlainText</span><span>&gt;</span></div></div><div><div><div>50</div></div><div><span><span>                </span></span><span>&lt;/</span><span>AdministratorPassword</span><span>&gt;</span></div></div><div><div><div>51</div></div><div><span><span>            </span></span><span>&lt;/</span><span>UserAccounts</span><span>&gt;</span></div></div><div><div><div>52</div></div><div><span>            </span><span>&lt;!-- 设置时区 --&gt;</span></div></div><div><div><div>53</div></div><div><span><span>            </span></span><span>&lt;</span><span>TimeZone</span><span>&gt;China Standard Time&lt;/</span><span>TimeZone</span><span>&gt;</span></div></div><div><div><div>54</div></div><div><span><span>        </span></span><span>&lt;/</span><span>component</span><span>&gt;</span></div></div><div><div><div>55</div></div><div><span><span>    </span></span><span>&lt;/</span><span>settings</span><span>&gt;</span></div></div><div><div><div>56</div></div><div><span><span>    </span></span><span>&lt;</span><span>settings</span><span> </span><span>pass</span><span>=</span><span>"windowsPE"</span><span>&gt;</span></div></div><div><div><div>57</div></div><div><span><span>        </span></span><span>&lt;</span><span>component</span><span> </span><span>name</span><span>=</span><span>"Microsoft-Windows-International-Core-WinPE"</span><span> </span><span>processorArchitecture</span><span>=</span><span>"amd64"</span><span> </span><span>publicKeyToken</span><span>=</span><span>"31bf3856ad364e35"</span><span> </span><span>language</span><span>=</span><span>"neutral"</span><span> </span><span>versionScope</span><span>=</span><span>"nonSxS"</span><span> </span><span>xmlns:wcm</span><span>=</span><span>"http://schemas.microsoft.com/WMIConfig/2002/State"</span><span> </span><span>xmlns:xsi</span><span>=</span><span>"http://www.w3.org/2001/XMLSchema-instance"</span><span>&gt;</span></div></div><div><div><div>58</div></div><div><span>            </span><span>&lt;!-- 设置界面语言 --&gt;</span></div></div><div><div><div>59</div></div><div><span><span>            </span></span><span>&lt;</span><span>SetupUILanguage</span><span>&gt;</span></div></div><div><div><div>60</div></div><div><span><span>                </span></span><span>&lt;</span><span>UILanguage</span><span>&gt;zh-CN&lt;/</span><span>UILanguage</span><span>&gt;</span></div></div><div><div><div>61</div></div><div><span>        </span><span>&lt;!--下面这句实际上原本并没有被注释，只是不注释的话 Markdown 解析会出问题，不知道是什么莫名其妙的BUG，后面还有一句被一模一样的被注释的语句同理--&gt;</span></div></div><div><div><div>62</div></div><div><span>                </span><span>&lt;!--&lt;WillShowUI&gt;OnError&lt;/WillShowUI&gt;--&gt;</span></div></div><div><div><div>63</div></div><div><span><span>            </span></span><span>&lt;/</span><span>SetupUILanguage</span><span>&gt;</span></div></div><div><div><div>64</div></div><div><span><span>        </span></span><span>&lt;/</span><span>component</span><span>&gt;</span></div></div><div><div><div>65</div></div><div><span><span>        </span></span><span>&lt;</span><span>component</span><span> </span><span>name</span><span>=</span><span>"Microsoft-Windows-Setup"</span><span> </span><span>processorArchitecture</span><span>=</span><span>"amd64"</span><span> </span><span>publicKeyToken</span><span>=</span><span>"31bf3856ad364e35"</span><span> </span><span>language</span><span>=</span><span>"neutral"</span><span> </span><span>versionScope</span><span>=</span><span>"nonSxS"</span><span> </span><span>xmlns:wcm</span><span>=</span><span>"http://schemas.microsoft.com/WMIConfig/2002/State"</span><span> </span><span>xmlns:xsi</span><span>=</span><span>"http://www.w3.org/2001/XMLSchema-instance"</span><span>&gt;</span></div></div><div><div><div>66</div></div><div><span>            </span><span>&lt;!-- 设置隐藏选择安装映像的界面 --&gt;</span></div></div><div><div><div>67</div></div><div><span><span>            </span></span><span>&lt;</span><span>ImageInstall</span><span>&gt;</span></div></div><div><div><div>68</div></div><div><span><span>                </span></span><span>&lt;</span><span>OSImage</span><span>&gt;</span></div></div><div><div><div>69</div></div><div><span>                </span><span>&lt;!--&lt;WillShowUI&gt;OnError&lt;/WillShowUI&gt;--&gt;</span></div></div><div><div><div>70</div></div><div><span>                    </span><span>&lt;!-- 如果是多版本系统的 wim 则还需要配置下面的这个&lt;InstallFrom&gt;设置需要安装的系统版本，如果是按照教程使用 Dim++ 制作的 wim 就无需设置，因为已经提取出单版本了--&gt;</span></div></div><div><div><div>71</div></div><div><span><span>                    </span></span><span>&lt;</span><span>InstallFrom</span><span>&gt;</span></div></div><div><div><div>72</div></div><div><span><span>                        </span></span><span>&lt;</span><span>MetaData</span><span> </span><span>wcm:action</span><span>=</span><span>"add"</span><span>&gt;</span></div></div><div><div><div>73</div></div><div><span><span>                            </span></span><span>&lt;</span><span>Key</span><span>&gt;/IMAGE/NAME&lt;/</span><span>Key</span><span>&gt;</span></div></div><div><div><div>74</div></div><div><span><span>                            </span></span><span>&lt;</span><span>Value</span><span>&gt;（系统名)&lt;/</span><span>Value</span><span>&gt;</span></div></div><div><div><div>75</div></div><div><span><span>                        </span></span><span>&lt;/</span><span>MetaData</span><span>&gt;</span></div></div><div><div><div>76</div></div><div><span><span>                    </span></span><span>&lt;/</span><span>InstallFrom</span><span>&gt;</span></div></div><div><div><div>77</div></div><div><span><span>                </span></span><span>&lt;/</span><span>OSImage</span><span>&gt;</span></div></div><div><div><div>78</div></div><div><span><span>            </span></span><span>&lt;/</span><span>ImageInstall</span><span>&gt;</span></div></div><div><div><div>79</div></div><div><span><span>            </span></span><span>&lt;</span><span>UserData</span><span>&gt;</span></div></div><div><div><div>80</div></div><div><span>                </span><span>&lt;!-- 设置安装时不激活（就算要激活也没有网络） --&gt;</span></div></div><div><div><div>81</div></div><div><span><span>                </span></span><span>&lt;</span><span>ProductKey</span><span>&gt;</span></div></div><div><div><div>82</div></div><div><span><span>                    </span></span><span>&lt;</span><span>Key</span><span>&gt;&lt;/</span><span>Key</span><span>&gt;</span></div></div><div><div><div>83</div></div><div><span><span>                </span></span><span>&lt;/</span><span>ProductKey</span><span>&gt;</span></div></div><div><div><div>84</div></div><div><span><span>                </span></span><span>&lt;</span><span>AcceptEula</span><span>&gt;true&lt;/</span><span>AcceptEula</span><span>&gt;</span></div></div><div><div><div>85</div></div><div><span><span>            </span></span><span>&lt;/</span><span>UserData</span><span>&gt;</span></div></div><div><div><div>86</div></div><div><span><span>        </span></span><span>&lt;/</span><span>component</span><span>&gt;</span></div></div><div><div><div>87</div></div><div><span><span>    </span></span><span>&lt;/</span><span>settings</span><span>&gt;</span></div></div><div><div><div>88</div></div><div><span>&lt;/</span><span>unattend</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/dd-win-vicer/</id>
      <title type="text">[Linux] 一键全自动 dd 安装 Windows</title>
      <published>2017-11-27T10:33:00.000Z</published>
      <updated>2020-01-11T13:04:46.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/dd-win-vicer/"/>
      <summary type="text">在 Linux 机器上一键全自动安装 Windows 系统，突破没有 VNC，没有救援模式，内存比 dd 包小的限制。使用 Debian Live CD 中的 busybox 做中间媒介，经过复杂的处理，使得即使没有 DHCP 能够让 Windows 获取网络参数，也能让 Windows 操作系统在开机的第一时间能够连通网络。</summary>
      <content type="html"><![CDATA[<p>在 Linux 机器上一键全自动安装 Windows 系统，突破没有 VNC，没有救援模式，内存比 dd 包小的限制。使用 Debian Live CD 中的 busybox 做中间媒介，经过复杂的处理，使得即使没有 DHCP 能够让 Windows 获取网络参数，也能让 Windows 操作系统在开机的第一时间能够连通网络。</p>
<p>Head Pic: <a href="http://seiga.nicovideo.jp/seiga/im5764175" target="_blank">アンチラちゃん / かぷりちお - ニコニコ静画 (イラスト)</a>
<a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=56629033" target="_blank">这个是P站链接，不过由于原画师设置了非公开所以无法查看</a></p>
<hr />
<p>是 Vicer 大佬的脚本，搬运过来并做一些补充说明，包括自制 dd 包的教程</p>
<section><h2>准备工作<a href="#准备工作"><span>#</span></a></h2><section><h3>准备一个 dd 包直链（无需下载，只需记住地址）<a href="#准备一个-dd-包直链无需下载只需记住地址"><span>#</span></a></h3><p>以下提供几个现成的 dd 包，当然喜欢折腾的也可以自己制作 dd 包</p><p>相关教程：</p><a href="/posts/dd-diy/"><div><div>[教程] 自制 Linux 可用的 Windows dd包</div><div>不折腾不舒服星人（比如我）可以自己动手丰衣足食_(:3」」</div><div><span>2017-12-03</span><span>教程</span><span><span>#windows</span><span>#dd</span><span>#镜像制作</span><span>#无人值守</span><span>#虚拟化</span></span></div></div><div><img src="/usr/uploads/2017/12/3003598251.jpg" alt="" loading="lazy" /></div></a><section><h4>我制作的<a href="#我制作的"><span>#</span></a></h4><div><div><div></div><div>Warning</div></div><div><p>很久以前制作的，由于经验不足没有考虑到防病毒问题，没有在防火墙中关闭一些危险端口，在扫描严重的网络环境下可能会在dd完成后被扫描种毒，如有此现象或者不放心请不要使用我制作的这些dd包</p></div></div><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows server 2008 R2 Standard VL 中文版</span></div></div><div><div><div>2</div></div><div><span># 2.9G（解压后8G） KVM 未激活 全新安装 已经过测试可用</span></div></div><div><div><div>3</div></div><div><span>https://files.lolico.moe/show/dd/win2008R2-standard-x64.gz</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># Windows 10 LTSB VL</span></div></div><div><div><div>6</div></div><div><span># 3.18G（解压后10G） KVM 未激活 全新安装 已经过测试可用</span></div></div><div><div><div>7</div></div><div><span>https://files.lolico.moe/show/dd/win10-ltsb.gz</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># Windows server 2016 Standard 中文版</span></div></div><div><div><div>10</div></div><div><span># 4.53G（解压后10G） KVM 未激活 全新安装</span></div></div><div><div><div>11</div></div><div><span># 为 Vultr Bare metal 制作，其他机器不一定可用</span></div></div><div><div><div>12</div></div><div><span>https://files.lolico.moe/show/dd/win2016-standard-vultr-bare-metal.gz</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span># 以上dd包的用户名密码均为</span></div></div><div><div><div>15</div></div><div><span>Username:</span><span> </span><span>Administrator</span></div></div><div><div><div>16</div></div><div><span>Password:</span><span> </span><span>lolico.moe123</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>萌咖 - moeclub.org<a href="#萌咖---moecluborg"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows 7 Embedded Standard x86 (Thin PC)</span></div></div><div><div><div>2</div></div><div><span># 1.19G KVM XEN 已激活</span></div></div><div><div><div>3</div></div><div><span>https://moeclub.org/get-win7embx86-auto</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span># Windows 8.1 Embedded Industry Pro x64</span></div></div><div><div><div>6</div></div><div><span># 2.87G KVM XEN Hyper-V 未激活</span></div></div><div><div><div>7</div></div><div><span>https://moeclub.org/get-win8embx64-auto</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># 以上dd包的用户名密码均为</span></div></div><div><div><div>10</div></div><div><span>Username:</span><span> </span><span>Administrator</span></div></div><div><div><div>11</div></div><div><span>Password:</span><span> </span><span>Vicer</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>Joodle - joodle.nl<a href="#joodle---joodlenl"><span>#</span></a></h4><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows server 2008 R2</span></div></div><div><div><div>2</div></div><div><span>http://down.80host.com/iso/dd/WS2008R2Enterprise-Joodle-Template.gz</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># Windows server 2012 R2</span></div></div><div><div><div>5</div></div><div><span>http://down.80host.com/iso/dd/Windows2012R2-Joodle-Template.gz</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span># Windows 7</span></div></div><div><div><div>8</div></div><div><span>http://down.80host.com/iso/dd/Windows7-Joodle-Template.gz</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># Windows 8.1</span></div></div><div><div><div>11</div></div><div><span>http://down.80host.com/iso/dd/Windows8.1-Joodle-Template.gz</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span># 以上dd包的用户名密码均为</span></div></div><div><div><div>14</div></div><div><span>Username:</span><span> </span><span>Administrator</span></div></div><div><div><div>15</div></div><div><span>Password:</span><span> </span><span>Password147</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h4>WhatUpTime - whatuptime.com<a href="#whatuptime---whatuptimecom"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows 7 Enterprise x64</span></div></div><div><div><div>2</div></div><div><span>http://mirror.whatuptime.com/besw26/7.ENT.EVAL.64.VIRTIO-SCSI.gz</span></div></div><div><div><div>3</div></div><div><span>http://down.80host.com/iso/dd/7.ENT.EVAL.64.VIRTIO-SCSI.gz</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>Username:</span><span> </span><span>WhatUpTime.com</span></div></div><div><div><div>6</div></div><div><span>Password:</span><span> </span><span>P@ssword64</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>80host - <a href="http://www.80host.com" target="_blank">www.80host.com</a><a href="#80host---www80hostcom"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows 7</span></div></div><div><div><div>2</div></div><div><span># 支持OVH VPS的scsi磁盘驱动，其他viostor的DD包在上面会蓝屏</span></div></div><div><div><div>3</div></div><div><span>http://down.80host.com/iso/dd/win7_cn_5gb_virtio_scsi.gz</span></div></div><div><div><div>4</div></div><div><span>http://down.80host.com/iso/dd/win7_cn_5gb_virtio_scsi_faster.gz</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>Username:</span><span> </span><span>administrator</span></div></div><div><div><div>7</div></div><div><span>Password:</span><span> </span><span>www.80host.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Leaseweb / Linode 专用</span></div></div><div><div><div>2</div></div><div><span>http://down.80host.com/iso/dd/cn2003-virtio-pass-Linode.gz</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>Username:</span><span> </span><span>Administrator</span></div></div><div><div><div>5</div></div><div><span>Password:</span><span> </span><span>Linode</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>yxz.me<a href="#yxzme"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows server 2003 for Kimsufi</span></div></div><div><div><div>2</div></div><div><span>http://down.80host.com/iso/dd/Kimsufi2003.gz</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>Username:</span><span> </span><span>Administrator</span></div></div><div><div><div>5</div></div><div><span>Password:</span><span> </span><span>password!yxz.me</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h4>Laiboke<a href="#laiboke"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># Windows server 2012 R2 中文版</span></div></div><div><div><div>2</div></div><div><span>http://down.80host.com/iso/dd/Win2012R2ZW.gz</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>Username:</span><span> </span><span>Administrator</span></div></div><div><div><div>5</div></div><div><span>Password:</span><span> </span><span>Laiboke.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h2>开始使用<a href="#开始使用"><span>#</span></a></h2><div><div><div></div><div>Note</div></div><div><p>原脚本目前已经与重装脚本功能合并，并且增加使用谷歌盘文件的功能，使用请阅读下面这篇文章</p></div></div><a href="/posts/linux-reinstall-vicer/"><div><div>[Linux] 网络脚本一键重装 Ubuntu/CentOS/Debian</div><div>【更新：补充重装成 CentOS 7 的方法】 适用于由 GRUB 引导的系统，使用官方发行版去掉模板预装的软件，同时也可以解决内核版本与软件不兼容的问题。 只要有 root 权限，还您一个纯净的系统。</div><div><span>2018-07-31</span><span>好东西就应该分享出来</span><span><span>#linux</span><span>#系统重装</span><span>#脚本</span><span>#磁盘扩容</span></span></div></div><div><img src="/usr/uploads/2017/11/1735547167.jpg" alt="" loading="lazy" /></div></a></section>
<section><h2>注意事项以及提示<a href="#注意事项以及提示"><span>#</span></a></h2><p>如果因使用此脚本此违反了 TOS，萌咖以及本站（lolico.moe）不负任何责任！</p><section><h3>如何激活 Windows 系统<a href="#如何激活-windows-系统"><span>#</span></a></h3><p>请点开博客左侧菜单的“嗯？”并找到“KMS 激活”</p></section><section><h3>关于磁盘空间<a href="#关于磁盘空间"><span>#</span></a></h3><p>如完成后发现磁盘空间大小不一致，可在磁盘管理中找到C盘，右键选择“扩展卷”，可以直接扩展C盘的空间到原本的大小。</p></section></section>
<section><h2>致谢<a href="#致谢"><span>#</span></a></h2><p>以上内容来源于以下文章以及本人经验
<a href="https://moeclub.org/2017/11/19/483/" target="_blank">https://moeclub.org/2017/11/19/483/</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/filerun/</id>
      <title type="text">[Filerun] 轻松搭建私有网盘以及WebDAV</title>
      <published>2017-11-22T12:08:00.000Z</published>
      <updated>2017-12-31T07:56:24.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/filerun/"/>
      <summary type="text">Filerun 是一个 php 环境下可部署的一个十分轻便的免费网盘程序，支持通过 Docker 一键部署，自带各种插件可供下载使用，一般网盘程序该有的功能一个也不少，支持中文，而且不像 ownCloud 和 NextCloud 那么重，就算是很低配的机器也能跑的很嗨。 更重要的是它同时自带 WebDAV 功能，并且提供 Windows / MacOS / Linux 平台的同步软件和 Android 客户端。</summary>
      <content type="html"><![CDATA[<p>Filerun 是一个 php 环境下可部署的一个十分轻便的免费网盘程序，支持通过 Docker 一键部署，自带各种插件可供下载使用，一般网盘程序该有的功能一个也不少，支持中文，而且不像 ownCloud 和 NextCloud 那么重，就算是很低配的机器也能跑的很嗨。</p>
<p>更重要的是它同时自带 WebDAV 功能，并且提供 Windows / MacOS / Linux 平台的同步软件和 Android 客户端。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=57713562" target="_blank">「ご注文はバルバロうさぎですか？」/「コ゛りぼて」のイラスト [pixiv]</a></p>
<hr />
<p>官网：<a href="https://www.filerun.com" target="_blank">https://www.filerun.com</a>
Demo: <a href="https://demo.filerun.co" target="_blank">https://demo.filerun.co</a></p>
<p>含有的插件：
<img src="/usr/uploads/2017/11/2087910013.png" alt="" /></p>
<section><h2>界面截图<a href="#界面截图"><span>#</span></a></h2><p>简直就是 Google Drive（。
个人很喜欢的一个功能是可以分别自定义每个网盘账户的数据根目录。</p><p></p><figure><img src="/usr/uploads/2017/11/1120129382.png" alt="主界面" /><figcaption>主界面</figcaption></figure><p></p><p></p><figure><img src="/usr/uploads/2017/11/819948245.png" alt="设置" /><figcaption>设置</figcaption></figure><p></p></section>
<section><h2>环境要求<a href="#环境要求"><span>#</span></a></h2><ul>
<li>PHP 5.5~7.0
<strong>PHP 必须安装 ionCube 扩展</strong>，用于解密 ionCube Encoder 加密脚本</li>
<li>MySQL 数据库</li>
</ul><div><div><div></div><div>Warning</div></div><div><p>官方不建议使用 PHP 5.5，建议升级至更新的版本，在 PHP 7.0 上使用体验最佳。</p></div></div><div><div><div></div><div>Caution</div></div><div><p>不支持 PHP 7.1，因为 7.1 的 ionCube 扩展版本与 Filerun 的加密版本不符，无法解密。</p></div></div><p>可选 PHP 扩展：</p><ul>
<li>mcrypt</li>
<li>openssl</li>
<li>gd</li>
<li>mbstring</li>
<li>exif</li>
<li>xml</li>
<li>zlib</li>
<li>ImageMagick 或 GraphicsMagick（用于支持额外的图片格式）</li>
<li>FFmpeg（用于显示视频缩略图）</li>
</ul></section>
<section><h2>安装步骤<a href="#安装步骤"><span>#</span></a></h2><p>这里只讲述常规安装方法，Docker 安装请直接查看官网的教程。</p><p>首先搭建好所有环境，安装上述必须/可选的 PHP 扩展。</p><p>接着访问 <a href="https://www.filerun.com/download" target="_blank">https://www.filerun.com/download</a>
根据你的 PHP 版本下载对应的源码，然后上传至站点根目录，解压，然后打开网站，即会进入安装页面。</p><p>接着 Next，来到检查环境以及配置的界面：
<img src="/usr/uploads/2017/11/4212353442.png" alt="" /></p><p>这里主要说明部分检查项</p><ul>
<li><strong>PHP configuration: open_basedir</strong>
PHP 程序在运行时，访问目录会受限于站点目录下的<code>.user.ini</code>文件，即 Filerun 可以进行读写的目录也仅限于此文件中规定的目录。</li>
<li>如果直接删除此文件，那么 Filerun 将可以浏览主机上的所有“PHP 程序具有读取权限”的文件，修改权限同理。</li>
<li>如果想要自定义<code>.user.ini</code>，由于此文件默认是被锁定的无法修改，想要解锁的话，进入网站目录，执行</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>chattr</span><span> </span><span>-i</span><span> </span><span>.user.ini</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>之后就可以自由修改了。
初始文件大概长这个样子：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>open_basedir=/www/wwwroot/xxx/:/tmp/:/proc/</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>更改等号后面的内容为你需要指定的目录即可，指定多个目录用英文冒号隔开。
更改完保存之后别忘了再将此文件加锁</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>chattr</span><span> </span><span>+i</span><span> </span><span>.user.ini</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li><strong>PHP configuration: “exec”</strong>
PHP 一般为了安全是禁止使用<code>exec</code>函数的，在 Filerun 中这一函数被用来调用其他扩展例如 ImageMagick，如果有需要的话就在 PHP 禁止函数列表中删除<code>exec</code>。
如果没有需求的话实际上这一项不需要理会，禁用<code>exec</code>函数并不会影响 Filerun 的正常使用。</li>
</ul><p>接着就到了配置数据库的环节，按照自己情况自行配置即可。</p><p>安装过程结束时会显示默认用户名及密码，记得保存。</p><p>在登录界面，左下角的语言默认是<code>EN</code>，选择<code>Chinese</code>再登录才能使用中文界面。</p></section>
<section><h2>使用 WebDAV<a href="#使用-webdav"><span>#</span></a></h2><p>Filerun 的强大所在是在如此轻便的程序中集成了 WebDAV 的功能。</p><p>WebDAV 地址：
<code>http(s)://你的网站域名/dav.php/@Home/</code>
用户名密码即为网盘用户的用户名密码</p><p>想挂载 WebDAV 可以参考教程：
<a href="/posts/mount-webdav/">[WebDAV] 如何在各个平台下挂载WebDAV</a></p><section><h3>注意点<a href="#注意点"><span>#</span></a></h3><ul>
<li>加了<code>@Home</code>才会进入用户网盘根目录，否则会进入一个有<code>@Home</code>文件夹的目录，需要进入此目录才能看见自己的文件，用起来会很不方便。</li>
<li>完整的 WebDAV 地址不能少了<code>dav.php</code>后面的斜杠！
即，你访问<code>http(s)://你的网站域名/dav.php/</code>是可以进入 WebDAV 的，而访问<code>http(s)://你的网站域名/dav.php</code>就不会了，而是会直接进入网盘。</li>
</ul></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/aria2/</id>
      <title type="text">[Aria2] 一个强大的普通文件/BT种子/磁力链下载工具 一键安装脚本</title>
      <published>2017-11-18T12:39:00.000Z</published>
      <updated>2018-02-05T03:12:49.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/aria2/"/>
      <summary type="text">Aria2 是一个轻量级的多协议和多源命令行下载工具。它支持 HTTP，HTTPS，FTP，SFTP，BitTorrent 和 Metalink（磁力链）。Aria2 可以通过内置的 JSON-RPC 和 XML-RPC 接口进行操作。</summary>
      <content type="html"><![CDATA[<p>Aria2 是一个轻量级的多协议和多源命令行下载工具。它支持 HTTP，HTTPS，FTP，SFTP，BitTorrent 和 Metalink（磁力链）。Aria2 可以通过内置的 JSON-RPC 和 XML-RPC 接口进行操作。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=18986469" target="_blank">「うさうさ」/「しゃねる」のイラスト [pixiv]</a></p>
<hr />
<p>建议配合 Web 前端一起使用，详见
<a href="/posts/ariang/">[AriaNg] 一个好看易用轻便的aria2的web前端</a></p>
<section><h2>一键安装/管理脚本<a href="#一键安装管理脚本"><span>#</span></a></h2><p>脚本来自于 <a href="https://github.com/ToyoDAdoubi/doubi/" target="_blank">https://github.com/ToyoDAdoubi/doubi/</a>
系统要求：CentOS 7+ / Debian 6+ / Ubuntu 14.04 +</p><p>直接运行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>-N</span><span> </span><span>--no-check-certificate</span><span> </span><span>https://moe.best/files/scripts/aria/aria2.sh</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>+x</span><span> </span><span>aria2.sh</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>aria2.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>运行后会出现如下界面</p><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Aria2 一键安装管理脚本 [vx.x.x]</span></div></div><div><div><div>2</div></div><div><span>-- Toyo | doub.io/shell-jc4 --</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>0. 升级脚本</span></div></div><div><div><div>5</div></div><div><span>————————————</span></div></div><div><div><div>6</div></div><div><span>1. 安装 Aria2</span></div></div><div><div><div>7</div></div><div><span>2. 卸载 Aria2</span></div></div><div><div><div>8</div></div><div><span>————————————</span></div></div><div><div><div>9</div></div><div><span>3. 启动 Aria2</span></div></div><div><div><div>10</div></div><div><span>4. 停止 Aria2</span></div></div><div><div><div>11</div></div><div><span>5. 重启 Aria2</span></div></div><div><div><div>12</div></div><div><span>————————————</span></div></div><div><div><div>13</div></div><div><span>6. 修改 配置文件</span></div></div><div><div><div>14</div></div><div><span>7. 查看 日志信息</span></div></div><div><div><div>15</div></div><div><span>————————————</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>当前状态: 未安装 并 未启动</span></div></div><div><div><div>18</div></div><div>
</div></div><div><div><div>19</div></div><div><span>请输入数字 [0-7]:</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>输入数字<code>1</code>然后回车即可开始一键安装</p><p>默认密匙为<code>doub.io</code>，如需更改可以找到 aria 的程序目录中的配置文件修改，然后重启 aria 生效。
aria 程序目录位于<code>/root</code>中。</p></section>
<section><h2>Aria2 的优点<a href="#aria2-的优点"><span>#</span></a></h2><ul>
<li><strong>支持多种协议的下载</strong>
Aria2可以从多个来源/协议下载文件，并尝试利用您的最大下载带宽，让你拥有真实高速下载的体验。</li>
<li><strong>轻量</strong>
Aria2 不需要太多的内存和 CPU。磁盘缓存关闭时，物理内存使用量通常为 4MiB（正常HTTP / FTP 下载）到 9MiB（BitTorrent 下载）。BitTorrent 下载速度 2.8MiB / sec 的 CPU 使用率约为 6％。</li>
<li><strong>全功能的 BitTorrent 客户端</strong>
您需要在 BitTorrent 客户端的所有功能：DHT，PEX，加密，磁力链，网络播种，选择性下载，本地对等发现和 UDP 跟踪。</li>
<li><strong>磁力链</strong>
Aria2 支持 Metalink（磁力链）下载描述格式（又名Metalink v4），Metalink v3和 Metalink / HTTP。Metalink 提供文件验证，HTTP / FTP / SFTP / BitTorrent 集成以及语言，位置，操作系统等的各种配置。</li>
<li><strong>远程控制</strong>
Aria2 支持 RPC 接口来控制 Aria2 进程。支持的接口是 JSON-RPC（通过 HTTP 和 WebSocket）和 XML-RPC。</li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/deluge/</id>
      <title type="text">[Deluge] 一个轻便强大的BT种子/磁力链下载客户端 一键安装脚本</title>
      <published>2017-11-18T10:21:00.000Z</published>
      <updated>2017-11-18T11:53:12.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/deluge/"/>
      <summary type="text">Deluge 是一个通过 PyGTK 建立图形界面的 BitTorrent 客户端，后端使用 libtorrent。Deluge 可以在多个平台上使用，如 Linux、OS X、Unix 和 Windows，体积小巧且节约系统资源，通过丰富的插件来实现核心以外的众多功能，而且支持 ipv6。</summary>
      <content type="html"><![CDATA[<p>Deluge 是一个通过 PyGTK 建立图形界面的 BitTorrent 客户端，后端使用 libtorrent。Deluge 可以在多个平台上使用，如 Linux、OS X、Unix 和 Windows，体积小巧且节约系统资源，通过丰富的插件来实现核心以外的众多功能，而且支持 ipv6。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=62197697" target="_blank">「文香さんと本と。」/「深井涼介」のイラスト [pixiv]</a></p>
<hr />
<section><h2>界面截图<a href="#界面截图"><span>#</span></a></h2><p><img src="/usr/uploads/2017/11/1078679563.png" alt="" /></p><p><img src="/usr/uploads/2017/11/2355473092.png" alt="" /></p></section>
<section><h2>个人使用体验<a href="#个人使用体验"><span>#</span></a></h2><p>虽然界面简陋了一丢丢，不过使用起来十分爽快，下载相关的自定义参数可以在下方的状态栏中快捷设置，用起来跟迅雷相差无几。</p><p>Deluge 很赞的一点就是<strong>支持选择下载种子中指定的文件</strong>，而且支持针对文件夹批量选择（如上图），并且可以设置下载完成后移动文件到指定目录。</p><p>不过只有手动上传种子才能直接选，如果直接下载磁力链的话，需要勾选“Add In Paused State”，即创建任务之后暂停，不会自动开始下载，然后再在下方任务详情的“Files”中取消掉不想下载的文件。</p></section>
<section><h2>安装及使用<a href="#安装及使用"><span>#</span></a></h2><p><i></i> <a href="https://github.com/sayem314/My-Deluge-Installer" target="_blank">View on Github</a></p><p>下载一键脚本并安装</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>-q</span><span> </span><span>--no-check-certificate</span><span> </span><span>raw.githubusercontent.com/sayem314/My-Deluge-Installer/master/install-deluge.sh</span><span> </span><span>-O</span><span> </span><span>install-deluge.sh</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>+x</span><span> </span><span>install-deluge.sh</span><span> &amp;&amp; </span><span>./install-deluge.sh</span><span> </span><span>-install</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装完成后请记得在防火墙中开放<code>8112</code>端口</p><p>WebUI 地址：<code>http://服务器IP:8112</code>
默认密码：<code>deluge</code></p><p>首次登录会有让你修改密码的提示，如果想修改 WebUI 端口的话，也可以在设置中更改。</p><p>首次使用时需要在“Connection Manager”中选择后端并连接。同理，你也可以在这里连接你已经在别的服务器上部署的后端。</p></section>
<section><h2>卸载<a href="#卸载"><span>#</span></a></h2><p>进入你安装时候下载脚本的目录，运行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>./install-deluge.sh</span><span> </span><span>-uninstall</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>具体功能<a href="#具体功能"><span>#</span></a></h2><ul>
<li>主要功能</li>
<li>种子建立</li>
<li>支持各种插件</li>
<li>UPnP 和 NAT-PMP 网络支持数据加密</li>
<li>网络功能</li>
<li>DHT 支持</li>
<li>uTorrent 种子交换</li>
<li>BitTorrent 协议加密</li>
<li>UPnP 和 NAT-PMP</li>
<li>使用代理下载</li>
<li>私人种子</li>
<li>各种只有你想不到没有它做不到的限速</li>
<li>RSS</li>
<li>其他功能</li>
<li>同时下载多个文件</li>
<li>预分配文件空间</li>
<li>下载完成后移动文件到指定目录</li>
<li>全局/单个文件速度、连接数限制</li>
<li>下载个别文件</li>
<li>文件预览</li>
<li>选择下载目录</li>
<li>使用队列来管理</li>
<li>可以在达到指定的分享比例后停止做种</li>
<li>可指定密码保护</li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/ariang/</id>
      <title type="text">[AriaNg] 一个好看易用轻便的aria2的web前端</title>
      <published>2017-11-17T03:50:00.000Z</published>
      <updated>2019-05-08T16:45:00.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/ariang/"/>
      <summary type="text">AriaNg 是一个让 aria2 更容易使用的现代 Web 前端。AriaNg 使用纯 html &amp; javascript 开发, 所以其不需要任何编译器或运行环境。您只要将 AriaNg 放在您的 Web 服务器里并在浏览器中打开即可使用。AriaNg 使用响应式布局, 支持各种计算机或移动设备。</summary>
      <content type="html"><![CDATA[<p>AriaNg 是一个让 aria2 更容易使用的现代 Web 前端。AriaNg 使用纯 html &amp; javascript 开发, 所以其不需要任何编译器或运行环境。您只要将 AriaNg 放在您的 Web 服务器里并在浏览器中打开即可使用。AriaNg 使用响应式布局, 支持各种计算机或移动设备。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=55155713" target="_blank">「卧槽！~」/「Magicians」のイラスト [pixiv]</a></p>
<section><h1>AriaNg<a href="#ariang"><span>#</span></a></h1><p>需要配合 Aria2 一起使用，详见
<a href="/posts/aria2/"> [Aria2] 一个强大的普通文件/BT种子/磁力链下载工具 一键安装脚本</a></p><section><h2>Demo<a href="#demo"><span>#</span></a></h2><p>Demo: <a href="http://ariang.mayswind.net/latest" target="_blank">http://ariang.mayswind.net/latest</a></p></section><section><h2>截图<a href="#截图"><span>#</span></a></h2><section><h3>计算机<a href="#计算机"><span>#</span></a></h3><p><img src="https://raw.githubusercontent.com/mayswind/AriaNg-WebSite/master/screenshots/desktop.png" alt="" /></p></section><section><h3>移动设备<a href="#移动设备"><span>#</span></a></h3><p><img src="https://raw.githubusercontent.com/mayswind/AriaNg-WebSite/master/screenshots/mobile.png" alt="" /></p></section></section><section><h2>特性<a href="#特性"><span>#</span></a></h2><ol>
<li>纯 Html &amp; Javascript 实现，不依赖其他运行环境</li>
<li>响应式布局设计，兼容计算机与移动设备</li>
<li>友好的界面交互</li>
</ol><ul>
<li>任务排序 (按文件名，文件大小，进度，剩余时间，下载速度等)，文件排序，连接节点排序</li>
<li>任务搜索</li>
<li>拖拽调整下载顺序</li>
<li>更详细的任务信息 (健康度，连接节点客户端信息等)</li>
<li>根据文件类型过滤任务中的文件 (按视频, 音频, 图片, 文档, 应用程序, 存档文件等)</li>
<li>全局以及单任务的上传/下载图表</li>
<li>完整支持 aria2 设置选项</li>
</ul><ol>
<li>支持网页地址命令行 API</li>
<li>下载完成消息通知</li>
<li>多语言支持</li>
<li>支持配置多个 aria2 RPC</li>
<li>节省带宽，仅请求增量数据</li>
</ol></section><section><h2>下载安装<a href="#下载安装"><span>#</span></a></h2><p>最新发布版本（正式版）:
<a href="https://github.com/mayswind/AriaNg/releases" target="_blank">https://github.com/mayswind/AriaNg/releases</a></p><p>最新每日构建版本（测试版）:
<a href="https://github.com/mayswind/AriaNg-DailyBuild/archive/master.zip" target="_blank">https://github.com/mayswind/AriaNg-DailyBuild/archive/master.zip</a></p><p>下载后解压至站点目录即可直接使用</p><p>在“AriaNg 设置”中连接你的 Aria2 后端即可</p><div><div><div></div><div>Warning</div></div><div><p>如果你的 Aria2 没有配置 SSL，那么就不能用 HTTPS 和 WSS 进行连接，这样的话 AriaNg 站点就必须使用 HTTP 进行访问，不能上 HTTPS，因为 HTTPS 不允许使用 HTTP 或者 WS 这种未经加密的传输协议。</p></div></div></section><section><h2>API<a href="#api"><span>#</span></a></h2><p>AriaNg 针对第三方应用提供命令行 API 以方便地调用 AriaNg 的功能。
您可以请求<code>http(s)://AriaNg/#!/command_api/parameters_1/.../parameters_n</code>调用命令行 API。</p><p>具体 API 命令请看
<a href="http://ariang.mayswind.net/zh_Hans/command-api.html" target="_blank">http://ariang.mayswind.net/zh_Hans/command-api.html</a></p></section></section>
<section><h1>AriaNg Native<a href="#ariang-native"><span>#</span></a></h1><p>由于 AriaNg 通过异步加载语言文件，所以可能无法直接在本地文件系统打开 index.html 来运行 AriaNg。</p><p>如果需要在计算机本地运行，可以下载不需要浏览器就可以运行的 AriaNg Native。</p><p><a href="https://github.com/mayswind/AriaNg-Native" target="_blank">https://github.com/mayswind/AriaNg-Native</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/netdata/</id>
      <title type="text">[NetData] 一个超酷炫的Linux性能实时监控探针</title>
      <published>2017-11-16T16:08:00.000Z</published>
      <updated>2017-11-16T16:14:09.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/netdata/"/>
      <summary type="text">NetData 是一个分布式的实时健康监测系统，它实时提供超高水平的监测功能，每秒收集数千个系统指标（也包括应用程序，如 Web 服务器和数据库服务器），并有着一个现代感十足的交互式 Web 仪表盘。 NetData 可以快速、高效的永久运行在所有 Linux 系统（真实或虚拟服务器、容器、物联网设备等），而不破坏其核心功能。</summary>
      <content type="html"><![CDATA[<p>NetData 是一个分布式的实时健康监测系统，它实时提供超高水平的监测功能，每秒收集数千个系统指标（也包括应用程序，如 Web 服务器和数据库服务器），并有着一个现代感十足的交互式 Web 仪表盘。</p>
<p>NetData 可以快速、高效的永久运行在所有 Linux 系统（真实或虚拟服务器、容器、物联网设备等），而不破坏其核心功能。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=58647586" target="_blank">「箱庭王国の創造主サマ」/「七桃りお」のイラスト [pixiv]</a></p>
<hr />
<p>官网：<a href="https://my-netdata.io/" target="_blank">https://my-netdata.io/</a>
Github：<a href="https://github.com/firehol/netdata" target="_blank">https://github.com/firehol/netdata</a>
Demo：<a href="https://my-netdata.io/#demosites" target="_blank">https://my-netdata.io/#demosites</a> （有8个地址，都是 Demo）</p>
<p><img src="/usr/uploads/2017/11/3501612481.gif" alt="" /></p>
<section><h2>安装<a href="#安装"><span>#</span></a></h2><div><div><div></div><div>Warning</div></div><div><p>所有的命令都不需要加<code>sudo</code>，脚本在需要的时候会自己 sudo。</p></div></div><section><h3>普通安装<a href="#普通安装"><span>#</span></a></h3><ul>
<li>一般情况下，直接在 root 权限下运行以下命令即可</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bash</span><span> </span><span>&lt;(</span><span>curl</span><span> </span><span>-Ss</span><span> https://my-netdata.io/kickstart.sh)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>其他情况<a href="#其他情况"><span>#</span></a></h3><section><h4>如果你想使用 NetData 的插件以及API<a href="#如果你想使用-netdata-的插件以及api"><span>#</span></a></h4><p>你也可以用下面的这个命令，它不仅会安装 NetData，还会帮你把 NetData 中自带插件的所需依赖包也一并安装。</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bash</span><span> </span><span>&lt;(</span><span>curl</span><span> </span><span>-Ss</span><span> https://my-netdata.io/kickstart.sh)</span><span> </span><span>all</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div></div><div>Warning</div></div><div><p>在使用这条命令前，请使用<code>apt-get uptate</code>或者<code>yum upgrade</code>命令更新软件包列表！</p></div></div></section><section><h4>如果你要在64位的缺少软件包管理器的 Linux 上安装<a href="#如果你要在64位的缺少软件包管理器的-linux-上安装"><span>#</span></a></h4><p>（例如CoreOS, CirrOS, busybox systems）则可以运行这个命令，netdata将以二进制编译形式进行安装</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>bash</span><span> </span><span>&lt;(</span><span>curl</span><span> </span><span>-Ss</span><span> https://my-netdata.io/kickstart-static64.sh)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果这个命令不能正常运行，那么试着分步运行以下命令</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>-O</span><span> </span><span>/tmp/kickstart-static64.sh</span><span> </span><span>https://my-netdata.io/kickstart-static64.sh</span></div></div><div><div><div>2</div></div><div><span>sh</span><span> </span><span>/tmp/kickstart-static64.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h2>配置<a href="#配置"><span>#</span></a></h2><p>安装完之后，访问<code>http://服务器IP:19999</code>即可访问。</p><p>在访问之前别忘记<strong>在防火墙中开启此端口</strong>噢！</p><section><h3>开启 KSM 以节省储存占用<a href="#开启-ksm-以节省储存占用"><span>#</span></a></h3><p>安装完以后往上翻一翻脚本的输出信息，如果有这么一段</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>Memory de-duplication instructions</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>You have kernel memory de-duper (called Kernel Same-page Merging,</span></div></div><div><div><div>4</div></div><div><span>or KSM) available, but it is not currently enabled.</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>To enable it run:</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>echo 1 &gt;/sys/kernel/mm/ksm/run</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>echo 1000 &gt;/sys/kernel/mm/ksm/sleep_millisecs</span></div></div><div><div><div>10</div></div><div>
</div></div><div><div><div>11</div></div><div><span>If you enable it, you will save 40-60% of netdata memory.</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>那么就说明你的系统有 KSM，但是未启用，按照这里说的执行这两句命令</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span> </span><span>1</span><span> &gt;</span><span>/sys/kernel/mm/ksm/run</span></div></div><div><div><div>2</div></div><div><span>echo</span><span> </span><span>1000</span><span> &gt;</span><span>/sys/kernel/mm/ksm/sleep_millisecs</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>即可开启 KSM，可以节省 40-60% 的储存空间。</p></section><section><h3>更改端口<a href="#更改端口"><span>#</span></a></h3><p>如果想换一个端口，那么编辑配置文件<code>/etc/netdata/netdata.conf</code>，找到第<code>51</code>行的</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># default port = 19999</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>去掉此行前面的<code>#</code>，然后更改成你想要的端口，接着执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>killall</span><span> </span><span>netdata</span></div></div><div><div><div>2</div></div><div><span>service</span><span> </span><span>netdata</span><span> </span><span>start</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果你的系统使用的是<code>systemctl</code>，那么第二句换成这句</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>systemctl</span><span> </span><span>netdata</span><span> </span><span>start</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>NetData 即会重启，使新配置生效。</p><p>改完之后也要记得也去防火墙中开启你更改后的端口！</p></section></section>
<section><h2>NetData 的安装目录<a href="#netdata-的安装目录"><span>#</span></a></h2><ul>
<li>守护进程　<code>/usr/sbin/netdata</code></li>
<li>配置文件　<code>/etc/netdata</code></li>
<li>网页文件　<code>/usr/share/netdata</code></li>
<li>插件　　　<code>/usr/libexec/netdata</code></li>
<li>数据文件　<code>/var/lib/netdata</code></li>
<li>日志　　　<code>/var/log/netdata</code></li>
<li>进程文件　<code>/var/run/netdata.pid</code></li>
<li>日志管理　<code>/etc/logrotate.d/netdata</code></li>
</ul></section>
<section><h2>NetData 命令<a href="#netdata-命令"><span>#</span></a></h2><p>查看帮助　<code>netdata -h</code></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/nazwa/</id>
      <title type="text">[nazwa] 限时大促销！30RMB一年的高内存10Gbps无限流量主机！对没听错是RMB！免费3个pl域名！</title>
      <published>2017-11-15T03:02:00.000Z</published>
      <updated>2017-11-24T17:35:50.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/nazwa/"/>
      <summary type="text">nazwa 是一家运营已久的波兰的大主机商，不用担心有翻车风险。最近有促销活动，单核 | 4G内存 | 25G硬盘 | 无限流量 仅需30RMB（含税）一年！而且免费注册3个pl域名和2个eu域名！</summary>
      <content type="html"><![CDATA[<p>nazwa 是一家运营已久的波兰的大主机商，不用担心有翻车风险。最近有促销活动，单核 | 4G内存 | 25G硬盘 | 无限流量 仅需30RMB（含税）一年！而且免费注册3个pl域名和2个eu域名！</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=56823558" target="_blank">「むにゃむにゃ……☆」/「亜沙都」のイラスト [pixiv]</a></p>
<hr />
<div><div><div></div><div>Caution</div></div><div><p>已经没了，现在新用户注册只限波兰居民，要认证身份……</p></div></div>
<p>官网：<a href="https://www.nazwa.pl/" target="_blank">https://www.nazwa.pl/</a>
网站均为波兰文，请自行使用网页翻译来食用。</p>
<div><div><div></div><div>Note</div></div><div><p>nazwa 支持的付款方式只有信用卡，但是可以使用虚拟信用卡，例如全球付的虚拟 master 卡。</p></div></div>
<p><strong>NVMe Start</strong>
1 vCPUs（E5 at 2,2 GHz）
4 GB RAM
25 GB NVMe disk
10 Gbps Connection speed
KVM
14,61zł/year.（约 4.02美元）</p>
<p>测试 IP: 85.128.128.10</p>
<section><h2>如何拿到优惠主机<a href="#如何拿到优惠主机"><span>#</span></a></h2><p>首先进入官网，找到右下角 VPS服务器 的购买按钮，点击之后选“私人”。
<img src="/usr/uploads/2017/11/2642066350.png" alt="" /></p><p>然后会进入到选择VPS配置的界面，时长不需要改，因为只有1年才会有如此优惠。选择你需要的系统，<strong>然后下面的管理面板不要选，是要额外加钱的</strong>。（只有 Debian 和 CentOS 可以加管理面板）然后点击“到收银机”。
<img src="/usr/uploads/2017/11/3873712335.png" alt="" /></p><p>如果你先前没有帐号的话，就需要在接下来的页面注册。</p><p><strong>温馨提示：</strong></p><ul>
<li>后期会<strong>额外</strong>送你免费一年的<code>姓名.pl</code>域名，例如姓<code>abc</code>名<code>def</code>就会送你<code>abcdef.pl</code>（如果这个域名没被人注册过的话），所以你懂的，姓名起一个你想要的。</li>
<li>国家最好选个欧洲国家，因为只有欧洲人才能免费拿两个 eu 域名，我一开始不知道所以没选欧洲的国家，后来改了也不能拿，不知道一开始注册的时候就选欧洲国家行不行。</li>
</ul><p>注册完之后需要填写购买者信息，具体填写项目请自行翻译或者参照下图。
<img src="/usr/uploads/2017/11/2404311044.png" alt="" /></p><p>然后会让你输入信用卡信息付款，此处就不再展示界面图片了，看不懂波兰文就用网页翻译就行。</p><p>付款成功后邮箱会收到一堆邮件，包含发票等，然后发邮件给客服（<a href="#">kontakt@nazwa.pl</a>）要求开通 VPS。
<img src="/usr/uploads/2017/11/1011826408.png" alt="" /></p><p>然后大概半个小时到一个小时就会收到包含管理面板登陆地址、用户名密码、VPS 的 IP 地址和初始 root 密码的邮件，然后就可以开始随意玩耍了。
<img src="/usr/uploads/2017/11/1727654351.png" alt="" /></p><div><div><div></div><div>Tip</div></div><div><p>实例管理面板是支持中文的，所以不用再担心全是波兰文看不懂还要网页翻译了。</p></div></div><div><div><div></div><div>Warning</div></div><div><p>虽然主机是无限流量，但是日流量如果超过 100GB 就会限制为 10M 带宽，防止滥用。</p></div></div></section>
<section><h2>免费一年的三个 pl 和两个 eu 域名<a href="#免费一年的三个-pl-和两个-eu-域名"><span>#</span></a></h2><p><img src="/usr/uploads/2017/11/2188210705.png" alt="" /></p><p>进入 <a href="https://www.nazwa.pl/domeny/" target="_blank">https://www.nazwa.pl/domeny/</a>
就和在和其他地方买域名一样，直接查询，然后添加到购物车，再购买即可，会看到结算金额是<code>0</code>。
注意：</p><ul>
<li>都是只能免费一年，续费按原价，或者可能到时候会有其他的优惠活动。</li>
<li>最多只能拿两个免费的<code>.pl</code>域名（<code>.com.pl</code>也算）；第三个免费的是后期会送的<code>你的姓名.pl</code>，会通过邮件发送购买链接给你，只有通过那个链接才是免费的。</li>
<li>两个免费的<code>.eu</code>域名要求必须是欧洲人，所以注册的时候最好选个欧洲国家（在上面我有提到过），事后更改貌似不行，或者也有可能是要求信用卡必须是欧洲的(?)，具体我也不是很清楚，各位可以尝试下然后告诉我结果。</li>
</ul><section><h3>修改域名 DNS<a href="#修改域名-dns"><span>#</span></a></h3><p>拿到域名的第一件事当然就是把域名托管到自己在用的 DNS，我觉得也没人会愿意天天看着波兰文来管理 DNS 记录吧……
<img src="/usr/uploads/2017/11/2959373819.gif" alt="" /></p><p>具体步骤：</p><ol>
<li>登录后台 <a href="https://panel.nazwa.pl" target="_blank">https://panel.nazwa.pl</a>
然后进入域名管理，找到你需要更改 DNS 的域名，然后点击“配置”。
<img src="/usr/uploads/2017/11/425628057.png" alt="" /></li>
<li>找到“外部DNS服务器”，输入 DNS 然后点击下面最右边的那个按钮；然后会出现一个确认网页，点击那个唯一的橙色按钮，这样就完成了，然后你会收到一封提示你已经更改了域名 DNS 的邮件。
<img src="/usr/uploads/2017/11/3042991083.png" alt="" /></li>
<li>坐等 NS 记录生效_(&lt;3&gt;」」</li>
</ol></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/linux-bbr-powered-vicer/</id>
      <title type="text">[谷歌BBR] TCP BBR 魔改版（加强版） for Debian/Ubuntu</title>
      <published>2017-11-11T12:51:00.000Z</published>
      <updated>2018-11-30T12:13:31.000Z</updated>
      <author><name>Vicer</name></author>
      <link rel="alternate" href="https://moe.best/posts/linux-bbr-powered-vicer/"/>
      <summary type="text">让机子的网速biubiu起来哦！比原版 BBR 还要强！</summary>
      <content type="html"><![CDATA[<p>让机子的网速biubiu起来哦！比原版 BBR 还要强！</p>
<p>Vicer 大佬的脚本</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=40761380" target="_blank">「島風です！」/「茨乃」のイラスト [pixiv]</a></p>
<hr />
<p>BBR 是来自 Google 的一个 TCP 拥塞控制算法，单边加速，可以提升你的网络利用率。</p>
<section><h2>安装<a href="#安装"><span>#</span></a></h2><section><h3>确认你可以使用 BBR<a href="#确认你可以使用-bbr"><span>#</span></a></h3><p>直接运行以下命令即可：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>-qO</span><span> </span><span>'BBR.sh'</span><span> </span><span>'https://moeclub.org/attachment/LinuxShell/BBR.sh'</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>a+x</span><span> </span><span>BBR.sh</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>BBR.sh</span><span> </span><span>-f</span></div></div><div><div><div>2</div></div><div><span># 本站备份：</span></div></div><div><div><div>3</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>-qO</span><span> </span><span>'BBR.sh'</span><span> </span><span>'https://moe.best/files/scripts/vicer/BBR.sh'</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>a+x</span><span> </span><span>BBR.sh</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>BBR.sh</span><span> </span><span>-f</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>脚本会自动安装并重启</p><div><div><div></div><div>Note</div></div><div><p>此脚本运行时会自动选择最新的<b>非rc版本</b>（非候选发布版）内核进行安装，并且自动卸载旧内核（无需人工干预）。</p></div></div><p>安装完成后，执行以下命令：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>lsmod</span><span> | </span><span>grep</span><span> </span><span>'bbr'</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>如果结果不为空，则说明成功开启了 BBR，那么你就可以使用后续的 BBR 加强版。</strong></p></section><section><h3>安装 BBR 魔改版<a href="#安装-bbr-魔改版"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>-qO</span><span> </span><span>'BBR_POWERED.sh'</span><span> </span><span>'https://moeclub.org/attachment/LinuxShell/BBR_POWERED.sh'</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>a+x</span><span> </span><span>BBR_POWERED.sh</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>BBR_POWERED.sh</span></div></div><div><div><div>2</div></div><div><span># 本站备份：</span></div></div><div><div><div>3</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>-qO</span><span> </span><span>'BBR_POWERED.sh'</span><span> </span><span>'https://moe.best/files/scripts/vicer/BBR_POWERED.sh'</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>a+x</span><span> </span><span>BBR_POWERED.sh</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>BBR_POWERED.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行过程中会重新编译模块，等待完成即可。</p><p>安装完成后执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>lsmod</span><span> | </span><span>grep</span><span> </span><span>'bbr_powered'</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果结果不为空，则说明成功开启了 BBR 加强版。</p></section></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li>如遇报错：<code>Error! Header not be matched by Linux Kernel.</code>
请使用<code>-f</code>参数来用强制模式重新安装原版 BBR，然后再尝试安装加强版 BBR。</li>
<li>如遇报错：<code>Error! Install make.</code>或<code>Error! Install gcc.</code></li>
<li>首先尝试<code>apt-get update</code>，再执行此脚本。</li>
<li>如果还是没解决，则请尝试安装 gcc(&gt;=4.9)
以下是 Ubuntu 安装 gcc 4.9 的示例</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>apt-get</span><span> </span><span>install</span><span> </span><span>-y</span><span> </span><span>software-properties-common</span></div></div><div><div><div>2</div></div><div><span>sudo</span><span> </span><span>add-apt-repository</span><span> </span><span>ppa:ubuntu-toolchain-r/test</span></div></div><div><div><div>3</div></div><div><span>sudo</span><span> </span><span>apt-get</span><span> </span><span>update</span></div></div><div><div><div>4</div></div><div><span>sudo</span><span> </span><span>apt-get</span><span> </span><span>-y</span><span> </span><span>install</span><span> </span><span>g++-4.9</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>此脚本在 Debian8,Debian9,Ubuntu16.04 上通过测试。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/h5ai/</id>
      <title type="text">[h5ai] 轻便但强大的 PHP 文件目录列表程序</title>
      <published>2017-11-09T04:17:00.000Z</published>
      <updated>2019-11-10T12:24:30.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/h5ai/"/>
      <summary type="text">h5ai 是一款功能强大的 PHP 文件目录列表程序，它提供多种文件目录列表呈现方式，支持 Apache、lighttpd、nginx、Cherokee 服务器，支持多国语言（有中文）。 你可以在线预览文本，图片，音频，视频等文件格式，以及打包下载，显示文件二维码等。</summary>
      <content type="html"><![CDATA[<p>h5ai 是一款功能强大的 PHP 文件目录列表程序，它提供多种文件目录列表呈现方式，支持 Apache、lighttpd、nginx、Cherokee 服务器，支持多国语言（有中文）。
你可以在线预览文本，图片，音频，视频等文件格式，以及打包下载，显示文件二维码等。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=54624460" target="_blank">「第一回シストチャレンジ！」/「凍咲しいな」のイラスト [pixiv]</a></p>
<hr />
<p>官网：<a href="https://larsjung.de/h5ai/" target="_blank">https://larsjung.de/h5ai/</a>
演示：<a href="https://larsjung.de/h5ai/demo/" target="_blank">https://larsjung.de/h5ai/demo/</a></p>
<p>本站演示：<a href="https://files.lolico.moe/" target="_blank">https://files.lolico.moe/</a></p>
<section><h2>环境要求<a href="#环境要求"><span>#</span></a></h2><ul>
<li>Apache / lighttpd / nginx / Cherokee 服务器</li>
<li>PHP 5.5+</li>
</ul></section>
<section><h2>下载<a href="#下载"><span>#</span></a></h2><p>进入官网直接点击右侧的“DOWNLOAD”即可。
你也可以直接访问 <a href="https://release.larsjung.de/h5ai/" target="_blank">https://release.larsjung.de/h5ai/</a> 来查看所有可供下载的版本（这一下载站点也运用了 h5ai）。</p></section>
<section><h2>部署<a href="#部署"><span>#</span></a></h2><ol>
<li>将下载好的压缩包上传到服务器，解压，将其中的<code>_h5ai</code>文件夹放到网站根目录。</li>
</ol><div><div><div></div><div>Tip</div></div><div><p>当然，如果你只想让某个子目录使用 h5ai 的话，你可以放到任意一个你想的子目录中。</p></div></div><ol>
<li>修改服务器配置：修改默认文档
<strong>其实就是在站点默认文档中加入<code>/_h5ai/public/index.php</code>这一项</strong></li>
</ol><ul>
<li>Apache: <code>httpd.conf</code>或者网站根目录的<code>.htaccess</code></li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>DirectoryIndex  index.html  index.php  /_h5ai/public/index.php</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>lighttpd 1.4: <code>lighttpd.conf</code></li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>index-file.names += ("index.html", "index.php", "/_h5ai/public/index.php")</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>nginx 1.2: <code>nginx.conf</code></li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>index  index.html  index.php  /_h5ai/public/index.php;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>Cherokee 1.2: <code>cherokee.conf</code></li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>vserver!1!directory_index = index.html,index.php,/_h5ai/public/index.php</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>禁止<code>/_h5ai/private</code>中的内容被访问
此目录下的文件不宜泄露，因此需要配置服务器以禁止此目录下的文件被访问。
这里拿 nginx 的配置来做示例。
在 nginx 当前网站的配置中加上以下内容：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>location ~ ^/_h5ai/private/ {</span></div></div><div><div><div>2</div></div><div><span><span>    </span></span><span>return 404;</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>如果在子目录中部署的话，前面要加上子目录的路径。</p></section>
<section><h2>注意事项<a href="#注意事项"><span>#</span></a></h2><ul>
<li><strong>如果发现无法正常使用，检查 PHP 禁用函数，不能禁用<code>exec</code>、<code>passthru</code>、<code>scandir</code>。</strong></li>
<li><strong>如果排除了上面这个问题，仍然不能显示文件，请检查你的站点根目录中是否有创建站点时自动生成的<code>index.html</code>之类的默认首页文件，请删除。</strong></li>
<li>在 _h5ai 中<strong>不会显示</strong>任何以<code>.</code>开头的隐藏文件/文件夹，也<strong>不会显示</strong>任何以<code>_h5ai</code>开头的文件/文件夹。
你也可以用正则表达式自定义不显示的文件/文件夹，这里在后面会讲，这可以用来保护隐私。</li>
<li><strong>不要使用目录别名</strong>（例如 Apache / nginx 的 alias），这会使 h5ai 无法得到目录下文件的地址。</li>
<li>在 Ubuntu 上你可能需要额外安装<code>PHP JSON</code>支持包。</li>
</ul></section>
<section><h2>配置文件<a href="#配置文件"><span>#</span></a></h2><p>h5ai 的配置文件位于<code>/_h5ai/private/conf/options.json</code></p><p>此处只讲一些比较重要的常用配置，仅作解释，请勿照抄，根据自己实际需求更改<code>true</code>或者<code>false</code>等。</p><section><h3>浏览相关<a href="#浏览相关"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>"view"</span><span>: {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>//为true的话，用1024进制来计算文件大小</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"binaryPrefix"</span><span>: </span><span>true</span><span>,</span></div></div><div><div><div>4</div></div><div><span>    </span><span>...</span></div></div><div><div><div>5</div></div><div><span>    </span><span>//隐藏名字与这些正则表达式匹配的文件/文件夹</span></div></div><div><div><div>6</div></div><div><span>    </span><span>"hidden"</span><span>: [</span><span>"^</span><span>\\</span><span>."</span><span>, </span><span>"^_h5ai"</span><span>],</span></div></div><div><div><div>7</div></div><div><span>    </span><span>...</span></div></div><div><div><div>8</div></div><div><span>    </span><span>//如果目录里存在这些文件之一则不应用 _h5ai 来管理文件</span></div></div><div><div><div>9</div></div><div><span>    </span><span>//（即用于点击目录直接打开网站之类的）</span></div></div><div><div><div>10</div></div><div><span>    </span><span>"unmanaged"</span><span>: [</span><span>"index.html"</span><span>, </span><span>"index.htm"</span><span>, </span><span>"index.php"</span><span>],</span></div></div><div><div><div>11</div></div><div><span>    </span><span>//是否在新窗口中打开上面提到的这种目录</span></div></div><div><div><div>12</div></div><div><span>    </span><span>"unmanagedInNewWindow"</span><span>: </span><span>false</span></div></div><div><div><div>13</div></div><div><span>},</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>自定义页头页脚<a href="#自定义页头页脚"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>"custom"</span><span>: {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>"enabled"</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>},</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>开启之后，可以自定义页头页脚。</p><p>当你打开一个目录后，_h5ai 会检测当前目录中是否含有<code>_h5ai.header.html</code>和<code>_h5ai.footer.html</code>，如果有的话则会当做页头/页脚显示。</p><p>如果找不到这两个文件，则会在当前目录或者依次去父级目录中寻找<code>_h5ai.headers.html</code>和<code>_h5ai.footers.html</code>这两个文件，如果有的话，则会当做页头/页脚显示。</p><p>这个机制很简单，其实就是带<code>s</code>的就可以让本目录及子目录都显示这个页头/页脚，但是不带<code>s</code>的具有更高的优先级。</p></section><section><h3>开启批量下载<a href="#开启批量下载"><span>#</span></a></h3><div><div><div></div><div>Warning</div></div><div><p>如果要开启批量下载功能，还需要<a href="#启用多选功能">启用多选功能</a>。</p></div></div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>"download"</span><span>: {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>//是否启用批量下载</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"enabled"</span><span>: </span><span>false</span><span>,</span></div></div><div><div><div>4</div></div><div><span>    </span><span>//批量打包方式，可选"php-tar", "shell-tar", "shell-zip"</span></div></div><div><div><div>5</div></div><div><span>    </span><span>"type"</span><span>: </span><span>"php-tar"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>    </span><span>//打包后的压缩包的名字，为 null 的话就使用当前目录的名字</span></div></div><div><div><div>7</div></div><div><span>    </span><span>"packageName"</span><span>: </span><span>null</span><span>,</span></div></div><div><div><div>8</div></div><div><span>    </span><span>//是否始终显示下载按钮</span></div></div><div><div><div>9</div></div><div><span>    </span><span>"alwaysVisible"</span><span>: </span><span>false</span></div></div><div><div><div>10</div></div><div><span>},</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>开启文件地址二维码<a href="#开启文件地址二维码"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>"info"</span><span>: {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>//是否允许显示信息侧边栏</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"enabled"</span><span>: </span><span>true</span><span>,</span></div></div><div><div><div>4</div></div><div><span>    </span><span>//是否默认显示侧边栏</span></div></div><div><div><div>5</div></div><div><span>    </span><span>"show"</span><span>: </span><span>true</span><span>,</span></div></div><div><div><div>6</div></div><div><span>    </span><span>//是否显示二维码</span></div></div><div><div><div>7</div></div><div><span>    </span><span>"qrcode"</span><span>: </span><span>true</span><span>,</span></div></div><div><div><div>8</div></div><div><span>    </span><span>//二维码前景色</span></div></div><div><div><div>9</div></div><div><span>    </span><span>"qrFill"</span><span>: </span><span>"#999"</span><span>,</span></div></div><div><div><div>10</div></div><div><span>    </span><span>//二维码背景色</span></div></div><div><div><div>11</div></div><div><span>    </span><span>"qrBack"</span><span>: </span><span>"#fff"</span></div></div><div><div><div>12</div></div><div><span>},</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>设置默认语言为中文<a href="#设置默认语言为中文"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>"l10n"</span><span>: {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>//用户是否可以自行选择语言</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"enabled"</span><span>: </span><span>true</span><span>,</span></div></div><div><div><div>4</div></div><div><span>    </span><span>//默认语言，"zh-cn"为简体中文，其他支持的语言可以到"/_h5ai/conf/l10n"中查看</span></div></div><div><div><div>5</div></div><div><span>    </span><span>"lang"</span><span>: </span><span>"zh-cn"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>    </span><span>//根据浏览器自动判断语言</span></div></div><div><div><div>7</div></div><div><span>    </span><span>"useBrowserLang"</span><span>: </span><span>true</span></div></div><div><div><div>8</div></div><div><span>},</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>启用搜索功能<a href="#启用搜索功能"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>"search"</span><span>: {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>//是否启用搜索</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"enabled"</span><span>: </span><span>true</span><span>,</span></div></div><div><div><div>4</div></div><div><span>    </span><span>//是否开启进阶搜索（需要开启"filter"设置项，具体请自行研究）</span></div></div><div><div><div>5</div></div><div><span>    </span><span>"advanced"</span><span>: </span><span>true</span><span>,</span></div></div><div><div><div>6</div></div><div><span>    </span><span>"debounceTime"</span><span>: </span><span>300</span><span>,</span></div></div><div><div><div>7</div></div><div><span>    </span><span>//是否忽略例外</span></div></div><div><div><div>8</div></div><div><span>    </span><span>"ignorecase"</span><span>: </span><span>true</span></div></div><div><div><div>9</div></div><div><span>},</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>启用多选功能<a href="#启用多选功能"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>"select"</span><span>: {</span></div></div><div><div><div>2</div></div><div><span>    </span><span>//是否启用多选</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"enabled"</span><span>: </span><span>false</span><span>,</span></div></div><div><div><div>4</div></div><div><span>    </span><span>//是否启用拖拽式多选</span></div></div><div><div><div>5</div></div><div><span>    </span><span>"clickndrag"</span><span>: </span><span>true</span><span>,</span></div></div><div><div><div>6</div></div><div><span>    </span><span>//是否启用多选框</span></div></div><div><div><div>7</div></div><div><span>    </span><span>"checkboxes"</span><span>: </span><span>true</span></div></div><div><div><div>8</div></div><div><span>},</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/ubuntu-change-kernel/</id>
      <title type="text">[Linux] Ubuntu 更换内核以支持锐速</title>
      <published>2017-11-07T13:26:00.000Z</published>
      <updated>2017-11-07T13:33:30.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/ubuntu-change-kernel/"/>
      <summary type="text">只是拿锐速举个例子，如果是由于其他原因需要更换内核，那么当然也可以按照这篇教程。</summary>
      <content type="html"><![CDATA[<p>只是拿锐速举个例子，如果是由于其他原因需要更换内核，那么当然也可以按照这篇教程。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=64451830" target="_blank">「夏チノ」/「ふぇありぃあい」のイラスト [pixiv]</a></p>
<hr />
<section><h2>明确你要更换的内核版本<a href="#明确你要更换的内核版本"><span>#</span></a></h2><p>例如需要安装锐速，这里拿 Vicer 大大的脚本举例：
<a href="https://moeclub.org/2017/03/08/14/" target="_blank">[锐速] [serverSpeeder] [lotServer] | 萌咖</a></p><p>例如 Ubuntu 16.04，首先在 Vicer 大大的<a href="https://github.com/0oVicero0/serverSpeeder_kernel/blob/master/serverSpeeder.txt" target="_blank">锐速脚本版本库</a>中查到其支持的最新内核为<code>4.4.0-47-generic</code>，下面说明如何更换内核</p></section>
<section><h2>更换内核<a href="#更换内核"><span>#</span></a></h2><p>首先你必须进入 root，然后</p><ol>
<li>安装新内核，版本号替换成你需要安装的版本，这里拿安装上面提到的那个内核做例子</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>linux-image-extra-4.4.0-47-generic</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>查看当前安装的内核</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>dpkg</span><span> </span><span>-l</span><span> | </span><span>grep</span><span> </span><span>linux-image</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>卸载你在第二步中看到的，除了你刚才新安装的内核之外的版本的内核（通常会有两个）
将<code>x.x.x-xx</code>替换成旧的内核版本</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>purge</span><span> </span><span>linux-image-x.x.x-xx-generic</span><span> </span><span>linux-image-extra-x.x.x-xx-generic</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>更新grub系统引导文件并重启系统</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>update-grub</span></div></div><div><div><div>2</div></div><div><span>reboot</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>重启之后查看当前内核版本，应该变为你更换了的内核了</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>uname</span><span> </span><span>-r</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/fate-iriya-movie/</id>
      <title type="text">Fate/kaleid liner 魔法少女☆伊莉雅：雪下的誓言</title>
      <published>2017-11-06T13:51:00.000Z</published>
      <updated>2018-05-18T11:55:51.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/fate-iriya-movie/"/>
      <summary type="text">资源！资源！</summary>
      <content type="html"><![CDATA[<p>资源！资源！</p>
<hr />
<p></p><figure><img src="/usr/uploads/2017/11/3063099889.jpg" alt="visual_01_pc.jpg" /><figcaption>visual_01_pc.jpg</figcaption></figure><p></p>
<section><h2>水点简介<a href="#水点简介"><span>#</span></a></h2><p>《Fate/kaleid liner 魔法少女☆伊莉雅：雪下的誓言》是由大沼心指导，井上坚二和水濑叶月编剧，SILVER LINK.制作的动画电影。</p><p>改编自广山弘原作的《Fate/stay night》外传漫画《Fate/kaleid liner 魔法少女☆伊莉雅 3rei!!》的第7卷内容，即电视动画第4期《Fate/kaleid liner 魔法少女☆伊莉雅 3rei!!》之后，“平行世界”中卫宫士郎和美游两兄妹的故事。</p><p>影片于2017年8月26日在日本上映。
官网：<a href="http://anime.prisma-illya.jp/movie/sekka/#home" target="_blank">「剧场版Fate/kaleid liner プリズマ☆イリヤ 」公式サイト </a></p><table><tbody><tr><td>剧本</td><td>井上坚二、水濑叶月</td></tr><tr><td>角色设计</td><td>平田和也</td></tr><tr><td>动画制作</td><td>SILVER LINK.</td></tr><tr><td>音乐</td><td>加藤达也、TECHNOBOYS PULCRAFT GREEN-FUND</td></tr><tr><td>主要配音</td><td>名冢佳织、杉山纪彰、下屋则子、花江夏树、小山力也、中田让治</td></tr><tr><td>原作</td><td>广山弘、TYPE-MOON</td></tr><tr><td>导演</td><td>大沼心</td></tr><tr><td>出品</td><td>《剧场版魔法少女☆伊莉雅》制作委员会</td></tr><tr><td>发行</td><td>角川ANIMATION</td></tr></tbody></table></section>
<section><h2>剧情简介<a href="#剧情简介"><span>#</span></a></h2><p>“我想我可以说出来了。我与美游的……至今为止的故事”</p><p>世界向着毁灭前进。能够阻止毁灭的步伐的，唯有身为“圣杯”的美游的牺牲而已。要选择世界，还是美游——。面对发起“世界的救济”的恩兹华斯所提出的这个问题，伊莉雅给出的答案是，“拯救双方”这种单纯的“任性”。</p><p>战斗迎来暂时的休止，一行人暂时栖身于美游与士郎成长的家中。在众人团聚的途中，士郎开始讲述自己与美游的过去。</p><p>曾经能够无差别地实现任何愿望的神稚儿美游。士郎将无家可归的她带回了自己与切嗣一同生活过的家里。在那之后过了5年。两人如同亲兄妹一般度过着平稳的生活。</p><p>但是，这样的日常却突然迎来了结束。造访美游老家的两人。在他们的面前，将美游当成“奇迹”地追求的朱利安出现了。</p><p>美游与士郎、恩兹华斯的因缘，在此揭晓。</p></section>
<section><h2>PV<a href="#pv"><span>#</span></a></h2><section><h3>第一弹<a href="#第一弹"><span>#</span></a></h3><p>视频大小 7.75 MB
您的浏览器不支持 HTML5 视频。 <a href="https://res.lolicon.app/video/iriya-movie-1.mp4">打开视频</a></p></section><section><h3>第二弹<a href="#第二弹"><span>#</span></a></h3><p>视频大小 10.2 MB
您的浏览器不支持 HTML5 视频。 <a href="https://res.lolicon.app/video/iriya-movie-2.mp4">打开视频</a></p></section><section><h3>第三弹<a href="#第三弹"><span>#</span></a></h3><p>视频大小 11.7 MB
您的浏览器不支持 HTML5 视频。 <a href="https://res.lolicon.app/video/iriya-movie-3.mp4">打开视频</a></p></section><section><h3>第四弹<a href="#第四弹"><span>#</span></a></h3><p>视频大小 12.7 MB
您的浏览器不支持 HTML5 视频。 <a href="https://res.lolicon.app/video/iriya-movie-4.mp4">打开视频</a></p></section></section>
<section><h2>下载地址<a href="#下载地址"><span>#</span></a></h2><ul>
<li><a href="https://mega.nz/#!s1412DxB!ht9lxjZ_dqMygQnFZCgi-dOobYhqTLmMKzEm8cPDf14" target="_blank">MEGA</a></li>
<li><a href="https://pan.baidu.com/s/1nviigeX" target="_blank">度娘</a> 密码: aeew</li>
<li><a href="https://drive.google.com/open?id=1RRfI8Kqc0fcMsdLDtIOYf1mI5UhlzqDe" target="_blank">某不存在的 Google Drive</a></li>
</ul><p></p><figure><img src="/usr/uploads/2017/11/1910568899.jpg" alt="story_01.jpg" /><figcaption>story_01.jpg</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/dnsmasq/</id>
      <title type="text">[DNSmasq] 安装&amp;配置详解</title>
      <published>2017-11-06T12:26:00.000Z</published>
      <updated>2018-04-21T20:37:56.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/dnsmasq/"/>
      <summary type="text">DNSmasq 是 Linux 下的一个用于配置 DNS 和 DHCP 的工具，个人认为最主要的功能还是用来做 DNS 服务器。一句话，好用的不行。</summary>
      <content type="html"><![CDATA[<p>DNSmasq 是 Linux 下的一个用于配置 DNS 和 DHCP 的工具，个人认为最主要的功能还是用来做 DNS 服务器。一句话，好用的不行。</p>
<p>Head Pic: <a href="http://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=1488083" target="_blank">「【PFⅡ】ヘッツェル」/「たはるコウスケ」のイラスト [pixiv]</a></p>
<hr />
<section><h2>安装<a href="#安装"><span>#</span></a></h2><section><h3>Ubuntu/Debian 等<a href="#ubuntudebian-等"><span>#</span></a></h3><p>无需多说，直接</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>install</span><span> </span><span>dnsmasq</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>CentOS<a href="#centos"><span>#</span></a></h3><p>由于 CentOS 的 yum 安装的 DNSmasq 版本比较旧，因此我们可以先下载最新版编译好，用 yum 安装完之后再替换掉程序。</p><p>先从 <a href="http://www.thekelleys.org.uk/dnsmasq/" target="_blank">http://www.thekelleys.org.uk/dnsmasq/</a> 找到你想要的 DNSmasq 版本的源码压缩包的下载地址，例如我选择的是我写这篇文章时的最新版<code>dnsmasq-2.78.tar.gz</code>。</p><p>下载对应的源码压缩包并解压</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>http://www.thekelleys.org.uk/dnsmasq/dnsmasq-2.78.tar.gz</span></div></div><div><div><div>2</div></div><div><span>tar</span><span> </span><span>xf</span><span> </span><span>dnsmasq-2.78.tar.gz</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>编译，源码 make 不带 etc 等</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>cd</span><span> </span><span>dnsmasq-2.78</span></div></div><div><div><div>2</div></div><div><span>make</span><span> </span><span>V=s</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后用 yum 安装 DNSmasq</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yum</span><span> </span><span>install</span><span> </span><span>dnsmasq</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>yum 安装的是2.4.8版本，然后我们再用我们编译好的最新版本替换</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yes</span><span> | </span><span>cp</span><span> </span><span>-f</span><span> </span><span>./src/dnsmasq</span><span> </span><span>/usr/sbin/dnsmasq</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这时可以查看 DNSmasq 的版本检验一下</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>dnsmasq</span><span> </span><span>-v</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>看一下版本号，应该就是我们编译好的版本了</p></section></section>
<section><h2>配置<a href="#配置"><span>#</span></a></h2><p>DNSmasq 的配置文件位于<code>/etc/dnsmasq.conf</code>，下面是 DNSmasq 中和 DNS 相关的配置项的说明。</p><div><div><div></div><div>Caution</div></div><div><p>此处的配置仅为说明，请勿照抄配置</p></div></div><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 用指定的端口代替默认的DNS 53端口，如果设置为0，则完全禁止DNS功能，只使用dhcp服务</span></div></div><div><div><div>2</div></div><div><span>port</span><span>=</span><span>5353</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 以下两个参数告诉Dnsmasq过滤一些查询：1.哪些公共DNS没有回答 2.哪些root根域不可达。</span></div></div><div><div><div>5</div></div><div><span># 从不转发格式错误的域名</span></div></div><div><div><div>6</div></div><div><span>domain-needed</span></div></div><div><div><div>7</div></div><div><span># 从不转发不在路由地址中的域名</span></div></div><div><div><div>8</div></div><div><span>bogus-priv</span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span># resolv-file配置Dnsmasq额外的向流的DNS服务器，通过下面的选项指定其他文件。</span></div></div><div><div><div>11</div></div><div><span># 如果不开启就使用linux主机默认的/etc/resolv.conf里的nameserver。</span></div></div><div><div><div>12</div></div><div><span>resolv-file</span><span>=</span><span>/etc/dnsmasq.d/upstream_dns.conf</span></div></div><div><div><div>13</div></div><div>
</div></div><div><div><div>14</div></div><div><span># 默认情况下Dnsmasq会发送查询到它的任何上游DNS服务器上，如果取消注释，</span></div></div><div><div><div>15</div></div><div><span># 则Dnsmasq则会严格按照/etc/resolv.conf中的DNS Server顺序进行查询。</span></div></div><div><div><div>16</div></div><div><span>strict-order</span></div></div><div><div><div>17</div></div><div>
</div></div><div><div><div>18</div></div><div><span># 以下两个参数控制是否通过/etc/resolv.conf确定上游服务器，是否检测/etc/resolv.conf的变化。</span></div></div><div><div><div>19</div></div><div><span># 如果你不想Dnsmasq读取/etc/resolv.conf文件或者其他文件，获得它的servers，则取消注释。</span></div></div><div><div><div>20</div></div><div><span>no-resolv</span></div></div><div><div><div>21</div></div><div><span># 如果你不允许Dnsmasq通过轮询/etc/resolv.conf或者其他文件来获取配置的改变，则取消注释。</span></div></div><div><div><div>22</div></div><div><span>no-poll</span></div></div><div><div><div>23</div></div><div>
</div></div><div><div><div>24</div></div><div><span># 增加一个name server，一般用于内网域名</span></div></div><div><div><div>25</div></div><div><span>server</span><span>=</span><span>/localnet/192.168.0.1</span></div></div><div><div><div>26</div></div><div>
</div></div><div><div><div>27</div></div><div><span># 设置一个反向解析，所有192.168.3.0/24的地址都到10.1.2.3去解析</span></div></div><div><div><div>28</div></div><div><span>server</span><span>=</span><span>/3.168.192.in-addr.arpa/10.1.2.3</span></div></div><div><div><div>29</div></div><div>
</div></div><div><div><div>30</div></div><div><span># 增加一个本地域名，会在/etc/hosts中进行查询</span></div></div><div><div><div>31</div></div><div><span>local</span><span>=</span><span>/localnet/</span></div></div><div><div><div>32</div></div><div>
</div></div><div><div><div>33</div></div><div><span># 增加一个域名，强制解析到你指定的地址上</span></div></div><div><div><div>34</div></div><div><span>address</span><span>=</span><span>/double-click.net/127.0.0.1</span></div></div><div><div><div>35</div></div><div>
</div></div><div><div><div>36</div></div><div><span># 同上，还支持ipv6</span></div></div><div><div><div>37</div></div><div><span>address</span><span>=</span><span>/www.thekelleys.org.uk/fe80::20d:60ff:fe36:f83</span></div></div><div><div><div>38</div></div><div>
</div></div><div><div><div>39</div></div><div><span># 增加查询yahoo google和它们的子域名到vpn、search查找</span></div></div><div><div><div>40</div></div><div><span>ipset</span><span>=</span><span>/yahoo.com/google.com/vpn,search</span></div></div><div><div><div>41</div></div><div>
</div></div><div><div><div>42</div></div><div><span># 你还可以控制Dnsmasq和Server之间的查询从哪个网卡出去</span></div></div><div><div><div>43</div></div><div><span>server</span><span>=</span><span>10.1.2.3@eth1</span></div></div><div><div><div>44</div></div><div>
</div></div><div><div><div>45</div></div><div><span># 指定源地址携带10.1.2.3地址和192.168.1.1的55端口进行通讯</span></div></div><div><div><div>46</div></div><div><span>server</span><span>=</span><span>10.1.2.3@192.168.1.1</span><span>#55</span></div></div><div><div><div>47</div></div><div>
</div></div><div><div><div>48</div></div><div><span># 改变Dnsmasq默认的uid和gid</span></div></div><div><div><div>49</div></div><div><span>user</span><span>=</span></div></div><div><div><div>50</div></div><div><span>group</span><span>=</span></div></div><div><div><div>51</div></div><div>
</div></div><div><div><div>52</div></div><div><span># 如果你想Dnsmasq监听某个端口为dhcp、dns提供服务</span></div></div><div><div><div>53</div></div><div><span>interface</span><span>=</span></div></div><div><div><div>54</div></div><div>
</div></div><div><div><div>55</div></div><div><span># 你还可以指定哪个端口你不想监听</span></div></div><div><div><div>56</div></div><div><span>except-interface</span><span>=</span></div></div><div><div><div>57</div></div><div>
</div></div><div><div><div>58</div></div><div><span># 设置想监听的地址，如果你本机要使用写上127.0.0.1。</span></div></div><div><div><div>59</div></div><div><span>listen-address</span><span>=</span></div></div><div><div><div>60</div></div><div>
</div></div><div><div><div>61</div></div><div><span># 如果你想在某个端口只提供dns服务，则可以进行配置禁止dhcp服务</span></div></div><div><div><div>62</div></div><div><span>no-dhcp-interface</span><span>=</span></div></div><div><div><div>63</div></div><div>
</div></div><div><div><div>64</div></div><div><span># On systems which support it, dnsmasq binds the wildcard address,</span></div></div><div><div><div>65</div></div><div><span># even when it is listening on only some interfaces. It then discards</span></div></div><div><div><div>66</div></div><div><span># requests that it shouldn't reply to. This has the advantage of</span></div></div><div><div><div>67</div></div><div><span># working even when interfaces come and go and change address. If you</span></div></div><div><div><div>68</div></div><div><span># want dnsmasq to really bind only the interfaces it is listening on,</span></div></div><div><div><div>69</div></div><div><span># uncomment this option. About the only time you may need this is when</span></div></div><div><div><div>70</div></div><div><span># running another nameserver on the same machine.</span></div></div><div><div><div>71</div></div><div><span>bind-interfaces</span></div></div><div><div><div>72</div></div><div>
</div></div><div><div><div>73</div></div><div><span># 如果你不想使用/etc/hosts，则取消下面的注释</span></div></div><div><div><div>74</div></div><div><span>no-hosts</span></div></div><div><div><div>75</div></div><div>
</div></div><div><div><div>76</div></div><div><span># 如果你项读取其他类似/etc/hosts文件，则进行配置</span></div></div><div><div><div>77</div></div><div><span>addn-hosts</span><span>=</span><span>/etc/banner_add_hosts</span></div></div><div><div><div>78</div></div><div>
</div></div><div><div><div>79</div></div><div><span># 自动的给hosts中的name增加一个域名</span></div></div><div><div><div>80</div></div><div><span>expand-hosts</span></div></div><div><div><div>81</div></div><div>
</div></div><div><div><div>82</div></div><div><span># 给dhcp服务赋予一个域名</span></div></div><div><div><div>83</div></div><div><span>domain</span><span>=</span><span>thekelleys.org.uk</span></div></div><div><div><div>84</div></div><div>
</div></div><div><div><div>85</div></div><div><span># 给dhcp的一个子域赋予一个不同的域名</span></div></div><div><div><div>86</div></div><div><span>domain</span><span>=</span><span>wireless.thekelleys.org.uk,192.168.2.0/24</span></div></div><div><div><div>87</div></div><div>
</div></div><div><div><div>88</div></div><div><span># 同上，不过子域是一个范围</span></div></div><div><div><div>89</div></div><div><span>domain</span><span>=</span><span>reserved.thekelleys.org.uk,192.68.3.100,192.168.3.200</span></div></div><div><div><div>90</div></div><div>
</div></div><div><div><div>91</div></div><div><span># dhcp分发ip的范围，以及每个ip的租约时间</span></div></div><div><div><div>92</div></div><div><span>dhcp-range</span><span>=</span><span>192.168.0.50,192.168.0.150,12h</span></div></div><div><div><div>93</div></div><div>
</div></div><div><div><div>94</div></div><div><span># 同上，不过给出了掩码</span></div></div><div><div><div>95</div></div><div><span>dhcp-range</span><span>=</span><span>192.168.0.50,192.168.0.150,255.255.255.0,12h</span></div></div><div><div><div>96</div></div><div>
</div></div><div><div><div>97</div></div><div><span># 自动加载conf-dir目录下的配置文件</span></div></div><div><div><div>98</div></div><div><span>conf-dir</span><span>=</span><span>/etc/dnsmasq.d</span></div></div><div><div><div>99</div></div><div>
</div></div><div><div><div>100</div></div><div><span># 设置dns缓存大小,默认为150条</span></div></div><div><div><div>101</div></div><div><span>cache-size</span><span>=</span><span>150</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>修改完配置之后需要重启 DNSmasq 以使配置生效</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>service dnsmasq start</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>配置过程中需要注意的几点<a href="#配置过程中需要注意的几点"><span>#</span></a></h2><section><h3>把你的服务器作为一个 DNS 服务器<a href="#把你的服务器作为一个-dns-服务器"><span>#</span></a></h3><ol>
<li>配置中的<code>listen-address</code>必须为你服务器的公网 IP</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>listen-address=你的公网IP</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>在防火墙中开放 53 端口</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>iptables</span><span> </span><span>-A</span><span> </span><span>INPUT</span><span> </span><span>-p</span><span> </span><span>udp</span><span> </span><span>-m</span><span> </span><span>udp</span><span> </span><span>--dport</span><span> </span><span>53</span><span> </span><span>-j</span><span> </span><span>ACCEPT</span></div></div><div><div><div>2</div></div><div><span>iptables</span><span> </span><span>-A</span><span> </span><span>INPUT</span><span> </span><span>-p</span><span> </span><span>tcp</span><span> </span><span>-m</span><span> </span><span>tcp</span><span> </span><span>--dport</span><span> </span><span>53</span><span> </span><span>-j</span><span> </span><span>ACCEPT</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>如果是 <strong>CentOS</strong> 的话需要保存并重启防火墙使以上改动生效</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>service</span><span> </span><span>iptables</span><span> </span><span>save</span></div></div><div><div><div>2</div></div><div><span>service</span><span> </span><span>iptables</span><span> </span><span>restart</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>如果想强制重定向本地的 DNS 请求给 DNSmasq<a href="#如果想强制重定向本地的-dns-请求给-dnsmasq"><span>#</span></a></h3><p><code>eth0</code>为网卡名，请替换为你自己机器的网卡名</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>iptables</span><span> </span><span>-t</span><span> </span><span>nat</span><span> </span><span>-A</span><span> </span><span>PREROUTING</span><span> </span><span>-i</span><span> </span><span>eth0</span><span> </span><span>-p</span><span> </span><span>upd</span><span> </span><span>--dport</span><span> </span><span>53</span><span> </span><span>-j</span><span> </span><span>REDIRECT</span><span> </span><span>--to-port</span><span> </span><span>53</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后重启防火墙（如果是 CentOS）</p></section><section><h3>如果想自定义上游 DNS<a href="#如果想自定义上游-dns"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>no-resolv</span></div></div><div><div><div>2</div></div><div><span>no-poll</span></div></div><div><div><div>3</div></div><div><span>server</span><span>=</span><span>x.x.x.x</span><span>#端口</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>不写<code>#端口</code>默认是<code>53</code></p></section></section>
<section><h2>使用上的一些建议<a href="#使用上的一些建议"><span>#</span></a></h2><p>如果需要自定义上游 DNS 服务器，以及设置特定域名的 Host 之类的，建议写到一个单独的<code>.conf</code>配置文件里，然后放到一个专门的文件夹，然后修改 DNSmasq 配置中的这条</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>conf-dir=配置文件夹</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>这样的话以后修改配置就不需要频繁修改主配置文件，而且也有利于配置的分块</p></section>
<section><h2>dnsmasq-china-list<a href="#dnsmasq-china-list"><span>#</span></a></h2><p>dnsmasq-china-list项目维护了一张国内常用但是通过国外DNS会解析错误的网站域名的列表，保证List中的国内域名全部走国内DNS服务器解析。</p><p>项目地址: <a href="https://github.com/felixonmars/dnsmasq-china-list" target="_blank">https://github.com/felixonmars/dnsmasq-china-list</a></p><section><h3>使用<a href="#使用"><span>#</span></a></h3><p>取消配置文件中<code>conf-dir=/etc/dnsmasq.d</code>这一行的注释</p><div><div><div></div><div>Note</div></div><div><p>如果此处你是用的是自己的配置文件夹，那么久在后续步骤中将配置文件放入你自己的配置文件夹即可</p></div></div><p>随便找一个地方将项目文件下载下来</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span> </span><span>clone</span><span> </span><span>https://github.com/felixonmars/dnsmasq-china-list.git</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后将其中的<code>accelerated-domains.china.conf</code>， <code>bogus-nxdomain.china.conf</code>，<code>google.china.conf</code>（可选）放到<code>/etc/dnsmasq.d/</code>目录中
最后重启 DNSmasq 即可</p></section></section>
<section><h2>参考文章<a href="#参考文章"><span>#</span></a></h2><p><a href="https://www.quyu.net/info/571.html" target="_blank">CentOS下yum安装dnsmasq,并强制替换为最新版</a>
<a href="https://www.hi-linux.com/posts/30947.html" target="_blank">利用Dnsmasq部署DNS服务</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/hosts-for-steam-fgo/</id>
      <title type="text">[Hosts] Pixiv &amp; Steam &amp; Fate-go 直连</title>
      <published>2017-10-21T15:11:00.000Z</published>
      <updated>2019-04-28T09:27:34.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/hosts-for-steam-fgo/"/>
      <summary type="text">对于 Pixiv / Steam / Fate-go 无法直连，以及某些被 DNS 污染的网站无法直连的解决方案。 最后更新：2017-10-21</summary>
      <content type="html"><![CDATA[<p>对于 Pixiv / Steam / Fate-go 无法直连，以及某些被 DNS 污染的网站无法直连的解决方案。
最后更新：2017-10-21</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=64204462" target="_blank">ﾄﾞﾗkawa。 by ﾌﾞﾚｴﾄﾞ</a></p>
<hr />
<div><div><div></div><div>Caution</div></div><div><p>由于 GFW 已升级为 SNI 阻断，Hosts 已经不再起效</p></div></div>
<section><h2>简述<a href="#简述"><span>#</span></a></h2><p>如果你的网络没有问题，但是你上不去一个网站，那么有三种可能</p><ol>
<li>这个网站死了</li>
<li>这个网站被墙了</li>
<li>这个网站在国内遭到了 DNS 污染</li>
</ol><p>修改 Hosts 可以解决小部分第二种问题和绝大部分第三种问题，但是本文的 Host 旨在解决第三种问题。</p><p>如果你需要完全的解决第三种问题，那么我建议你去 <a href="https://laod.cn/hosts/2017-google-hosts.html" target="_blank">这里</a>。</p></section>
<section><h2>如何知道这个网站遭到了 DNS 污染<a href="#如何知道这个网站遭到了-dns-污染"><span>#</span></a></h2><p>此判断方法只对国外网站有效，因为某些国内网站可能会对应国内和国外给出不同的IP地址</p><p>在电脑上打开命令提示符，执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ping</span><span> </span><span>你要上的网站域名</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>请注意是域名，而不是网址！
然后你应该能看到解析出来的 IP 地址，记下它。</p><p>接着到
<a href="https://whatismyipaddress.com/hostname-ip" target="_blank">https://whatismyipaddress.com/hostname-ip</a>
把你要上的网站域名输进去，点击“Lookup IP Address”</p><p>如果得出的结果中没有一个是你在上面 ping 到的 IP 地址，并且在<a href="https://zh.wikipedia.org/wiki/%E5%9F%9F%E5%90%8D%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%BC%93%E5%AD%98%E6%B1%A1%E6%9F%93#IPv4%E7%8E%AF%E5%A2%83" target="_blank">此 IP 列表</a>内，那么恭喜你，这个网站被国内 DNS 污染了。</p></section>
<section><h2>DNS 污染是什么<a href="#dns-污染是什么"><span>#</span></a></h2><p>首先你要知道 DNS 是什么。
简单的来说，DNS 就是一个能让网址转换为其对应的 IP 地址的东西，没有这个的话你仅凭网址是没办法上网的。</p><p>DNS 污染就是 GFW 通过拦截指定网站的 DNS 请求，并返回给你一个实际上不存在或无法连通的 IP 地址，而达到不让你上某些网站的目的。</p><p>如果一个网站仅仅是遭到了 DNS 污染，那么无需翻*也可以解决。</p></section>
<section><h2>如何解决<a href="#如何解决"><span>#</span></a></h2><p>仿照下面的方式写一份属于你自己的 Hosts 文件，然后把内容添加到系统 Hosts 文件中然后保存即可，即时生效。</p></section>
<section><h2>Hosts<a href="#hosts"><span>#</span></a></h2><p>以下给出</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span># Steam</span></div></div><div><div><div>2</div></div><div><span>23.66.253.192    store.steampowered.com</span></div></div><div><div><div>3</div></div><div><span>23.66.253.192    steamcommunity.com</span></div></div><div><div><div>4</div></div><div><span># Fate-go</span></div></div><div><div><div>5</div></div><div><span>54.192.143.40    data.fate-go.jp</span></div></div><div><div><div>6</div></div><div><span># Pixiv</span></div></div><div><div><div>7</div></div><div><span>210.129.120.41   pixiv.net</span></div></div><div><div><div>8</div></div><div><span>210.129.120.41   www.pixiv.net</span></div></div><div><div><div>9</div></div><div><span>210.129.120.41   accounts.pixiv.net</span></div></div><div><div><div>10</div></div><div><span>210.140.131.144  source.pixiv.net</span></div></div><div><div><div>11</div></div><div><span># 备注</span></div></div><div><div><div>12</div></div><div><span># 210.129.120.41 可换成 210.129.120.43 或 210.129.120.44</span></div></div><div><div><div>13</div></div><div><span># 210.140.131.144 可换成 210.140.131.145 ~ 210.140.131.147</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>将以上 Hosts 条目复制粘贴加入 Hosts 文件末尾然后保存即可。</p><section><h3>Hosts 文件在哪<a href="#hosts-文件在哪"><span>#</span></a></h3><p>Windows: <code>C:\Windows\System32\drivers\etc\hosts</code>
Android/iPhone: <code>/etc/hosts</code>
注意安卓需要root，iOS需要越狱才能修改DNS。</p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/js-input-effect/</id>
      <title type="text">[js] 网页输入框打字特效（懒人版）</title>
      <published>2017-10-21T08:54:00.000Z</published>
      <updated>2018-01-07T13:29:08.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/js-input-effect/"/>
      <summary type="text">一个可用于博客的 JavaScript 网页输入框打字特效</summary>
      <content type="html"><![CDATA[<p>一个可用于博客的 JavaScript 网页输入框打字特效</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=55491641" target="_blank">「空の境界×Fate/GO　コラボ記念」/「冬ゆき」のイラスト [pixiv]</a></p>
<hr />
<p>具体效果见本博客评论输入打字效果</p>
<section><h2>如何使用<a href="#如何使用"><span>#</span></a></h2><p>直接下载 <a href="/usr/js/commentTyping.js">这个js脚本</a> 放到网站的某个位置，然后在博客的 <strong>footer</strong> 模板中引用即可，无需再添加任何额外代码。</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>&lt;!-- In footer.php --&gt;</span></div></div><div><div><div>2</div></div><div><span>&lt;</span><span>script</span><span> </span><span>type</span><span>=</span><span>"text/javascript"</span><span> </span><span>src</span><span>=</span><span>"(这个脚本的路径)"</span><span>&gt;&lt;/</span><span>script</span><span>&gt;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><div><div></div><div>Tip</div></div><div><p>这个 JavaScript 脚本已经经过混淆压缩，相比原版脚本更节省流量。</p></div></div><div><div><div></div><div>Warning</div></div><div><p>请务必在 <b>footer</b>，即网页模板中 body 的末尾位置引用！<br />如果在 header 中引用会有找不到 body 的错误。</p></div></div></section>
<section><h2>源码（未压缩混淆）<a href="#源码未压缩混淆"><span>#</span></a></h2><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>(</span><span>function</span><span> </span><span>webpackUniversalModuleDefinition</span><span><span>(</span><span>root</span><span>, </span><span>factory</span><span>) {</span></span></div></div><div><div><div>2</div></div><div><span>  </span><span>if</span><span> (</span><span>typeof</span><span> </span><span>exports</span><span> </span><span>===</span><span> </span><span>"object"</span><span> </span><span>&amp;&amp;</span><span> </span><span>typeof</span><span> </span><span>module</span><span> </span><span>===</span><span> </span><span>"object"</span><span>)</span></div></div><div><div><div>3</div></div><div><span>    </span><span>module</span><span>.</span><span>exports</span><span> </span><span>=</span><span> </span><span>factory</span><span>();</span></div></div><div><div><div>4</div></div><div><span>  </span><span>else</span><span> </span><span>if</span><span> (</span><span>typeof</span><span><span> </span><span>define</span><span> </span></span><span>===</span><span> </span><span>"function"</span><span> </span><span>&amp;&amp;</span><span><span> </span><span>define</span><span>.</span></span><span>amd</span><span>) </span><span>define</span><span><span>([], </span><span>factory</span><span>);</span></span></div></div><div><div><div>5</div></div><div><span>  </span><span>else</span><span> </span><span>if</span><span> (</span><span>typeof</span><span> </span><span>exports</span><span> </span><span>===</span><span> </span><span>"object"</span><span>) </span><span>exports</span><span>[</span><span>"POWERMODE"</span><span>] </span><span>=</span><span> </span><span>factory</span><span>();</span></div></div><div><div><div>6</div></div><div><span>  </span><span>else</span><span><span> </span><span>root</span><span>[</span></span><span>"POWERMODE"</span><span>] </span><span>=</span><span> </span><span>factory</span><span>();</span></div></div><div><div><div>7</div></div><div><span>})(</span><span>this</span><span>, </span><span>function</span><span> () {</span></div></div><div><div><div>8</div></div><div><span>  </span><span>return</span><span> (</span><span>function</span><span><span> (</span><span>modules</span><span>) {</span></span></div></div><div><div><div>9</div></div><div><span>    </span><span>var</span><span><span> </span><span>installedModules</span><span> </span></span><span>=</span><span> {};</span></div></div><div><div><div>10</div></div><div><span>    </span><span>function</span><span> </span><span>__webpack_require__</span><span><span>(</span><span>moduleId</span><span>) {</span></span></div></div><div><div><div>11</div></div><div><span>      </span><span>if</span><span><span> (</span><span>installedModules</span><span>[</span><span>moduleId</span><span>]) </span></span><span>return</span><span><span> </span><span>installedModules</span><span>[</span><span>moduleId</span><span>].</span></span><span>exports</span><span>;</span></div></div><div><div><div>12</div></div><div><span>      </span><span>var</span><span><span> </span><span>module</span><span> </span></span><span>=</span><span><span> (</span><span>installedModules</span><span>[</span><span>moduleId</span><span>] </span></span><span>=</span><span> {</span></div></div><div><div><div>13</div></div><div><span>        </span><span>exports</span><span>:</span><span> {},</span></div></div><div><div><div>14</div></div><div><span>        </span><span>id</span><span>:</span><span><span> </span><span>moduleId</span><span>,</span></span></div></div><div><div><div>15</div></div><div><span>        </span><span>loaded</span><span>:</span><span> </span><span>false</span><span>,</span></div></div><div><div><div>16</div></div><div><span><span>      </span></span><span>});</span></div></div><div><div><div>17</div></div><div><span><span>      </span></span><span>modules</span><span>[</span><span>moduleId</span><span>].</span><span>call</span><span>(</span></div></div><div><div><div>18</div></div><div><span>        </span><span>module</span><span>.</span><span>exports</span><span>,</span></div></div><div><div><div>19</div></div><div><span>        </span><span>module</span><span>,</span></div></div><div><div><div>20</div></div><div><span>        </span><span>module</span><span>.</span><span>exports</span><span>,</span></div></div><div><div><div>21</div></div><div><span><span>        </span></span><span>__webpack_require__</span><span>,</span></div></div><div><div><div>22</div></div><div><span><span>      </span></span><span>);</span></div></div><div><div><div>23</div></div><div><span>      </span><span>module</span><span>.</span><span>loaded</span><span> </span><span>=</span><span> </span><span>true</span><span>;</span></div></div><div><div><div>24</div></div><div><span>      </span><span>return</span><span> </span><span>module</span><span>.</span><span>exports</span><span>;</span></div></div><div><div><div>25</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>26</div></div><div><span><span>    </span></span><span>__webpack_require__</span><span>.</span><span>m</span><span> </span><span>=</span><span><span> </span><span>modules</span><span>;</span></span></div></div><div><div><div>27</div></div><div><span><span>    </span></span><span>__webpack_require__</span><span>.</span><span>c</span><span> </span><span>=</span><span><span> </span><span>installedModules</span><span>;</span></span></div></div><div><div><div>28</div></div><div><span><span>    </span></span><span>__webpack_require__</span><span>.</span><span>p</span><span> </span><span>=</span><span> </span><span>""</span><span>;</span></div></div><div><div><div>29</div></div><div><span>    </span><span>return</span><span> </span><span>__webpack_require__</span><span>(</span><span>0</span><span>);</span></div></div><div><div><div>30</div></div><div><span><span>  </span></span><span>})([</span></div></div><div><div><div>31</div></div><div><span>    </span><span>function</span><span><span> (</span><span>module</span><span>, </span><span>exports</span><span>, </span><span>__webpack_require__</span><span>) {</span></span></div></div><div><div><div>32</div></div><div><span>      </span><span>"use strict"</span><span>;</span></div></div><div><div><div>33</div></div><div><span>      </span><span>var</span><span><span> </span><span>canvas</span><span> </span></span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>createElement</span><span>(</span><span>"canvas"</span><span>);</span></div></div><div><div><div>34</div></div><div><span><span>      </span></span><span>canvas</span><span>.</span><span>width</span><span> </span><span>=</span><span><span> </span><span>window</span><span>.</span></span><span>innerWidth</span><span>;</span></div></div><div><div><div>35</div></div><div><span><span>      </span></span><span>canvas</span><span>.</span><span>height</span><span> </span><span>=</span><span><span> </span><span>window</span><span>.</span></span><span>innerHeight</span><span>;</span></div></div><div><div><div>36</div></div><div><span><span>      </span></span><span>canvas</span><span>.</span><span>style</span><span>.</span><span>cssText</span><span> </span><span>=</span></div></div><div><div><div>37</div></div><div><span>        </span><span>"position:fixed;top:0;left:0;pointer-events:none;z-index:999999"</span><span>;</span></div></div><div><div><div>38</div></div><div><span><span>      </span></span><span>window</span><span>.</span><span>addEventListener</span><span>(</span><span>"resize"</span><span>, </span><span>function</span><span> () {</span></div></div><div><div><div>39</div></div><div><span><span>        </span></span><span>canvas</span><span>.</span><span>width</span><span> </span><span>=</span><span><span> </span><span>window</span><span>.</span></span><span>innerWidth</span><span>;</span></div></div><div><div><div>40</div></div><div><span><span>        </span></span><span>canvas</span><span>.</span><span>height</span><span> </span><span>=</span><span><span> </span><span>window</span><span>.</span></span><span>innerHeight</span><span>;</span></div></div><div><div><div>41</div></div><div><span><span>      </span></span><span>});</span></div></div><div><div><div>42</div></div><div><span><span>      </span></span><span>document</span><span>.</span><span>body</span><span>.</span><span>appendChild</span><span><span>(</span><span>canvas</span><span>);</span></span></div></div><div><div><div>43</div></div><div><span>      </span><span>var</span><span><span> </span><span>context</span><span> </span></span><span>=</span><span><span> </span><span>canvas</span><span>.</span></span><span>getContext</span><span>(</span><span>"2d"</span><span>);</span></div></div><div><div><div>44</div></div><div><span>      </span><span>var</span><span><span> </span><span>particles</span><span> </span></span><span>=</span><span> [];</span></div></div><div><div><div>45</div></div><div><span>      </span><span>var</span><span><span> </span><span>particlePointer</span><span> </span></span><span>=</span><span> </span><span>0</span><span>;</span></div></div><div><div><div>46</div></div><div><span>      </span><span>var</span><span><span> </span><span>frames</span><span> </span></span><span>=</span><span> </span><span>120</span><span>;</span></div></div><div><div><div>47</div></div><div><span>      </span><span>var</span><span><span> </span><span>framesRemain</span><span> </span></span><span>=</span><span><span> </span><span>frames</span><span>;</span></span></div></div><div><div><div>48</div></div><div><span>      </span><span>var</span><span><span> </span><span>rendering</span><span> </span></span><span>=</span><span> </span><span>false</span><span>;</span></div></div><div><div><div>49</div></div><div><span>      </span><span>POWERMODE</span><span>.</span><span>shake</span><span> </span><span>=</span><span> </span><span>true</span><span>;</span></div></div><div><div><div>50</div></div><div>
</div></div><div><div><div>51</div></div><div><span>      </span><span>function</span><span> </span><span>getRandom</span><span><span>(</span><span>min</span><span>, </span><span>max</span><span>) {</span></span></div></div><div><div><div>52</div></div><div><span>        </span><span>return</span><span><span> </span><span>Math</span><span>.</span></span><span>random</span><span>() </span><span>*</span><span><span> (</span><span>max</span><span> </span></span><span>-</span><span><span> </span><span>min</span><span>) </span></span><span>+</span><span><span> </span><span>min</span><span>;</span></span></div></div><div><div><div>53</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>54</div></div><div><span>      </span><span>function</span><span> </span><span>getColor</span><span><span>(</span><span>el</span><span>) {</span></span></div></div><div><div><div>55</div></div><div><span>        </span><span>if</span><span> (</span><span>POWERMODE</span><span>.</span><span>colorful</span><span>) {</span></div></div><div><div><div>56</div></div><div><span>          </span><span>var</span><span><span> </span><span>u</span><span> </span></span><span>=</span><span> </span><span>getRandom</span><span>(</span><span>0</span><span>, </span><span>360</span><span>);</span></div></div><div><div><div>57</div></div><div><span>          </span><span>return</span><span> (</span></div></div><div><div><div>58</div></div><div><span>            </span><span>"hsla("</span><span> </span><span>+</span></div></div><div><div><div>59</div></div><div><span>            </span><span>getRandom</span><span><span>(</span><span>u</span><span> </span></span><span>-</span><span> </span><span>10</span><span><span>, </span><span>u</span><span> </span></span><span>+</span><span> </span><span>10</span><span>) </span><span>+</span></div></div><div><div><div>60</div></div><div><span>            </span><span>", 100%, "</span><span> </span><span>+</span></div></div><div><div><div>61</div></div><div><span>            </span><span>getRandom</span><span>(</span><span>50</span><span>, </span><span>80</span><span>) </span><span>+</span></div></div><div><div><div>62</div></div><div><span>            </span><span>"%, "</span><span> </span><span>+</span></div></div><div><div><div>63</div></div><div><span>            </span><span>1</span><span> </span><span>+</span></div></div><div><div><div>64</div></div><div><span>            </span><span>")"</span></div></div><div><div><div>65</div></div><div><span><span>          </span></span><span>);</span></div></div><div><div><div>66</div></div><div><span><span>        </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>67</div></div><div><span>          </span><span>return</span><span><span> </span><span>window</span><span>.</span></span><span>getComputedStyle</span><span><span>(</span><span>el</span><span>).</span></span><span>color</span><span>;</span></div></div><div><div><div>68</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>69</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>70</div></div><div><span>      </span><span>function</span><span> </span><span>getCaret</span><span>() {</span></div></div><div><div><div>71</div></div><div><span>        </span><span>var</span><span><span> </span><span>el</span><span> </span></span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>activeElement</span><span>;</span></div></div><div><div><div>72</div></div><div><span>        </span><span>var</span><span><span> </span><span>bcr</span><span>;</span></span></div></div><div><div><div>73</div></div><div><span>        </span><span>if</span><span> (</span></div></div><div><div><div>74</div></div><div><span><span>          </span></span><span>el</span><span>.</span><span>tagName</span><span> </span><span>===</span><span> </span><span>"TEXTAREA"</span><span> </span><span>||</span></div></div><div><div><div>75</div></div><div><span><span>          </span></span><span>(</span><span>el</span><span>.</span><span>tagName</span><span> </span><span>===</span><span> </span><span>"INPUT"</span><span> </span><span>&amp;&amp;</span><span><span> </span><span>el</span><span>.</span></span><span>getAttribute</span><span>(</span><span>"type"</span><span>) </span><span>===</span><span> </span><span>"text"</span><span>)</span></div></div><div><div><div>76</div></div><div><span><span>        </span></span><span>) {</span></div></div><div><div><div>77</div></div><div><span>          </span><span>var</span><span><span> </span><span>offset</span><span> </span></span><span>=</span><span> </span><span>__webpack_require__</span><span>(</span><span>1</span><span><span>)(</span><span>el</span><span>, </span><span>el</span><span>.</span></span><span>selectionStart</span><span>);</span></div></div><div><div><div>78</div></div><div><span><span>          </span></span><span>bcr</span><span> </span><span>=</span><span><span> </span><span>el</span><span>.</span></span><span>getBoundingClientRect</span><span>();</span></div></div><div><div><div>79</div></div><div><span>          </span><span>return</span><span> {</span></div></div><div><div><div>80</div></div><div><span>            </span><span>x</span><span>:</span><span><span> </span><span>offset</span><span>.</span></span><span>left</span><span> </span><span>+</span><span><span> </span><span>bcr</span><span>.</span></span><span>left</span><span>,</span></div></div><div><div><div>81</div></div><div><span>            </span><span>y</span><span>:</span><span><span> </span><span>offset</span><span>.</span></span><span>top</span><span> </span><span>+</span><span><span> </span><span>bcr</span><span>.</span></span><span>top</span><span>,</span></div></div><div><div><div>82</div></div><div><span>            </span><span>color</span><span>:</span><span> </span><span>getColor</span><span><span>(</span><span>el</span><span>),</span></span></div></div><div><div><div>83</div></div><div><span><span>          </span></span><span>};</span></div></div><div><div><div>84</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>85</div></div><div><span>        </span><span>var</span><span><span> </span><span>selection</span><span> </span></span><span>=</span><span><span> </span><span>window</span><span>.</span></span><span>getSelection</span><span>();</span></div></div><div><div><div>86</div></div><div><span>        </span><span>if</span><span><span> (</span><span>selection</span><span>.</span></span><span>rangeCount</span><span>) {</span></div></div><div><div><div>87</div></div><div><span>          </span><span>var</span><span><span> </span><span>range</span><span> </span></span><span>=</span><span><span> </span><span>selection</span><span>.</span></span><span>getRangeAt</span><span>(</span><span>0</span><span>);</span></div></div><div><div><div>88</div></div><div><span>          </span><span>var</span><span><span> </span><span>startNode</span><span> </span></span><span>=</span><span><span> </span><span>range</span><span>.</span></span><span>startContainer</span><span>;</span></div></div><div><div><div>89</div></div><div><span>          </span><span>if</span><span><span> (</span><span>startNode</span><span>.</span></span><span>nodeType</span><span> </span><span>===</span><span><span> </span><span>document</span><span>.</span></span><span>TEXT_NODE</span><span>) {</span></div></div><div><div><div>90</div></div><div><span><span>            </span></span><span>startNode</span><span> </span><span>=</span><span><span> </span><span>startNode</span><span>.</span></span><span>parentNode</span><span>;</span></div></div><div><div><div>91</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>92</div></div><div><span><span>          </span></span><span>bcr</span><span> </span><span>=</span><span><span> </span><span>range</span><span>.</span></span><span>getBoundingClientRect</span><span>();</span></div></div><div><div><div>93</div></div><div><span>          </span><span>return</span><span> {</span></div></div><div><div><div>94</div></div><div><span>            </span><span>x</span><span>:</span><span><span> </span><span>bcr</span><span>.</span></span><span>left</span><span>,</span></div></div><div><div><div>95</div></div><div><span>            </span><span>y</span><span>:</span><span><span> </span><span>bcr</span><span>.</span></span><span>top</span><span>,</span></div></div><div><div><div>96</div></div><div><span>            </span><span>color</span><span>:</span><span> </span><span>getColor</span><span><span>(</span><span>startNode</span><span>),</span></span></div></div><div><div><div>97</div></div><div><span><span>          </span></span><span>};</span></div></div><div><div><div>98</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>99</div></div><div><span>        </span><span>return</span><span> {</span></div></div><div><div><div>100</div></div><div><span>          </span><span>x</span><span>:</span><span> </span><span>0</span><span>,</span></div></div><div><div><div>101</div></div><div><span>          </span><span>y</span><span>:</span><span> </span><span>0</span><span>,</span></div></div><div><div><div>102</div></div><div><span>          </span><span>color</span><span>:</span><span> </span><span>"transparent"</span><span>,</span></div></div><div><div><div>103</div></div><div><span><span>        </span></span><span>};</span></div></div><div><div><div>104</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>105</div></div><div><span>      </span><span>function</span><span> </span><span>createParticle</span><span><span>(</span><span>x</span><span>, </span><span>y</span><span>, </span><span>color</span><span>) {</span></span></div></div><div><div><div>106</div></div><div><span>        </span><span>return</span><span> {</span></div></div><div><div><div>107</div></div><div><span>          </span><span>x</span><span>:</span><span><span> </span><span>x</span><span>,</span></span></div></div><div><div><div>108</div></div><div><span>          </span><span>y</span><span>:</span><span><span> </span><span>y</span><span>,</span></span></div></div><div><div><div>109</div></div><div><span>          </span><span>alpha</span><span>:</span><span> </span><span>1</span><span>,</span></div></div><div><div><div>110</div></div><div><span>          </span><span>color</span><span>:</span><span><span> </span><span>color</span><span>,</span></span></div></div><div><div><div>111</div></div><div><span>          </span><span>velocity</span><span>:</span><span> {</span></div></div><div><div><div>112</div></div><div><span>            </span><span>x</span><span>:</span><span> </span><span>-</span><span>1</span><span> </span><span>+</span><span><span> </span><span>Math</span><span>.</span></span><span>random</span><span>() </span><span>*</span><span> </span><span>2</span><span>,</span></div></div><div><div><div>113</div></div><div><span>            </span><span>y</span><span>:</span><span> </span><span>-</span><span>3.5</span><span> </span><span>+</span><span><span> </span><span>Math</span><span>.</span></span><span>random</span><span>() </span><span>*</span><span> </span><span>2</span><span>,</span></div></div><div><div><div>114</div></div><div><span><span>          </span></span><span>},</span></div></div><div><div><div>115</div></div><div><span><span>        </span></span><span>};</span></div></div><div><div><div>116</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>117</div></div><div><span>      </span><span>function</span><span> </span><span>POWERMODE</span><span>() {</span></div></div><div><div><div>118</div></div><div><span><span>        </span></span><span>{</span></div></div><div><div><div>119</div></div><div><span>          </span><span>var</span><span><span> </span><span>caret</span><span> </span></span><span>=</span><span> </span><span>getCaret</span><span>();</span></div></div><div><div><div>120</div></div><div><span>          </span><span>var</span><span><span> </span><span>numParticles</span><span> </span></span><span>=</span><span> </span><span>5</span><span> </span><span>+</span><span><span> </span><span>Math</span><span>.</span></span><span>round</span><span><span>(</span><span>Math</span><span>.</span></span><span>random</span><span>() </span><span>*</span><span> </span><span>10</span><span>);</span></div></div><div><div><div>121</div></div><div><span>          </span><span>while</span><span><span> (</span><span>numParticles</span></span><span>--</span><span>) {</span></div></div><div><div><div>122</div></div><div><span><span>            </span></span><span>particles</span><span>[</span><span>particlePointer</span><span>] </span><span>=</span><span> </span><span>createParticle</span><span>(</span></div></div><div><div><div>123</div></div><div><span><span>              </span></span><span>caret</span><span>.</span><span>x</span><span>,</span></div></div><div><div><div>124</div></div><div><span><span>              </span></span><span>caret</span><span>.</span><span>y</span><span>,</span></div></div><div><div><div>125</div></div><div><span><span>              </span></span><span>caret</span><span>.</span><span>color</span><span>,</span></div></div><div><div><div>126</div></div><div><span><span>            </span></span><span>);</span></div></div><div><div><div>127</div></div><div><span><span>            </span></span><span>particlePointer</span><span> </span><span>=</span><span><span> (</span><span>particlePointer</span><span> </span></span><span>+</span><span> </span><span>1</span><span>) </span><span>%</span><span> </span><span>500</span><span>;</span></div></div><div><div><div>128</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>129</div></div><div><span><span>          </span></span><span>framesRemain</span><span> </span><span>=</span><span><span> </span><span>frames</span><span>;</span></span></div></div><div><div><div>130</div></div><div><span>          </span><span>if</span><span> (</span><span>!</span><span><span>rendering</span><span>) {</span></span></div></div><div><div><div>131</div></div><div><span>            </span><span>requestAnimationFrame</span><span><span>(</span><span>loop</span><span>);</span></span></div></div><div><div><div>132</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>133</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>134</div></div><div><span><span>        </span></span><span>{</span></div></div><div><div><div>135</div></div><div><span>          </span><span>if</span><span> (</span><span>POWERMODE</span><span>.</span><span>shake</span><span>) {</span></div></div><div><div><div>136</div></div><div><span>            </span><span>var</span><span><span> </span><span>intensity</span><span> </span></span><span>=</span><span> </span><span>1</span><span> </span><span>+</span><span> </span><span>2</span><span> </span><span>*</span><span><span> </span><span>Math</span><span>.</span></span><span>random</span><span>();</span></div></div><div><div><div>137</div></div><div><span>            </span><span>var</span><span><span> </span><span>x</span><span> </span></span><span>=</span><span><span> </span><span>intensity</span><span> </span></span><span>*</span><span><span> (</span><span>Math</span><span>.</span></span><span>random</span><span>() </span><span>&gt;</span><span> </span><span>0.5</span><span> </span><span>?</span><span> </span><span>-</span><span>1</span><span> </span><span>:</span><span> </span><span>1</span><span>);</span></div></div><div><div><div>138</div></div><div><span>            </span><span>var</span><span><span> </span><span>y</span><span> </span></span><span>=</span><span><span> </span><span>intensity</span><span> </span></span><span>*</span><span><span> (</span><span>Math</span><span>.</span></span><span>random</span><span>() </span><span>&gt;</span><span> </span><span>0.5</span><span> </span><span>?</span><span> </span><span>-</span><span>1</span><span> </span><span>:</span><span> </span><span>1</span><span>);</span></div></div><div><div><div>139</div></div><div><span><span>            </span></span><span>document</span><span>.</span><span>body</span><span>.</span><span>style</span><span>.</span><span>marginLeft</span><span> </span><span>=</span><span><span> </span><span>x</span><span> </span></span><span>+</span><span> </span><span>"px"</span><span>;</span></div></div><div><div><div>140</div></div><div><span><span>            </span></span><span>document</span><span>.</span><span>body</span><span>.</span><span>style</span><span>.</span><span>marginTop</span><span> </span><span>=</span><span><span> </span><span>y</span><span> </span></span><span>+</span><span> </span><span>"px"</span><span>;</span></div></div><div><div><div>141</div></div><div><span>            </span><span>setTimeout</span><span>(</span><span>function</span><span> () {</span></div></div><div><div><div>142</div></div><div><span><span>              </span></span><span>document</span><span>.</span><span>body</span><span>.</span><span>style</span><span>.</span><span>marginLeft</span><span> </span><span>=</span><span> </span><span>""</span><span>;</span></div></div><div><div><div>143</div></div><div><span><span>              </span></span><span>document</span><span>.</span><span>body</span><span>.</span><span>style</span><span>.</span><span>marginTop</span><span> </span><span>=</span><span> </span><span>""</span><span>;</span></div></div><div><div><div>144</div></div><div><span><span>            </span></span><span>}, </span><span>75</span><span>);</span></div></div><div><div><div>145</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>146</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>147</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>148</div></div><div><span>      </span><span>POWERMODE</span><span>.</span><span>colorful</span><span> </span><span>=</span><span> </span><span>false</span><span>;</span></div></div><div><div><div>149</div></div><div>
</div></div><div><div><div>150</div></div><div><span>      </span><span>function</span><span> </span><span>loop</span><span>() {</span></div></div><div><div><div>151</div></div><div><span>        </span><span>if</span><span><span> (</span><span>framesRemain</span><span> </span></span><span>&gt;</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>152</div></div><div><span>          </span><span>requestAnimationFrame</span><span><span>(</span><span>loop</span><span>);</span></span></div></div><div><div><div>153</div></div><div><span><span>          </span></span><span>framesRemain</span><span>--</span><span>;</span></div></div><div><div><div>154</div></div><div><span><span>          </span></span><span>rendering</span><span> </span><span>=</span><span> </span><span>true</span><span>;</span></div></div><div><div><div>155</div></div><div><span><span>        </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>156</div></div><div><span><span>          </span></span><span>rendering</span><span> </span><span>=</span><span> </span><span>false</span><span>;</span></div></div><div><div><div>157</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>158</div></div><div><span><span>        </span></span><span>context</span><span>.</span><span>clearRect</span><span>(</span><span>0</span><span>, </span><span>0</span><span><span>, </span><span>canvas</span><span>.</span></span><span>width</span><span><span>, </span><span>canvas</span><span>.</span></span><span>height</span><span>);</span></div></div><div><div><div>159</div></div><div><span>        </span><span>for</span><span> (</span><span>var</span><span><span> </span><span>i</span><span> </span></span><span>=</span><span> </span><span>0</span><span><span>; </span><span>i</span><span> </span></span><span>&lt;</span><span><span> </span><span>particles</span><span>.</span></span><span>length</span><span>; </span><span>++</span><span><span>i</span><span>) {</span></span></div></div><div><div><div>160</div></div><div><span>          </span><span>var</span><span><span> </span><span>particle</span><span> </span></span><span>=</span><span><span> </span><span>particles</span><span>[</span><span>i</span><span>];</span></span></div></div><div><div><div>161</div></div><div><span>          </span><span>if</span><span><span> (</span><span>particle</span><span>.</span></span><span>alpha</span><span> </span><span>&lt;=</span><span> </span><span>0.1</span><span>) </span><span>continue</span><span>;</span></div></div><div><div><div>162</div></div><div><span><span>          </span></span><span>particle</span><span>.</span><span>velocity</span><span>.</span><span>y</span><span> </span><span>+=</span><span> </span><span>0.075</span><span>;</span></div></div><div><div><div>163</div></div><div><span><span>          </span></span><span>particle</span><span>.</span><span>x</span><span> </span><span>+=</span><span><span> </span><span>particle</span><span>.</span></span><span>velocity</span><span>.</span><span>x</span><span>;</span></div></div><div><div><div>164</div></div><div><span><span>          </span></span><span>particle</span><span>.</span><span>y</span><span> </span><span>+=</span><span><span> </span><span>particle</span><span>.</span></span><span>velocity</span><span>.</span><span>y</span><span>;</span></div></div><div><div><div>165</div></div><div><span><span>          </span></span><span>particle</span><span>.</span><span>alpha</span><span> </span><span>*=</span><span> </span><span>0.96</span><span>;</span></div></div><div><div><div>166</div></div><div><span><span>          </span></span><span>context</span><span>.</span><span>globalAlpha</span><span> </span><span>=</span><span><span> </span><span>particle</span><span>.</span></span><span>alpha</span><span>;</span></div></div><div><div><div>167</div></div><div><span><span>          </span></span><span>context</span><span>.</span><span>fillStyle</span><span> </span><span>=</span><span><span> </span><span>particle</span><span>.</span></span><span>color</span><span>;</span></div></div><div><div><div>168</div></div><div><span><span>          </span></span><span>context</span><span>.</span><span>fillRect</span><span>(</span></div></div><div><div><div>169</div></div><div><span><span>            </span></span><span>Math</span><span>.</span><span>round</span><span><span>(</span><span>particle</span><span>.</span></span><span>x</span><span> </span><span>-</span><span> </span><span>1.5</span><span>),</span></div></div><div><div><div>170</div></div><div><span><span>            </span></span><span>Math</span><span>.</span><span>round</span><span><span>(</span><span>particle</span><span>.</span></span><span>y</span><span> </span><span>-</span><span> </span><span>1.5</span><span>),</span></div></div><div><div><div>171</div></div><div><span>            </span><span>3</span><span>,</span></div></div><div><div><div>172</div></div><div><span>            </span><span>3</span><span>,</span></div></div><div><div><div>173</div></div><div><span><span>          </span></span><span>);</span></div></div><div><div><div>174</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>175</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>176</div></div><div><span>      </span><span>requestAnimationFrame</span><span><span>(</span><span>loop</span><span>);</span></span></div></div><div><div><div>177</div></div><div><span>      </span><span>module</span><span>.</span><span>exports</span><span> </span><span>=</span><span> </span><span>POWERMODE</span><span>;</span></div></div><div><div><div>178</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>179</div></div><div><span>    </span><span>function</span><span><span> (</span><span>module</span><span>, </span><span>exports</span><span>) {</span></span></div></div><div><div><div>180</div></div><div><span><span>      </span></span><span>(</span><span>function</span><span> () {</span></div></div><div><div><div>181</div></div><div><span>        </span><span>var</span><span><span> </span><span>properties</span><span> </span></span><span>=</span><span> [</span></div></div><div><div><div>182</div></div><div><span>          </span><span>"direction"</span><span>,</span></div></div><div><div><div>183</div></div><div><span>          </span><span>"boxSizing"</span><span>,</span></div></div><div><div><div>184</div></div><div><span>          </span><span>"width"</span><span>,</span></div></div><div><div><div>185</div></div><div><span>          </span><span>"height"</span><span>,</span></div></div><div><div><div>186</div></div><div><span>          </span><span>"overflowX"</span><span>,</span></div></div><div><div><div>187</div></div><div><span>          </span><span>"overflowY"</span><span>,</span></div></div><div><div><div>188</div></div><div><span>          </span><span>"borderTopWidth"</span><span>,</span></div></div><div><div><div>189</div></div><div><span>          </span><span>"borderRightWidth"</span><span>,</span></div></div><div><div><div>190</div></div><div><span>          </span><span>"borderBottomWidth"</span><span>,</span></div></div><div><div><div>191</div></div><div><span>          </span><span>"borderLeftWidth"</span><span>,</span></div></div><div><div><div>192</div></div><div><span>          </span><span>"borderStyle"</span><span>,</span></div></div><div><div><div>193</div></div><div><span>          </span><span>"paddingTop"</span><span>,</span></div></div><div><div><div>194</div></div><div><span>          </span><span>"paddingRight"</span><span>,</span></div></div><div><div><div>195</div></div><div><span>          </span><span>"paddingBottom"</span><span>,</span></div></div><div><div><div>196</div></div><div><span>          </span><span>"paddingLeft"</span><span>,</span></div></div><div><div><div>197</div></div><div><span>          </span><span>"fontStyle"</span><span>,</span></div></div><div><div><div>198</div></div><div><span>          </span><span>"fontVariant"</span><span>,</span></div></div><div><div><div>199</div></div><div><span>          </span><span>"fontWeight"</span><span>,</span></div></div><div><div><div>200</div></div><div><span>          </span><span>"fontStretch"</span><span>,</span></div></div><div><div><div>201</div></div><div><span>          </span><span>"fontSize"</span><span>,</span></div></div><div><div><div>202</div></div><div><span>          </span><span>"fontSizeAdjust"</span><span>,</span></div></div><div><div><div>203</div></div><div><span>          </span><span>"lineHeight"</span><span>,</span></div></div><div><div><div>204</div></div><div><span>          </span><span>"fontFamily"</span><span>,</span></div></div><div><div><div>205</div></div><div><span>          </span><span>"textAlign"</span><span>,</span></div></div><div><div><div>206</div></div><div><span>          </span><span>"textTransform"</span><span>,</span></div></div><div><div><div>207</div></div><div><span>          </span><span>"textIndent"</span><span>,</span></div></div><div><div><div>208</div></div><div><span>          </span><span>"textDecoration"</span><span>,</span></div></div><div><div><div>209</div></div><div><span>          </span><span>"letterSpacing"</span><span>,</span></div></div><div><div><div>210</div></div><div><span>          </span><span>"wordSpacing"</span><span>,</span></div></div><div><div><div>211</div></div><div><span>          </span><span>"tabSize"</span><span>,</span></div></div><div><div><div>212</div></div><div><span>          </span><span>"MozTabSize"</span><span>,</span></div></div><div><div><div>213</div></div><div><span><span>        </span></span><span>];</span></div></div><div><div><div>214</div></div><div><span>        </span><span>var</span><span><span> </span><span>isFirefox</span><span> </span></span><span>=</span><span><span> </span><span>window</span><span>.</span></span><span>mozInnerScreenX</span><span> </span><span>!=</span><span> </span><span>null</span><span>;</span></div></div><div><div><div>215</div></div><div>
</div></div><div><div><div>216</div></div><div><span>        </span><span>function</span><span> </span><span>getCaretCoordinates</span><span><span>(</span><span>element</span><span>, </span><span>position</span><span>, </span><span>options</span><span>) {</span></span></div></div><div><div><div>217</div></div><div><span>          </span><span>var</span><span><span> </span><span>debug</span><span> </span></span><span>=</span><span><span> (</span><span>options</span><span> </span></span><span>&amp;&amp;</span><span><span> </span><span>options</span><span>.</span></span><span>debug</span><span>) </span><span>||</span><span> </span><span>false</span><span>;</span></div></div><div><div><div>218</div></div><div><span>          </span><span>if</span><span><span> (</span><span>debug</span><span>) {</span></span></div></div><div><div><div>219</div></div><div><span>            </span><span>var</span><span><span> </span><span>el</span><span> </span></span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>querySelector</span><span>(</span></div></div><div><div><div>220</div></div><div><span>              </span><span>"#input-textarea-caret-position-mirror-div"</span><span>,</span></div></div><div><div><div>221</div></div><div><span><span>            </span></span><span>);</span></div></div><div><div><div>222</div></div><div><span>            </span><span>if</span><span><span> (</span><span>el</span><span>) {</span></span></div></div><div><div><div>223</div></div><div><span><span>              </span></span><span>el</span><span>.</span><span>parentNode</span><span>.</span><span>removeChild</span><span><span>(</span><span>el</span><span>);</span></span></div></div><div><div><div>224</div></div><div><span><span>            </span></span><span>}</span></div></div><div><div><div>225</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>226</div></div><div><span>          </span><span>var</span><span><span> </span><span>div</span><span> </span></span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>createElement</span><span>(</span><span>"div"</span><span>);</span></div></div><div><div><div>227</div></div><div><span><span>          </span></span><span>div</span><span>.</span><span>id</span><span> </span><span>=</span><span> </span><span>"input-textarea-caret-position-mirror-div"</span><span>;</span></div></div><div><div><div>228</div></div><div><span><span>          </span></span><span>document</span><span>.</span><span>body</span><span>.</span><span>appendChild</span><span><span>(</span><span>div</span><span>);</span></span></div></div><div><div><div>229</div></div><div><span>          </span><span>var</span><span><span> </span><span>style</span><span> </span></span><span>=</span><span><span> </span><span>div</span><span>.</span></span><span>style</span><span>;</span></div></div><div><div><div>230</div></div><div><span>          </span><span>var</span><span><span> </span><span>computed</span><span> </span></span><span>=</span><span><span> </span><span>window</span><span>.</span></span><span>getComputedStyle</span></div></div><div><div><div>231</div></div><div><span>            </span><span>?</span><span> </span><span>getComputedStyle</span><span><span>(</span><span>element</span><span>)</span></span></div></div><div><div><div>232</div></div><div><span>            </span><span>:</span><span><span> </span><span>element</span><span>.</span></span><span>currentStyle</span><span>;</span></div></div><div><div><div>233</div></div><div><span><span>          </span></span><span>style</span><span>.</span><span>whiteSpace</span><span> </span><span>=</span><span> </span><span>"pre-wrap"</span><span>;</span></div></div><div><div><div>234</div></div><div><span>          </span><span>if</span><span><span> (</span><span>element</span><span>.</span></span><span>nodeName</span><span> </span><span>!==</span><span> </span><span>"INPUT"</span><span><span>) </span><span>style</span><span>.</span></span><span>wordWrap</span><span> </span><span>=</span><span> </span><span>"break-word"</span><span>;</span></div></div><div><div><div>235</div></div><div><span><span>          </span></span><span>style</span><span>.</span><span>position</span><span> </span><span>=</span><span> </span><span>"absolute"</span><span>;</span></div></div><div><div><div>236</div></div><div><span>          </span><span>if</span><span> (</span><span>!</span><span><span>debug</span><span>) </span><span>style</span><span>.</span></span><span>visibility</span><span> </span><span>=</span><span> </span><span>"hidden"</span><span>;</span></div></div><div><div><div>237</div></div><div><span><span>          </span></span><span>properties</span><span>.</span><span>forEach</span><span>(</span><span>function</span><span><span> (</span><span>prop</span><span>) {</span></span></div></div><div><div><div>238</div></div><div><span><span>            </span></span><span>style</span><span>[</span><span>prop</span><span>] </span><span>=</span><span><span> </span><span>computed</span><span>[</span><span>prop</span><span>];</span></span></div></div><div><div><div>239</div></div><div><span><span>          </span></span><span>});</span></div></div><div><div><div>240</div></div><div><span>          </span><span>if</span><span><span> (</span><span>isFirefox</span><span>) {</span></span></div></div><div><div><div>241</div></div><div><span>            </span><span>if</span><span><span> (</span><span>element</span><span>.</span></span><span>scrollHeight</span><span> </span><span>&gt;</span><span> </span><span>parseInt</span><span><span>(</span><span>computed</span><span>.</span></span><span>height</span><span>))</span></div></div><div><div><div>242</div></div><div><span><span>              </span></span><span>style</span><span>.</span><span>overflowY</span><span> </span><span>=</span><span> </span><span>"scroll"</span><span>;</span></div></div><div><div><div>243</div></div><div><span><span>          </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>244</div></div><div><span><span>            </span></span><span>style</span><span>.</span><span>overflow</span><span> </span><span>=</span><span> </span><span>"hidden"</span><span>;</span></div></div><div><div><div>245</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>246</div></div><div><span><span>          </span></span><span>div</span><span>.</span><span>textContent</span><span> </span><span>=</span><span><span> </span><span>element</span><span>.</span></span><span>value</span><span>.</span><span>substring</span><span>(</span><span>0</span><span><span>, </span><span>position</span><span>);</span></span></div></div><div><div><div>247</div></div><div><span>          </span><span>if</span><span><span> (</span><span>element</span><span>.</span></span><span>nodeName</span><span> </span><span>===</span><span> </span><span>"INPUT"</span><span>)</span></div></div><div><div><div>248</div></div><div><span><span>            </span></span><span>div</span><span>.</span><span>textContent</span><span> </span><span>=</span><span><span> </span><span>div</span><span>.</span></span><span>textContent</span><span>.</span><span>replace</span><span>(</span><span>/</span><span>\s</span><span>/</span><span>g</span><span>, </span><span>"</span><span>\u00a0</span><span>"</span><span>);</span></div></div><div><div><div>249</div></div><div><span>          </span><span>var</span><span><span> </span><span>span</span><span> </span></span><span>=</span><span><span> </span><span>document</span><span>.</span></span><span>createElement</span><span>(</span><span>"span"</span><span>);</span></div></div><div><div><div>250</div></div><div><span><span>          </span></span><span>span</span><span>.</span><span>textContent</span><span> </span><span>=</span><span><span> </span><span>element</span><span>.</span></span><span>value</span><span>.</span><span>substring</span><span><span>(</span><span>position</span><span>) </span></span><span>||</span><span> </span><span>"."</span><span>;</span></div></div><div><div><div>251</div></div><div><span><span>          </span></span><span>div</span><span>.</span><span>appendChild</span><span><span>(</span><span>span</span><span>);</span></span></div></div><div><div><div>252</div></div><div><span>          </span><span>var</span><span><span> </span><span>coordinates</span><span> </span></span><span>=</span><span> {</span></div></div><div><div><div>253</div></div><div><span>            </span><span>top</span><span>:</span><span><span> </span><span>span</span><span>.</span></span><span>offsetTop</span><span> </span><span>+</span><span> </span><span>parseInt</span><span><span>(</span><span>computed</span><span>[</span></span><span>"borderTopWidth"</span><span>]),</span></div></div><div><div><div>254</div></div><div><span>            </span><span>left</span><span>:</span><span><span> </span><span>span</span><span>.</span></span><span>offsetLeft</span><span> </span><span>+</span><span> </span><span>parseInt</span><span><span>(</span><span>computed</span><span>[</span></span><span>"borderLeftWidth"</span><span>]),</span></div></div><div><div><div>255</div></div><div><span><span>          </span></span><span>};</span></div></div><div><div><div>256</div></div><div><span>          </span><span>if</span><span><span> (</span><span>debug</span><span>) {</span></span></div></div><div><div><div>257</div></div><div><span><span>            </span></span><span>span</span><span>.</span><span>style</span><span>.</span><span>backgroundColor</span><span> </span><span>=</span><span> </span><span>"#aaa"</span><span>;</span></div></div><div><div><div>258</div></div><div><span><span>          </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>259</div></div><div><span><span>            </span></span><span>document</span><span>.</span><span>body</span><span>.</span><span>removeChild</span><span><span>(</span><span>div</span><span>);</span></span></div></div><div><div><div>260</div></div><div><span><span>          </span></span><span>}</span></div></div><div><div><div>261</div></div><div><span>          </span><span>return</span><span><span> </span><span>coordinates</span><span>;</span></span></div></div><div><div><div>262</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>263</div></div><div><span>        </span><span>if</span><span> (</span></div></div><div><div><div>264</div></div><div><span>          </span><span>typeof</span><span> </span><span>module</span><span> </span><span>!=</span><span> </span><span>"undefined"</span><span> </span><span>&amp;&amp;</span></div></div><div><div><div>265</div></div><div><span>          </span><span>typeof</span><span> </span><span>module</span><span>.</span><span>exports</span><span> </span><span>!=</span><span> </span><span>"undefined"</span></div></div><div><div><div>266</div></div><div><span><span>        </span></span><span>) {</span></div></div><div><div><div>267</div></div><div><span>          </span><span>module</span><span>.</span><span>exports</span><span> </span><span>=</span><span><span> </span><span>getCaretCoordinates</span><span>;</span></span></div></div><div><div><div>268</div></div><div><span><span>        </span></span><span>} </span><span>else</span><span> {</span></div></div><div><div><div>269</div></div><div><span><span>          </span></span><span>window</span><span>.</span><span>getCaretCoordinates</span><span> </span><span>=</span><span><span> </span><span>getCaretCoordinates</span><span>;</span></span></div></div><div><div><div>270</div></div><div><span><span>        </span></span><span>}</span></div></div><div><div><div>271</div></div><div><span><span>      </span></span><span>})();</span></div></div><div><div><div>272</div></div><div><span><span>    </span></span><span>},</span></div></div><div><div><div>273</div></div><div><span><span>  </span></span><span>]);</span></div></div><div><div><div>274</div></div><div><span>});</span></div></div><div><div><div>275</div></div><div><span>POWERMODE</span><span>.</span><span>colorful</span><span> </span><span>=</span><span> </span><span>true</span><span>; </span><span>// make power mode colorful</span></div></div><div><div><div>276</div></div><div><span>POWERMODE</span><span>.</span><span>shake</span><span> </span><span>=</span><span> </span><span>false</span><span>; </span><span>// turn off shake</span></div></div><div><div><div>277</div></div><div><span><span>document</span><span>.</span></span><span>body</span><span>.</span><span>addEventListener</span><span>(</span><span>"input"</span><span>, </span><span>POWERMODE</span><span>);</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section>
<section><h2>引用<a href="#引用"><span>#</span></a></h2><p>此脚本相较原始有些许改进。</p><p>转载自 <a href="https://typecho.linyezhandidi.com/Website-design/Comment-typing-typing-effects.html" target="_blank">林叶展弟弟 - 评论输入框打字特效</a>
原始来源 <a href="https://qqdie.com/archives/to-share-the-typing-effect-of-an-input-box.html" target="_blank">QQ爹の博客 - 分享一个输入框的打字特效</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/comment2wechat/</id>
      <title type="text">[Typecho插件] 新评论微信提醒 Comment2Wechat V2.0</title>
      <published>2017-10-19T17:38:00.000Z</published>
      <updated>2020-03-09T11:47:41.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/comment2wechat/"/>
      <summary type="text">Comment2Wechat 一个 Typecho 评论微信提醒插件，修改自原版本，增加了一些功能以及设置。使用了 Easy 大大的开源项目 serverchan。</summary>
      <content type="html"><![CDATA[<hr />
<p>一个 Typecho 评论微信提醒插件，修改自原版本，增加了一些功能以及设置。使用了 Easy 大大的开源项目 serverchan。</p>
<section><h2>功能<a href="#功能"><span>#</span></a></h2><p>每当有人评论你的文章时，可以通过 Server酱 推送到你的微信上。
相比原插件新增了两个功能设置：</p><ol>
<li>当评论者为自己时不提醒</li>
<li>使用 HTTPS 与 Server酱 进行通信</li>
</ol><p></p><figure><img src="/usr/uploads/2017/10/1645816248.png" alt="Comment2Wechat" /><figcaption>Comment2Wechat</figcaption></figure><p></p></section>
<section><h2>下载<a href="#下载"><span>#</span></a></h2><ul>
<li><a href="/usr/uploads/2017/10/189493532.zip">直接下载</a></li>
<li><a href="https://github.com/Tsuk1ko/Comment2Wechat/archive/master.zip" target="_blank">从 Github 下载</a></li>
</ul><p><i></i> <a href="https://github.com/Tsuk1ko/Comment2Wechat" target="_blank">View source on Github</a></p></section>
<section><h2>部署<a href="#部署"><span>#</span></a></h2><p>下载完后将<code>Comment2Wechat</code>文件夹解压至<code>(Typecho根目录)/usr/plugins</code>中即可。</p><div><div><div></div><div>Warning</div></div><div><p>如果你是从 Github 下载的，请记得将插件文件夹重命名为 Comment2Wechat</p></div></div><div><div><div></div><div>Tip</div></div><div><p>如果你已经有原版插件，可以直接覆盖，但是在这之后必须点开设置菜单并保存设置一次（即使你不需要更改默认设置）</p></div></div></section>
<section><h2>使用<a href="#使用"><span>#</span></a></h2><p>首先去 <a href="https://sc.ftqq.com/" target="_blank">Server酱</a> 首页，根据首页的说明一步步操作即可。
然后将你获取的 SCKEY 粘贴到插件的设置中，保存设置。
就这么简单。</p><img src="/usr/uploads/2017/10/3737715179.jpg" /></section>
<section><h2>原作<a href="#原作"><span>#</span></a></h2><p>Comment2Wechat V1.0.0 by <a href="https://yian.me" target="_blank">Y!an</a>
<a href="https://github.com/YianAndCode/Comment2Wechat" target="_blank">https://github.com/YianAndCode/Comment2Wechat</a></p></section>
<section><h2>感谢<a href="#感谢"><span>#</span></a></h2><p>原作者 Y!an
<a href="https://www.weibo.com/easy" target="_blank">@Easy</a> 大大的 <a href="https://sc.ftqq.com/" target="_blank">Server酱</a> 解决方案</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/linux-vps-install-collection/</id>
      <title type="text">[收集] Linux VPS装机相关</title>
      <published>2017-10-18T11:37:00.000Z</published>
      <updated>2017-11-10T06:02:28.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/linux-vps-install-collection/"/>
      <summary type="text">自己整理的一些自己常用的VPS装机必备脚本，包括Linux网络一键重装、网络优化（锐速）、Linux面板。</summary>
      <content type="html"><![CDATA[<p>自己整理的一些自己常用的VPS装机必备脚本，包括Linux网络一键重装、网络优化（锐速）、Linux面板。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=60412013" target="_blank">「寒い冬，ロシアスープを飲む 最高です！！」/「翼つばさ」のイラスト [pixiv]</a>
这是我很喜欢的一个国人画师，响爷痴汉www</p>
<hr />
<p>菜鸡英语↑</p>
<section><h2>网络一键重装<a href="#网络一键重装"><span>#</span></a></h2><section><h3>Debian(Ubuntu)网络安装/重装一键脚本<a href="#debianubuntu网络安装重装一键脚本"><span>#</span></a></h3><p><a href="https://moeclub.org/2017/03/25/82/" target="_blank">https://moeclub.org/2017/03/25/82/</a>
by Vicer</p><section><h4>说明<a href="#说明"><span>#</span></a></h4><p>可以从由 GRUB 引导的 CentOS/Ubuntu/Debian 系统一键网络重装成 Debian/Ubuntu。用过好多次，十分好用，感谢 Vicer 大佬。
不过唯一不足的就是不能重装成 CentOS 了，因为个人在 VPS 上还是习惯用 CentOS，但是大佬不喜欢 CentOS 好像也没有什么办法……</p><p></p><figure><img src="/usr/uploads/2017/10/2942733415.jpg" alt="唉……" /><figcaption>唉……</figcaption></figure><p></p></section></section><section><h3>CentOS 6.9 网络安装/重装一键脚本<a href="#centos-69-网络安装重装一键脚本"><span>#</span></a></h3><p><a href="http://xiaofd.win/index.php/archives/98/" target="_blank">http://xiaofd.win/index.php/archives/98/</a>
by 狗仔小分队
此地址已失效，貌似原作者迁移了博客，下面有原文以及脚本的备份（防止失效）。</p><section><h4>说明<a href="#说明-1"><span>#</span></a></h4><p>这脚本是作者根据 Vicer 大佬的脚本改写的，能把系统重装成 CentOS 6.9 Final，拟补了 Vicer 大佬脚本的遗憾。个人测试过 AWS Lightsail 东京 没问题，但 AWS Lightsail 新加坡 装完就进不去ssh了，也是神奇。
不知道可不可以先用 Vicer 的脚本重装完再用这个脚本重装一次来解决问题，我没有试过。</p></section><section><h4>作者原文<a href="#作者原文"><span>#</span></a></h4><p><strong>背景</strong>
一个最纯净 最原装的 CentOS系统
感谢 <a href="https://moeclub.org/2017/03/25/82/" target="_blank">Vicer大佬的文章—Debian(Ubuntu)网络安装/重装一键脚本</a> 非常好用。
看得似懂非懂后，仿照着折腾了一下CentOS的重装脚本
我自己不用CentOS，脚本水平也比较渣，希望大佬们能够继续帮忙完善脚本，提高下兼容性，多添加些版本啥的~~~</p><p><strong>使用</strong>
条件：GRUB引导、非OVZ虚拟化
架构：X64</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>xiaofd.github.io/centos.sh</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>centos.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装时间（Vultr 2.5刀机器 重装大概15分钟） root用户密码为xiaofd.win</p><p><strong>测试说明</strong>
Debian系列貌似跑不起来，脚本不好使
测试了Vultr下重装，Ubuntu 16.04、Ubuntu 14.04、CentOS 6、CentOS 7 都能正常重装到 CentOS 6.9
测试了Azure下重装，Ubuntu 16.04 能正常重装到 CentOS 6.9（耗时较长，大概2030分钟）
测试了AWS-LightSail下重装，Ubuntu 16.04 能正常重装到 CentOS 6.9（耗时较长，大概2030分钟）
手里也没啥别的炸鸡了，其他就不测了
目测没啥幺蛾子的小鸡鸡都能成功装上</p><p><strong>补充</strong>
X86架构需要替换下源地址， 应该可以用，其他版本不确定直接替换能不能用~</p></section><section><h4>备用使用方式（本站备份）<a href="#备用使用方式本站备份"><span>#</span></a></h4><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>--no-check-certificate</span><span> </span><span>https://moe.best/files/scripts/centos6.9-reinstall/centos.sh</span><span> &amp;&amp; </span><span>bash</span><span> </span><span>centos.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section></section>
<section><h2>网络优化<a href="#网络优化"><span>#</span></a></h2><section><h3>锐速 ServerSpeeder LotServer<a href="#锐速-serverspeeder-lotserver"><span>#</span></a></h3><p><a href="https://moeclub.org/2017/03/08/14/" target="_blank">https://moeclub.org/2017/03/08/14/</a>
by Vicer</p><p>也是 Vicer 大佬的脚本，好用的一批。</p></section><section><h3>BBR（增强版）<a href="#bbr增强版"><span>#</span></a></h3><p><a href="https://moeclub.org/2017/06/24/278/" target="_blank">https://moeclub.org/2017/06/24/278/</a>
by Vicer</p><p>无所不能的 Vicer 大佬。</p></section></section>
<section><h2>Linux面板<a href="#linux面板"><span>#</span></a></h2><section><h3>宝塔面板<a href="#宝塔面板"><span>#</span></a></h3><p><a href="https://www.bt.cn/" target="_blank">https://www.bt.cn/</a>
Linux版请确保纯净系统安装(支持CentOS、Ubuntu、Debian、Fedora、deepin)，Web端管理；一键创建网站、FTP、数据库、SSL；安全管理，计划任务，文件管理，PHP多版本共存及切换；自带LNMP与LAMP。</p><section><h4>说明<a href="#说明-2"><span>#</span></a></h4><p>一直用的是这个，感觉挺好用，比较符合我的实际需求，但是也有人觉得没用的功能太多/老出bug……我自己使用时并没有碰到过什么问题，总之因人而异吧。</p><p></p><figure><img src="/usr/uploads/2017/10/3646456628.jpg" alt="宝塔面板" /><figcaption>宝塔面板</figcaption></figure><p></p></section></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/teracloud/</id>
      <title type="text">[TeraCloud] 免费20GB的WebDAV（网盘）</title>
      <published>2017-10-08T04:00:00.000Z</published>
      <updated>2017-10-28T14:37:34.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/teracloud/"/>
      <summary type="text">TeraCloud是一家日本的WebDAV商，目前有活动，你可以免费获得20GB的WebDAV空间，可以说是非常超值了。</summary>
      <content type="html"><![CDATA[<p>TeraCloud是一家日本的WebDAV商，目前有活动，你可以免费获得20GB的WebDAV空间，可以说是非常超值了。</p>
<hr />
<section><h2>WebDAV是什么？<a href="#webdav是什么"><span>#</span></a></h2><p><a href="https://zh.wikipedia.org/wiki/WebDAV" target="_blank">https://zh.wikipedia.org/wiki/WebDAV</a>
简单的来说，类似于网盘，但是比网盘更便捷，可以直接挂载到操作系统上，当作一个磁盘来使用，对于批量存取文件和随用随取是十分有用的。
虽然不足网盘的一点是缺少了分享功能，但是这一点可以通过<a href="https://www.multcloud.com" target="_blank">MultCloud</a>来拟补。(稍后出教程)</p></section>
<section><h2>注册TeraCLOUD得15GB<a href="#注册teracloud得15gb"><span>#</span></a></h2><p>首先直接进入TeraCLOUD日文官网
<a href="https://teracloud.jp/ja/" target="_blank">https://teracloud.jp/ja/</a></p><div><div><div></div><div>Warning</div></div><div><p>如果你直接通过 <a href="https://teracloud.jp/" target="_blank">https://teracloud.jp/</a> 进入官网，那么一般情况下会给你跳到其英文官网 <a href="https://teracloud.jp/en/" target="_blank">https://teracloud.jp/en/</a> ，英文官网是只有介绍，没有注册入口的。</p></div></div><p>看到右侧的登录框：</p><p></p><figure><img src="/usr/uploads/2017/10/3648270357.jpg" alt="首页登录框" /><figcaption>首页登录框</figcaption></figure><p></p><p>直接点击那个红色的按钮进入<a href="https://account.teracloud.jp/RegistForm.php/index/" target="_blank">注册页面</a>←当然你直接点这个也可以……
如果不会日文就看下面的翻译填写注册信息：</p><p></p><figure><img src="/usr/uploads/2017/10/2222811466.png" alt="注册页面" /><figcaption>注册页面</figcaption></figure><p></p><p>最后别忘了勾上“同意利用规约”，然后点击“次へ”。
接着就会来到一个邮箱验证页面，等待邮箱收到验证码之后填写然后再点击“次へ”。</p><p></p><figure><img src="/usr/uploads/2017/10/1381390740.jpg" alt="邮箱验证" /><figcaption>邮箱验证</figcaption></figure><p></p><p>（懒得再注册一次所以借用一下其他人的图）
然后就可以登陆进个人中心了，并且获得了15GB的WebDAV空间。</p></section>
<section><h2>剩下5GB呢<a href="#剩下5gb呢"><span>#</span></a></h2><p>那当然就是填写邀请码啦，嘻嘻~
首先进入个人中心
<a href="https://teracloud.jp/ja/modules/mypage/usage/" target="_blank">https://teracloud.jp/ja/modules/mypage/usage/</a>
拉到下方“紹介ボーナス情報”
</p><figure><img src="/usr/uploads/2017/10/1818360054.jpg" alt="邀请码填写" /><figcaption>邀请码填写</figcaption></figure><p></p><p>对，看到这个框，把邀请码<code>HNLN7</code>填进去然后猛戳“コード適用”，邀请方和被邀请方都能获得5GB空间，互利共赢。</p><div><div><div></div><div>Warning</div></div><div><p>需要注意的是，如果您使用的是免费帐户，并且连续超过90天未登录，则TeraCLOUD上的帐户和数据将被删除，所以一定要记得每过一段时间就登录一次哦！</p></div></div></section>
<section><h2>需要用的网址总结<a href="#需要用的网址总结"><span>#</span></a></h2><p>个人中心：
<a href="https://teracloud.jp/ja/modules/mypage/usage/" target="_blank">https://teracloud.jp/ja/modules/mypage/usage/</a>
WebDAV在线浏览器：
<a href="https://nanao.teracloud.jp/browser/" target="_blank">https://nanao.teracloud.jp/browser/</a>
WebDAV地址：
<a href="https://nanao.teracloud.jp/dav/" target="_blank">https://nanao.teracloud.jp/dav/</a></p></section>
<section><h2>如何挂载WebDAV<a href="#如何挂载webdav"><span>#</span></a></h2><p><a href="/posts/mount-webdav/">[WebDAV] 如何在各个平台挂载WebDAV</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/mount-webdav/</id>
      <title type="text">[WebDAV] 如何在各个平台下挂载WebDAV</title>
      <published>2017-10-07T20:46:00.000Z</published>
      <updated>2018-10-29T10:12:40.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/mount-webdav/"/>
      <summary type="text">WebDAV是个好文明</summary>
      <content type="html"><![CDATA[<p>WebDAV是个好文明</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=54605685" target="_blank">「裸パーカー猿耳しっぽニーソ！」/「ぺこ／かにビーム」のイラスト [pixiv]</a></p>
<hr />
<section><h2>这是什么？有什么用？<a href="#这是什么有什么用"><span>#</span></a></h2><p><a href="https://zh.wikipedia.org/wiki/WebDAV" target="_blank">https://zh.wikipedia.org/wiki/WebDAV</a></p></section>
<section><h2>Linux<a href="#linux"><span>#</span></a></h2><p>Centos &amp; Fedora &amp; RedHat</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>yum</span><span> </span><span>-y</span><span> </span><span>install</span><span> </span><span>davfs2</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>其他的比如Ubuntu之类的</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>apt-get</span><span> </span><span>-y</span><span> </span><span>install</span><span> </span><span>davfs2</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>安装完davfs2之后执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sed</span><span> </span><span>-i</span><span> </span><span>'s/# use_locks       1/use_locks       0/g'</span><span> </span><span>/etc/davfs2/davfs2.conf</span></div></div><div><div><div>2</div></div><div><span>echo</span><span> </span><span>"你的WebDAV地址 用户名 密码"</span><span> &gt;&gt; </span><span>/etc/davfs2/secrets</span><span> </span><span>#保存用户名密码，以后可以直接免密码挂载</span></div></div><div><div><div>3</div></div><div><span>mount.davfs</span><span> </span><span>你的WebDAV地址</span><span> </span><span>你想要挂载到的目录</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>即可成功挂载</p><div><div><div></div><div>Warning</div></div><div><p>注意1：挂载目录必须提前创建好！<br />注意2：如果你不执行第二句保存用户名密码，那么你以后挂载的时候都会要求输入用户名密码！</p></div></div><section><h3>开机自动挂载<a href="#开机自动挂载"><span>#</span></a></h3><p>如果想要开机自动挂载，则再执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>echo</span><span> </span><span>"mount.davfs 你的WebDAV地址 你想要挂载到的目录"</span><span> &gt;&gt; </span><span>/etc/rc.local</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>执行完此句之后检查一下<code>/etc/rc.local</code>文件，看看是否有<code>exit 0</code>这句。如果有的话，要手动把上面命令添加进去的语句放到<code>exit 0</code>之前。</p></section></section>
<section><h2>Windows<a href="#windows"><span>#</span></a></h2><div><div><div></div><div>Warning</div></div><div><p>Windows 资源管理器挂载只能挂载 HTTPS 的 WebDAV。如果想挂载 HTTP 的，貌似需要动点手脚，或者使用第三方软件（见下方）。</p></div></div><ol>
<li>
<p>直接打开“我的电脑”，右击-添加一个网络位置。</p>
</li>
<li>
<p>一路“下一步”，然后在这个框内填入你的WebDAV地址，这里以TeraCLOUD为例（<a href="/posts/teracloud/">[TeraCloud] 免费20GB的WebDAV</a>）。
</p><figure><img src="/usr/uploads/2017/10/189786174.jpg" alt="输入WebDAV地址" /><figcaption>输入WebDAV地址</figcaption></figure><p></p>
</li>
<li>
<p>继续下一步，然后等待，会弹出一个登录框让你输入用户名密码，即为你账户的用户名密码。
</p><figure><img src="/usr/uploads/2017/10/791205003.jpg" alt="输入用户名密码" /><figcaption>输入用户名密码</figcaption></figure><p></p>
</li>
<li>
<p>输入网络位置名称，其实就是取个名字，请随意，然后一路“下一步”，完工，现在你应该可以在我的电脑里看到你挂载的WebDAV了。</p>
</li>
</ol></section>
<section><h2>MacOS<a href="#macos"><span>#</span></a></h2><p>在 Finder 中连接到服务器，操作与Windows大同小异，由于我没有Mac所以就不讲了，此处直接给出苹果官方文档。
<a href="http://support.apple.com/kb/PH3857" target="_blank">http://support.apple.com/kb/PH3857</a></p></section>
<section><h2>第三方软件<a href="#第三方软件"><span>#</span></a></h2><p>实际上比较推荐使用第三方软件，特别是Windows，资源管理器总有一点科学无法解释的BUG，使用体验不是很好。</p><table><thead><tr><th>程序名</th><th>适用平台</th><th>许可</th><th>注释</th></tr></thead><tbody><tr><td><a href="https://www.raidrive.com">RaiDrive</a></td><td>Windows</td><td>免费</td><td>还支持谷歌、OneDrive等网盘</td></tr><tr><td><a href="http://cyberduck.ch/">Cyberduck</a></td><td>Windows/MacOS</td><td>免费</td><td></td></tr><tr><td><a href="https://southrivertech.com/products/webdrive/download/">WebDrive</a></td><td>Windows/MacOS</td><td>免费试用10天</td><td></td></tr><tr><td><a href="http://www.netdrive.net/">NetDrive</a></td><td>Windows</td><td>个人免费使用</td><td></td></tr><tr><td><a href="https://www.webdavsystem.com/">IT Hit "Map Drive"</a></td><td>Windows</td><td>商业使用</td><td></td></tr><tr><td><a href="https://www.goodsync.com/">GoodSync</a></td><td>Windows/MacOS/Android/iOS</td><td>免费/专业版</td><td>适用于双向文件夹同步</td></tr><tr><td><a href="https://itunes.apple.com/us/app/webdav-navigator/id382551345?mt=8">WebDAV Navigator</a></td><td>iOS</td><td>免费</td><td></td></tr><tr><td><a href="http://sourceforge.net/projects/webdav-sync/">WebDAV-Sync</a></td><td>任意平台(Java)</td><td> 开源</td><td>适用于双向文件夹同步的命令行工具</td></tr><tr><td><a href="http://www.pincette.biz/davbox/index.xhtml">DAVbox</a></td><td>任意平台(Java)</td><td>商业使用</td><td>适用于双向文件夹同步</td></tr></tbody></table></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/mysql-allow-external/</id>
      <title type="text">[MySQL] 设置MySQL允许从外网访问</title>
      <published>2017-10-07T13:10:00.000Z</published>
      <updated>2017-10-28T14:38:41.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/mysql-allow-external/"/>
      <summary type="text">笔记：如何设置MySQL使其允许从外网访问</summary>
      <content type="html"><![CDATA[<p>笔记：如何设置MySQL使其允许从外网访问</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=40419493" target="_blank">「のんのんびより」/「コ゛りぼて」</a></p>
<hr />
<section><h2>如果你装有phpMyAdmin<a href="#如果你装有phpmyadmin"><span>#</span></a></h2><p>那么十分简单。</p><ol>
<li>
<p>首先进入phpMyAdmin，找到“mysql”数据库，进入“user”表，然后你应该能会看到这样的若干条除了“Host”以外都一样的数据（当然，“User”中的“Hostname”也会不一样）
</p><figure><img src="/usr/uploads/2017/10/33455519.jpg" alt="user表" /><figcaption>user表</figcaption></figure><p></p>
</li>
<li>
<p>从这些条目中随便挑一条点复制
</p><figure><img src="/usr/uploads/2017/10/1612276486.jpg" alt="复制之后的编辑界面" /><figcaption>复制之后的编辑界面</figcaption></figure>
然后会进入编辑界面，将“Host”改为你想要允许访问的IP，如果想完全对外网开放则改为<code>%</code>，其他项不要动，然后点击最下面的“执行”<p></p>
</li>
<li>
<p>找到phpMyAdmin页面最下方的控制台(Console)，输入<code>flush privileges</code>，然后按下 Ctrl+Enter 以执行语句
</p><figure><img src="/usr/uploads/2017/10/2090926498.jpg" alt="flush privileges" /><figcaption>flush privileges</figcaption></figure>
此步的目的是刷新MySQL的权限设置，使之前的改动真正生效<p></p>
</li>
</ol><p>这样，你就可以从你指定IP的主机远程访问你的MySQL了。</p></section>
<section><h2>没装phpMyAdmin怎么办<a href="#没装phpmyadmin怎么办"><span>#</span></a></h2><ol>
<li>
<p>这玩意都不装？赶紧去装一个啦……
或者你也可以考虑用Adminer，一款颜值完爆phpMyAdmin的数据库管理工具，而且支持多种数据库，不止MySQL
</p><figure><img src="/usr/uploads/2017/10/2301300135.jpg" alt="Adminer" /><figcaption>Adminer</figcaption></figure><p></p>
</li>
<li>
<p>或者参考文章 <a href="http://blog.csdn.net/meseal/article/details/52814086" target="_blank">http://blog.csdn.net/meseal/article/details/52814086</a></p>
</li>
</ol></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/ddos-deflate/</id>
      <title type="text">[DDoS deflate] 一个防御DDoS的纯Shell脚本 修复BUG&amp;汉化</title>
      <published>2017-10-07T11:11:00.000Z</published>
      <updated>2018-02-17T15:58:51.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/ddos-deflate/"/>
      <summary type="text">最后更新 2017-10-11 DDoS deflate是一款免费的用来防御和减轻DDoS攻击的脚本。它通过netstat监测跟踪创建大量网络连接的IP地址，在检测到某个结点超过预设的值时，该脚本会通过APF或iptables禁止这些IP的访问。</summary>
      <content type="html"><![CDATA[<section><h2>最后更新 2017-10-11<a href="#最后更新-2017-10-11"><span>#</span></a></h2><p>DDoS deflate是一款免费的用来防御和减轻DDoS攻击的脚本。它通过netstat监测跟踪创建大量网络连接的IP地址，在检测到某个结点超过预设的值时，该脚本会通过APF或iptables禁止这些IP的访问。
据说官网为 <a href="http://deflate.medialayer.com/" target="_blank">http://deflate.medialayer.com/</a> ，但是已经无法访问。</p><p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=42688297" target="_blank">「ごはんなのです！」/「コ゛りぼて」</a></p><hr /></section>
<section><h2>安装<a href="#安装"><span>#</span></a></h2><p>直接执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>-N</span><span> </span><span>--no-check-certificate</span><span> </span><span>https://moe.best/files/scripts/ddos/install-ddos-deflate.sh</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>+x</span><span> </span><span>install-ddos-deflate.sh</span><span> &amp;&amp; </span><span>./install-ddos-deflate.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>即可自动安装。
安装完成后会进入一个给你看本脚本license的界面，按<code>q</code>即可退出。</p></section>
<section><h2>配置<a href="#配置"><span>#</span></a></h2><p>配置文件在<code>/usr/local/ddos/ddos.conf</code>，我已经将配置文件的英文说明汉化。
此处展示一下重要配置内容：</p><div><div><div><figure><figcaption><span></span><span>Terminal window</span><span>展开</span><span>收起</span></figcaption><pre><code><div><div><div>1</div></div><div><span>##### 运行此脚本的频率（分钟）</span></div></div><div><div><div>2</div></div><div><span>##### 注意：每当你修改了FREQ这个设置，你需要带 --cron 参数运行一次此脚本才能让这个设置生效</span></div></div><div><div><div>3</div></div><div><span>FREQ</span><span>=</span><span>1</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>##### 一个IP连接有这~么多连接数才需要拉黑</span></div></div><div><div><div>6</div></div><div><span>NO_OF_CONNECTIONS</span><span>=</span><span>150</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span>##### 是否使用APF（一个防火墙程序）来ban掉IP</span></div></div><div><div><div>9</div></div><div><span>##### APF_BAN=1 （请确保你的APF版本至少为0.96）</span></div></div><div><div><div>10</div></div><div><span>##### APF_BAN=0 （用iptables，即系统自带防火墙来ban掉IP）</span></div></div><div><div><div>11</div></div><div><span>APF_BAN</span><span>=</span><span>0</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>##### KILL=0 （不会ban掉IP，对脚本交互有利）</span></div></div><div><div><div>14</div></div><div><span>##### KILL=1 （管他的直接ban，推荐使用这个设置）</span></div></div><div><div><div>15</div></div><div><span>KILL</span><span>=</span><span>1</span></div></div><div><div><div>16</div></div><div>
</div></div><div><div><div>17</div></div><div><span>##### 当一个IP被ban之后会发邮件到下面这个邮箱里</span></div></div><div><div><div>18</div></div><div><span>##### 留空则不会发送</span></div></div><div><div><div>19</div></div><div><span>EMAIL_TO</span><span>=</span><span>"root"</span></div></div><div><div><div>20</div></div><div>
</div></div><div><div><div>21</div></div><div><span>##### 当这么多秒过去以后，被ban的IP将解ban</span></div></div><div><div><div>22</div></div><div><span>BAN_PERIOD</span><span>=</span><span>600</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div><p>请根据你自己的需要修改配置，然后保存。</p></section>
<section><h2>修改说明<a href="#修改说明"><span>#</span></a></h2><p>这个脚本经过了我的修改以修复一个严重的 BUG</p><ol>
<li>脚本中的第119行</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>netstat</span><span> </span><span>-ntu</span><span> | </span><span>awk</span><span> </span><span>'{print $5}'</span><span> | </span><span>cut</span><span> </span><span>-d:</span><span> </span><span>-f1</span><span> | </span><span>sort</span><span> | </span><span>uniq</span><span> </span><span>-c</span><span> | </span><span>sort</span><span> </span><span>-nr</span><span> &gt; </span><span>$BAD_IP_LIST</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>此行被我注释，修改成了第120行的</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>netstat</span><span> </span><span>-ntu</span><span> | </span><span>sed</span><span> </span><span>'1,2d'</span><span> | </span><span>awk</span><span> </span><span>'{print $5}'</span><span> | </span><span>cut</span><span> </span><span>-d:</span><span> </span><span>-f1</span><span> | </span><span>sed</span><span> </span><span>'/^\s*$/d'</span><span> | </span><span>sort</span><span> | </span><span>uniq</span><span> </span><span>-c</span><span> | </span><span>sort</span><span> </span><span>-nr</span><span> &gt; </span><span>$BAD_IP_LIST</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>此处新增的<code>sed '1,2d'</code>是为了过滤掉使用<code>netstat -ntu</code>命令时返回的开头两句英文说明。
而<code>sed '/^\s*$/d'</code>是为了删除前一步<code>cut -d: -f1</code>中产生的未删除的空行，如果不删除空行，在后面的统计排序中将会出现将空行也统计进去的BUG。</p><ol>
<li>脚本里的<code>head()</code>函数被我重命名为<code>showhead()</code>，因为会与系统程序<code>head</code>冲突。</li>
</ol></section>
<section><h2>嫌1分钟的运行间隔不够短？<a href="#嫌1分钟的运行间隔不够短"><span>#</span></a></h2><p>由于 Crontab 定时任务的最短定时间隔为1分钟，然而如果真的被攻击，1分钟的时间都够服务器喝一大壶的了。</p><p>想让脚本运行时间间隔小于1分钟，思路也十分简单，用另一个脚本让 DDoS deflate 在一分钟内运行数次就可以了。</p><p>例如要让这个脚本每10秒运行一次：</p><ol>
<li>在<code>/usr/local/ddos</code>内新增一个脚本<code>runddos.sh</code></li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vi</span><span> </span><span>/usr/local/ddos/runddos.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>并填入以下内容</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>#!/bin/sh</span></div></div><div><div><div>2</div></div><div><span>i</span><span>=</span><span>0</span><span>;</span></div></div><div><div><div>3</div></div><div><span>while</span><span> </span><span>[</span><span> </span><span>$i</span><span> </span><span>-le</span><span> </span><span>5</span><span> ]</span></div></div><div><div><div>4</div></div><div><span>do</span></div></div><div><div><div>5</div></div><div><span>    </span><span>i</span><span>=</span><span>`</span><span>expr</span><span> </span><span>$i</span><span> + </span><span>1</span><span>`</span></div></div><div><div><div>6</div></div><div><span>    </span><span>/usr/local/ddos/ddos.sh</span><span> &gt;</span><span>/dev/null</span><span> 2&gt;&amp;1</span></div></div><div><div><div>7</div></div><div><span>    </span><span>sleep</span><span> </span><span>10</span></div></div><div><div><div>8</div></div><div><span>done</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后保存，记得给脚本加执行权限</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>chmod</span><span> </span><span>+x</span><span> </span><span>/usr/local/ddos/runddos.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>修改 crontab 中 ddos 脚本的配置</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>vi</span><span> </span><span>/etc/cron.d/ddos.cron</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>将文件中的</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>0-59/1 * * * * root /usr/local/ddos/ddos.sh &gt;/dev/null 2&gt;&amp;1</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>改为</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>0-59/1 * * * * root /usr/local/ddos/runddos.sh &gt;/dev/null 2&gt;&amp;1</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>实际上就是改成我们刚刚新建的那个<code>runddos.sh</code>脚本</p><ol>
<li>重启 crontab</li>
</ol><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>service</span><span> </span><span>crond</span><span> </span><span>restart</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>至此这个修改就完成了</p></section>
<section><h2>如果想让脚本监控网站访问日志<a href="#如果想让脚本监控网站访问日志"><span>#</span></a></h2><p>如果想要监控网站访问记录，请将所有的网站访问日志放到一个文件夹里（下面以日志都在<code>/www/wwwlogs</code>并且文件名统一为<code>xxxx.com.log</code>为例），然后</p><ul>
<li>如果是 <strong>Nginx</strong> 的话，将脚本中第120行注释掉（有<code>&gt; $BAD_IP_LIST</code>而且没注释掉的那行）
然后紧接着加入以下三行内容：</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>TMP_DATE</span><span>=</span><span>`</span><span>date</span><span>`</span></div></div><div><div><div>2</div></div><div><span>TMP_DATE</span><span>=</span><span>`</span><span>echo</span><span> "</span><span><span>${</span><span>TMP_DATE</span><span>}</span></span><span>" </span><span>|</span><span> </span><span>awk</span><span> '{print $3}'`</span><span>/</span><span>`</span><span>echo</span><span> "</span><span><span>${</span><span>TMP_DATE</span><span>}</span></span><span>" </span><span>|</span><span> </span><span>awk</span><span> '{print $2}'`</span><span>/</span><span>`</span><span>echo</span><span> "</span><span><span>${</span><span>TMP_DATE</span><span>}</span></span><span>" </span><span>|</span><span> </span><span>awk</span><span> '{print $6}'`</span><span>:</span><span>`</span><span>echo</span><span> "</span><span><span>${</span><span>TMP_DATE</span><span>}</span></span><span>" </span><span>|</span><span> </span><span>awk</span><span> '{print $4}' </span><span>|</span><span> </span><span>head</span><span> </span><span>-c</span><span> </span><span>-3</span><span>`</span></div></div><div><div><div>3</div></div><div><span>grep</span><span> </span><span>-h</span><span> </span><span>"</span><span>$TMP_DATE</span><span>"</span><span> </span><span>/www/wwwlogs/</span><span>*</span><span>.com.log</span><span> | </span><span>awk</span><span> </span><span>'{print $1}'</span><span> | </span><span>sort</span><span> | </span><span>uniq</span><span> </span><span>-c</span><span> | </span><span>sort</span><span> </span><span>-nr</span><span> &gt; </span><span>$BAD_IP_LIST</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>第三行中的日志目录与通配符文件名匹配请根据你的实际情况修改。</strong>
<em>只懂得shell的一点皮毛，写的很罗嗦还请见谅，如果你还有更好的写法请务必提出来让我学习一个</em></p><ul>
<li>如果是 <strong>Apache</strong> ，由于我没用所以不知道日志长啥样，不过监控原理是一样的，如果你看得懂上面这句你就会写。</li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/free-kiwi-buzz/</id>
      <title type="text">[Octopoly] 免费一年 kiwi / buzz 域名</title>
      <published>2017-09-30T19:09:00.000Z</published>
      <updated>2018-01-28T15:18:22.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/free-kiwi-buzz/"/>
      <summary type="text">Octopoly 现在有活动，每个帐号可以白嫖一年的一个 kiwi 域名和一个 buzz 域名，而且无需任何信用卡之类的验证，只需要一个邮箱，可以说是非常厉害了。</summary>
      <content type="html"><![CDATA[<p>Octopoly 现在有活动，每个帐号可以白嫖一年的一个 kiwi 域名和一个 buzz 域名，而且无需任何信用卡之类的验证，只需要一个邮箱，可以说是非常厉害了。</p>
<hr />
<section><h2>优惠码<a href="#优惠码"><span>#</span></a></h2><p>2017.10.1 亲测可用优惠码 <strong><code>PIESENPAI</code></strong> <strong>已失效</strong></p><p>如果此优惠码失效，去谷歌搜索“octopoly voucher code”找新的可用优惠码。我之前自己注册的时候就是百度搜到的优惠码<code>GEEKZONE</code>和<code>OCTOPOLY</code>都是过期的，最后在谷歌上找到了可以用的。</p></section>
<section><h2>注册<a href="#注册"><span>#</span></a></h2><p>首先你需要先去 <a href="https://octopoly.com/domain-promo-codes" target="_blank">Octopoly 活动页面</a>，你在这里可以看到其他的一些官方放出的优惠码，如果你觉得它们有用，你可以记下来。
接着就是注册一个帐号，这里提供一个注册页面的翻译图给好不容易过了四六级之后就不想再看到鸟语的同学。
</p><figure><img src="/usr/uploads/2017/10/3319598560.png" alt="注册页面" /><figcaption>注册页面</figcaption></figure><p></p></section>
<section><h2>使用优惠码购买域名<a href="#使用优惠码购买域名"><span>#</span></a></h2><p>注意：优惠码只能免费注册 kiwi 和 buzz 域名噢！
接着就在注册完之后的页面下方的搜索框内搜索你想要注册的域名，然后把 kiwi 或者 buzz 域名加入购物车，然后下一步。
</p><figure><img src="/usr/uploads/2017/10/874672930.jpg" alt="QQ截图20171001021420.jpg" /><figcaption>QQ截图20171001021420.jpg</figcaption></figure><p></p><p>此时会看到这样的界面，第一次购买的时候右侧结算里应该是有金额的，我这里显示 $0 是因为我已经用过优惠码注册了 kiwi 域名了，所以我还能免费再注册一个 buzz 域名。
</p><figure><img src="/usr/uploads/2017/10/12221242.jpg" alt="域名设置" /><figcaption>域名设置</figcaption></figure><p></p><p>此时不要着急点击下一步，如果你不想用 Octopoly 提供的域名解析，你可以直接在下方设置自己的 DNS。如果你在域名创建完成之后再更换 DNS，那么请看后续步骤<a href="#update-dns">注册域名后如何更改DNS</a>。
</p><figure><img src="/usr/uploads/2017/10/4133029766.jpg" alt="QQ截图20171001021508.jpg" /><figcaption>QQ截图20171001021508.jpg</figcaption></figure><p></p><p>确认完设置以后，点击下一步，进入结算页面。此时，在结算金额下方有个“Voucher code”输入框，在这里填入文章开头所说的优惠码，然后点击“APPLY”，如果没有红色提示优惠码已无法使用什么的那就成功了。如果此时金额还是没有变为0，那么在这里删除域名然后返回去再购买一次即可看到金额变为0。
</p><figure><img src="/usr/uploads/2017/10/3244132062.jpg" alt="结算页面" /><figcaption>结算页面</figcaption></figure><p></p><p>购买成功之后会显示如下页面，此时耐心等待域名成功建立即可，需要一定的时间，域名可用之后会发邮件通知你。
</p><figure><img src="/usr/uploads/2017/10/3784011902.jpg" alt="白嫖成功" /><figcaption>白嫖成功</figcaption></figure><p></p><p><span></span></p></section>
<section><h2>注册域名之后如何修改 DNS<a href="#注册域名之后如何修改-dns"><span>#</span></a></h2><p>进入“MY DOMAINS”，然后勾选你需要更改DNS的域名，接着在最下方的两个选项框中分别选择“Update name servers”和“Selected domains”，点击右边的“START”，然后就会回到你当初购买时的域名设置界面，此时更改 DNS 然后一路继续即可，更改 DNS 是不需要额外交钱的，请放心。提交修改之后也需要等待一段时间才能更改完成。
</p><figure><img src="/usr/uploads/2017/10/3474387815.jpg" alt="更新DNS" /><figcaption>更新DNS</figcaption></figure><p></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/nhentai-downloader/</id>
      <title type="text">[Shell] nhentai一键批量下载</title>
      <published>2017-09-28T05:38:00.000Z</published>
      <updated>2019-04-24T14:41:06.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/nhentai-downloader/"/>
      <summary type="text">一个能一键分析批量下载nhentai本子的纯Shell脚本，下完还能自动打包成zip。</summary>
      <content type="html"><![CDATA[<p>一个能一键分析批量下载nhentai本子的纯Shell脚本，下完还能自动打包成zip。
主要是给VPS用的，批量快速下完打包然后拉回来一气呵成（。</p>
<p>Head Pic: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=60273241" target="_blank">「アストルフォきゅん」/「イチリ」</a></p>
<hr />
<a href="https://github.com/Tsuk1ko/nhentai-one-key-downloader" target="_blank"><div><div><div><div></div><div>Tsuk1ko</div></div><div>/</div><div>nhentai-one-key-downloader</div></div><div></div></div><div>一个可以一键下载nhentai本子的纯shell脚本。A pure shell script that can easily download comics from nhentai.</div><div><div>—</div><div>—</div><div>GPL-3.0</div><span>Shell</span></div></a>
<p>但由于 shell 脚本仍存在很多问题，不建议使用，有兴趣可以看这个</p>
<a href="/posts/nhentai-download-as-zip/"><div><div>[Script] nhentai 下载增强</div><div>因为 nhentai 本身仅提供登陆后 BT 下载的方式，比较麻烦而且速度较慢，因此编写了这个脚本，增加了直接 zip 打包下载的方式</div><div><span>2019-01-26</span><span>个人项目</span><span><span>#nhentai</span><span>#油猴</span><span>#下载</span><span>#打包</span></span></div></div><div><img src="/usr/uploads/2019/01/3125120331.jpg" alt="" loading="lazy" /></div></a>
<section><h2>演示视频<a href="#演示视频"><span>#</span></a></h2><p>视频约1.7MB
演示内容顺序：</p><ol>
<li>模式A 白名单</li>
<li>模式B + 断点续传</li>
<li>模式A 黑名单 + 查重</li>
</ol><p>你的浏览器不支持HTML5视频。 <a href="https://res.lolicon.app/video/nhentai-srcipt.mp4">打开视频</a></p></section>
<section><h2>准备工作<a href="#准备工作"><span>#</span></a></h2><p>首先你需要有Linux。。。VPS也可虚拟机也可。
然后用以下命令下载这个脚本：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>-N</span><span> </span><span>--no-check-certificate</span><span>  </span><span>https://raw.githubusercontent.com/Tsuk1ko/nhentai-one-key-downloader/master/nhentai-batch.sh</span><span> &amp;&amp; </span><span>chmod</span><span> </span><span>+x</span><span> </span><span>nhentai-batch.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后用编辑器打开它，自己根据需要修改脚本开头的设置：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>#setting  off:0  on:1</span></div></div><div><div><div>2</div></div><div><span>zad</span><span>=</span><span>1</span><span>       </span><span>#下载完一个本子后自动压缩成zip</span></div></div><div><div><div>3</div></div><div><span>dsaz</span><span>=</span><span>1</span><span>      </span><span>#压缩完之后删除源文件</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>dldir</span><span>=</span><span>"comics"</span><span>  </span><span>#你想要把本子下载在哪个目录，相对/绝对路径均可</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section>
<section><h2>开始使用<a href="#开始使用"><span>#</span></a></h2><p>这个脚本有两种下载模式。</p><section><h3>模式A<a href="#模式a"><span>#</span></a></h3><p>从一个nhentai搜索页面，地址类似于<code>https://nhentai.net/search/?q=xxxxxx</code>，或者其他的什么Tags/Artists/…页面下载本子，反正就是像下面这样的有很多本子结果的页面。</p><p></p><figure><img src="/usr/uploads/2017/09/172485445.jpg" alt="哇！好多本子！" /><figcaption>哇！好多本子！</figcaption></figure><p></p><p>那就执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>./nhentai-batch.sh</span><span> </span><span>-a</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后就输入这个网址接着回车就可以了，然后脚本会自动分析页面内的所有本子并且罗列出来并标上序号。如果你输入的网址有误会提示你。
然后会提示你有3种模式来下载本子：</p><ol>
<li>白名单模式：下载你指定的本子</li>
<li>黑名单模式：除了你指定的本子之外，都下载</li>
<li>想个屁模式：我全下了！(列表中有重复的本子也不要紧，由于“查重”功能，只会下载一个)</li>
</ol><p>如果你选择了模式1或者模式2，你需要输入你指定的本子的序号并以空格隔开，最后回车。</p></section><section><h3>模式B<a href="#模式b"><span>#</span></a></h3><p>从一个本子详情页，类似<code>https://nhentai.net/g/xxxxxx/</code>网址的页面下载本子，也就是下图所示的这种页面。</p><p></p><figure><img src="/usr/uploads/2017/09/2397299981.jpg" alt="哇！本子！" /><figcaption>哇！本子！</figcaption></figure><p></p><p>那就执行</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>./nhentai-batch.sh</span><span> </span><span>-b</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后就会提示要你输入网址，按回车换行。你可以批量下载，即输入一个网址-换行-再输入一个网址-换行-……。当你输入一个空行的时候（即连续两次换行）即可结束输入，然后脚本会自动将所有你输入的网址里的本子下载下来。</p></section></section>
<section><h2>其他功能<a href="#其他功能"><span>#</span></a></h2><p>这个脚本带有查重功能和断点续传功能。
也就是说，如果你一个本子下到一半没下完就ctrl+c终止了脚本，那么你下次再下载同样的本子的时候会自动从上次断掉的地方开始下载（会自动检测并删除wget没有下载完全的文件并重新下载）。
已经下好了的图片会直接略过；如果文件夹内有和本子名称同名的压缩包(.zip)，则也会判定为这个本子已经下过并跳过。</p></section>
<section><h2>补充说明<a href="#补充说明"><span>#</span></a></h2><p>如果在脚本完全运行完之前就ctrl+c结束了脚本，那么</p><ul>
<li>在总下载目录里会遗留形如<code>.nhentai-temp-xxxxx</code>的文件夹，删除即可</li>
<li>在没下完的本子目录里会遗留<code>.dl</code>文件，这是用于记录本子下载进度的。如果你删除了，那么下次下载同一个本子的时候就无法识别 wget 是否完整下载了当时强制结束脚本时的那个图片。</li>
</ul></section>
<section><h2>TODO<a href="#todo"><span>#</span></a></h2><p>开发网页程序（进行中）</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/closers-memory/</id>
      <title type="text">[纪念] CLOSERS 封印者</title>
      <published>2017-09-16T11:00:00.000Z</published>
      <updated>2020-02-09T12:06:56.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/closers-memory/"/>
      <summary type="text">这游戏陪伴了我加起来大概一年的时间，不算中间 AFK 了半年的话。由于主要还是个手游玩家，并且学业并没有轻松到能让我每天都花一两个小时来打完疲劳的程度，因此还是决定永久 AFK 了。不过总的来说，嗯，是一个很棒的游戏，给予了我一段美好的回忆。</summary>
      <content type="html"><![CDATA[<p>这游戏陪伴了我加起来大概一年的时间，不算中间 AFK 了半年的话。由于主要还是个手游玩家，并且学业并没有轻松到能让我每天都花一两个小时来打完疲劳的程度，因此还是决定永久 AFK 了。不过总的来说，嗯，是一个很棒的游戏，给予了我一段美好的回忆。</p>
<hr />
<section><h2>本命们<a href="#本命们"><span>#</span></a></h2><section><h3>粉毛<a href="#粉毛"><span>#</span></a></h3><p><img src="/usr/uploads/2018/03/1367394277.jpg" alt="" /></p><p><img src="/usr/uploads/2018/03/1367394277.jpg" alt="" /></p><p>退坑后不久后，秒伤终于和韩服一样改成综合战斗力了。之前秒伤 20w 多一丢，现在综合战斗力 933096，不知道算个什么水平。
至于装备，武器和上身三件都+13，放大器+12，武器铂金蓝+2x双重蓝绿，退坑前肝出来倒是也算了结了以前还是咸鱼时候的心愿吧。
时装以前肝过天6。不过不得不说巫女服真是好看，wtmsb。</p></section><section><h3>缇娜<a href="#缇娜"><span>#</span></a></h3><p>缇娜就看看时装就好了。</p><p><img src="/usr/uploads/2018/03/330564939.jpg" alt="" /></p><p><img src="/usr/uploads/2018/03/2025532668.jpg" alt="" /></p></section></section>
<section><h2>全家福<a href="#全家福"><span>#</span></a></h2><p><img src="/usr/uploads/2018/03/4269476827.jpg" alt="" /></p><p><img src="/usr/uploads/2018/03/3593912038.jpg" alt="" /></p><p><img src="/usr/uploads/2018/03/2582277281.jpg" alt="" /></p><p><img src="/usr/uploads/2018/03/3669903938.jpg" alt="" /></p><p><img src="/usr/uploads/2018/03/1110720814.jpg" alt="" /></p><p><img src="/usr/uploads/2018/03/3794918807.jpg" alt="" /></p><p><img src="/usr/uploads/2018/03/1090009945.jpg" alt="" /></p><p>再见了，封印者们</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/linux-l2tp/</id>
      <title type="text">[L2TP] 在Linux上搭建L2TP服务器 &amp; Windows连接L2TP失败的解决方法</title>
      <published>2017-09-06T12:38:00.000Z</published>
      <updated>2017-11-29T16:29:39.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/linux-l2tp/"/>
      <summary type="text">记一次困扰了我两天的瞎折腾。</summary>
      <content type="html"><![CDATA[<p>记一次困扰了我两天的瞎折腾。
Pic from: (C91) [予備学科 (米白粕)] ふりふりりぼん</p>
<hr />
<section><h2>安装 L2TP 服务器<a href="#安装-l2tp-服务器"><span>#</span></a></h2><ul>
<li>如果是Ubuntu或者Debian</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>https://git.io/vpnsetup</span><span> </span><span>-O</span><span> </span><span>vpnsetup.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ul>
<li>如果是CentOS或者RHEL</li>
</ul><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>wget</span><span> </span><span>https://git.io/vpnsetup-centos</span><span> </span><span>-O</span><span> </span><span>vpnsetup.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>接着编辑<code>vpnsetup.sh</code>文件</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>nano</span><span> </span><span>-w</span><span> </span><span>vpnsetup.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>往脚本开头的<code>YOUR_IPSEC_PSK</code>,<code>YOUR_USERNAME</code>,<code>YOUR_PASSWORD</code>后面的反引号中分别填入你想要的 IPsec密匙、VPN用户名、VPN密码。
然后运行脚本</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>sudo</span><span> </span><span>sh</span><span> </span><span>vpnsetup.sh</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>然后你只要耐心等待脚本执行完毕就可以了。</p></section>
<section><h2>解决Windows无法连接L2TP的问题<a href="#解决windows无法连接l2tp的问题"><span>#</span></a></h2><p>如果你是首次连接L2TP，应该会出现这样的错误：</p><blockquote><p>无法建立计算机与 VPN 服务器之间的网络连接，因为远程服务器未响应。</p></blockquote><p>要解决此错误，在首次连接之前需要修改一次注册表，以解决 VPN服务器 和/或 客户端与 NAT（比如家用路由器） 的兼容问题。
你有两种方法来操作。</p><section><h3>方法1<a href="#方法1"><span>#</span></a></h3><p>首先打开注册表编辑器，然后在下述位置新建 DWORD 值：</p><section><h5>对于 Windows Vista, 7, 8, 10, 2008 Server<a href="#对于-windows-vista-7-8-10-2008-server"><span>#</span></a></h5><p>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PolicyAgent
名称: AssumeUDPEncapsulationContextOnSendRule
类型: DWORD
值: 2</p></section><section><h5>对于叉屁<a href="#对于叉屁"><span>#</span></a></h5><p>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IPSec
名称: AssumeUDPEncapsulationContextOnSendRule
类型: DWORD
值: 2</p></section></section><section><h3>方法2<a href="#方法2"><span>#</span></a></h3><p>以管理员权限打开命令提示符，然后键入以下命令并执行：</p><section><h5>对于 Windows Vista, 7, 8, 10, 2008 Server<a href="#对于-windows-vista-7-8-10-2008-server-1"><span>#</span></a></h5><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>REG</span><span> </span><span>ADD</span><span> </span><span>HKLM</span><span>\S</span><span>YSTEM</span><span>\C</span><span>urrentControlSet</span><span>\S</span><span>ervices</span><span>\P</span><span>olicyAgent</span><span> </span><span>/v</span><span> </span><span>AssumeUDPEncapsulationContextOnSendRule</span><span> </span><span>/t</span><span> </span><span>REG_DWORD</span><span> </span><span>/d</span><span> </span><span>0x2</span><span> </span><span>/f</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h5>对于叉屁<a href="#对于叉屁-1"><span>#</span></a></h5><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>REG</span><span> </span><span>ADD</span><span> </span><span>HKLM</span><span>\S</span><span>YSTEM</span><span>\C</span><span>urrentControlSet</span><span>\S</span><span>ervices</span><span>\I</span><span>PSec</span><span> </span><span>/v</span><span> </span><span>AssumeUDPEncapsulationContextOnSendRule</span><span> </span><span>/t</span><span> </span><span>REG_DWORD</span><span> </span><span>/d</span><span> </span><span>0x2</span><span> </span><span>/f</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section><section><h3>然后呢？<a href="#然后呢"><span>#</span></a></h3><p>然后重启！然后重启！然后重启！
之后应该就能正常连接了。</p></section><section><h3>emmm我还是有些无法解决的问题怎么办？<a href="#emmm我还是有些无法解决的问题怎么办"><span>#</span></a></h3><p><a href="https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/README-zh.md" target="_blank">看看脚本作者写的很详细的常见问题排查</a></p></section></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/bilibili-nekopara/</id>
      <title type="text">[已完结] 哔哩哔哩 Nekopara B站网页萌化主题</title>
      <published>2017-09-01T18:01:00.000Z</published>
      <updated>2021-12-11T08:05:06.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/bilibili-nekopara/"/>
      <summary type="text">終わりました。</summary>
      <content type="html"><![CDATA[<p>終わりました。</p>
<hr />
<p>这个样式原本是我开始学 CSS 的时候 xjb 写的一个东西，其实仅仅是为了熟悉各种属性的运用以及积累一些实际经验</p>
<p>N年过去了，回头再看，样式本身其实十分臃肿，另外，B站样式频繁的改版是必然的，并且也使得成为了社畜的我很难维护并维持当时的自己写出来的大杂烩的样子</p>
<p>而且新版B站的 UI 设计很好，我挑不出什么刺来，我觉得我原来大多数 xjb 改的地方都是多余的</p>
<p>所以我决定重新开始做一些微小的工作，仅仅为了 nekopara 而做一个很简单的附加式的皮肤，只保留我之前做的一些 UI 图片资源，剩下的，原来是什么样的，就还是什么样的</p>
<section><h2>附加功能<a href="#附加功能"><span>#</span></a></h2><ul>
<li>去页面推广、广告</li>
<li>隐藏了旧版视频播放器顶部消息栏</li>
<li>对导航栏应用了一些人性化调整</li>
<li>在旧版视频播放界面播放器<strong>全屏</strong>或<strong>网页全屏</strong>状态下，将鼠标放在右侧边缘可呼出播放器右侧面板</li>
</ul></section>
<section><h2>安装<a href="#安装"><span>#</span></a></h2><div><div><div></div><div>Warning</div></div><div><p>由于 userstyles.org 改版，我号登不上了，因此没法在该站继续发布样式更新，现已转至 userstyles.world，请老用户重新安装样式</p></div></div><p><a href="https://userstyles.world/style/2322" target="_blank">点这里打开此样式安装页面</a></p><p>使用前还需要先安装 <a href="https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne" target="_blank">Stylus</a> 插件</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/stylish/</id>
      <title type="text">[Stylish] 使用教程-一个可以让网站变得萌萌哒的插件</title>
      <published>2017-09-01T16:54:00.000Z</published>
      <updated>2018-09-07T16:01:04.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/stylish/"/>
      <summary type="text">Stylish 使用教程 Stylish 由于被爆隐私问题被下架，不再推荐使用，请换用 Stylus 大致说明下 Stylish 是给指定网站应用自己或他人编写的css样式的一款插件，根据作者的设定还可以根据个人需求进行一定程度的定制，Chrome、Firefox、Opera都可以使用。（ie表示很绝望</summary>
      <content type="html"><![CDATA[<hr />
<div><div><div></div><div>Caution</div></div><div><p>Stylish 由于被爆隐私问题被下架，不再推荐使用，请换用 Stylus</p></div></div>
<section><h2>大致说明下<a href="#大致说明下"><span>#</span></a></h2><p>Stylish 是给指定网站应用自己或他人编写的css样式的一款插件，根据作者的设定还可以根据个人需求进行一定程度的定制，Chrome、Firefox、Opera都可以使用。（ie表示很绝望</p></section>
<section><h2>那咋下载叻<a href="#那咋下载叻"><span>#</span></a></h2><ul>
<li>Chrome: <a href="https://www.crx4chrome.com/crx/1184/" target="_blank">crx4chrome</a> 或者 <a href="https://chrome.google.com/webstore/detail/stylish-custom-themes-for/fjnbnpbmkenffdnngjfgmeleoegfcffe" target="_blank">Chrome应用商店（需要翻墙）</a></li>
<li>Firefox: <a href="https://addons.mozilla.org/zh-CN/firefox/addon/stylish/" target="_blank">Stylish :: Firefox 附加组件</a></li>
<li>Opera: <a href="https://addons.opera.com/zh-cn/extensions/details/stylish/" target="_blank">Stylish扩展 - Opera 插件</a></li>
<li>Edge 不知道有没有，听说 Edge 支持扩展插件了，如果能装油猴插件的话好像也可以去弄一个 Stylish 的脚本。</li>
</ul><p>需要注意的是，Chrome浏览器会阻止安装从 crx4chrome 等第三方下载的 crx 插件，如果不能翻墙，那么解决方法请自行百度或使用 360chrome 等国产的有 Chrome 内核的浏览器。</p></section>
<section><h2>装好了，怎么用<a href="#装好了怎么用"><span>#</span></a></h2><p>去 userstyles 可以安装各种样式：<a href="https://userstyles.org" target="_blank">https://userstyles.org</a>
我的 Stylish 作品主页：<a href="https://userstyles.org/users/379643" target="_blank">https://userstyles.org/users/379643</a></p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/ps2017-fu/</id>
      <title type="text">[Photoshop CC 2017] 启动界面萌化</title>
      <published>2017-09-01T16:41:00.000Z</published>
      <updated>2017-11-16T10:10:10.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/ps2017-fu/"/>
      <summary type="text">Ps CC 2017 启动界面 - 芙 说明 这是一个Photoshop CC 2017的启动界面萌化。</summary>
      <content type="html"><![CDATA[<hr />
<section><h2>说明<a href="#说明"><span>#</span></a></h2><p>这是一个Photoshop CC 2017的启动界面萌化。</p></section>
<section><h2>预览图<a href="#预览图"><span>#</span></a></h2><p></p><figure><img src="/usr/uploads/2017/09/925604231.jpg" alt="ps1.jpg" /><figcaption>ps1.jpg</figcaption></figure><p></p><p>pixiv: <a href="http://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=57907745" target="_blank">芙! by Magicians</a>
（Magicians大佬也是我最喜欢的画师之一</p></section>
<section><h2>下载<a href="#下载"><span>#</span></a></h2><p>工具：<a href="http://nullice.com/archives/1859" target="_blank">PsCoser – Photoshop CC 2015/2017 启动图修改器</a>
此主题：<a href="https://pan.baidu.com/s/1qXWsivE" target="_blank">cover<em>CC2017</em>芙</a></p></section>
<section><h2>食用方法<a href="#食用方法"><span>#</span></a></h2><p>注意先以管理员权限打开工具。把下载的主题 zip 文件或者自己制作的主题文件夹拖入 PsCoser 的窗口即可添加主题，或者点击主题列表右边“…”按钮添加主题。然后应用即可，详情应用步骤及细节请参考PsCoser工具的作者的博客页面。</p></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/osu-nekopara/</id>
      <title type="text">[osu] Nekopara V3.1</title>
      <published>2017-09-01T16:07:00.000Z</published>
      <updated>2018-01-30T12:58:24.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/osu-nekopara/"/>
      <summary type="text">osu! Skin - Nekopara 说明 这是一个我东拼西凑并自己魔改部分样式的 osu 皮肤。</summary>
      <content type="html"><![CDATA[<hr />
<section><h2>说明<a href="#说明"><span>#</span></a></h2><p>这是一个我东拼西凑并自己魔改部分样式的 osu 皮肤。</p></section>
<section><h2>预览图<a href="#预览图"><span>#</span></a></h2><section><h3>主界面<a href="#主界面"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/2389650833.jpg" alt="osu1.jpg" /><figcaption>osu1.jpg</figcaption></figure><p></p></section><section><h3>选曲界面<a href="#选曲界面"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/3360653020.jpg" alt="osu4.jpg" /><figcaption>osu4.jpg</figcaption></figure><p></p></section><section><h3>选mod界面<a href="#选mod界面"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/1740631272.jpg" alt="osu2.jpg" /><figcaption>osu2.jpg</figcaption></figure><p></p></section><section><h3>游戏界面<a href="#游戏界面"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/3155511574.jpg" alt="osu5.jpg" /><figcaption>osu5.jpg</figcaption></figure><p></p></section><section><h3>结算界面<a href="#结算界面"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/234968212.jpg" alt="osu3.jpg" /><figcaption>osu3.jpg</figcaption></figure><p></p></section></section>
<section><h2>下载<a href="#下载"><span>#</span></a></h2><ul>
<li><a href="http://www.multcloud.com/share/dc54151d-0f41-4f25-ac1f-0df722af2e48" target="_blank">MultCloud (From GoogleDrive)</a></li>
<li><a href="https://1drv.ms/f/s!AuORJSWCcMcrg2QISN5VV-I87Jpi" target="_blank">OneDrive</a></li>
<li><a href="https://pan.baidu.com/s/1c17DRWk" target="_blank">百度云</a></li>
</ul></section>
<section><h2>食用方法<a href="#食用方法"><span>#</span></a></h2><p>注：带”TAG”字样的为针对接力模式优化的皮肤，方便在多人游戏时crtl+o直接设置切换皮肤</p><p>有三种方法：</p><ol>
<li>直接打开osz文件即可（前提是有文件关联）</li>
<li>打开osu，然后把osz文件拖进去</li>
<li>用压缩文件查看器打开然后解压到osu根目录的skin文件夹中</li>
</ol></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/baidu-moe/</id>
      <title type="text">[Stylish] 百度萌化样式</title>
      <published>2017-09-01T15:39:00.000Z</published>
      <updated>2020-01-21T11:48:23.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/baidu-moe/"/>
      <summary type="text">百度萌化样式 此早期黑历史已经停止维护 简介 此Stylish样式为百度系列的萌化，优化了部分显示效果，屏蔽了一些无用元素及广告推广。 背景图片可以自行设置。</summary>
      <content type="html"><![CDATA[<hr />
<div><div><div></div><div>Caution</div></div><div><p>此早期黑历史已经停止维护</p></div></div>
<section><h2>简介<a href="#简介"><span>#</span></a></h2><p>此Stylish样式为百度系列的萌化，优化了部分显示效果，屏蔽了一些无用元素及广告推广。
背景图片可以自行设置。</p></section>
<section><h2>预览图<a href="#预览图"><span>#</span></a></h2><section><h3>主页<a href="#主页"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/2735501547.jpg" alt="baidu2.jpg" /><figcaption>baidu2.jpg</figcaption></figure><p></p></section><section><h3>搜索结果页面<a href="#搜索结果页面"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/3869073170.jpg" alt="baidu1.jpg" /><figcaption>baidu1.jpg</figcaption></figure><p></p></section><section><h3>百度云<a href="#百度云"><span>#</span></a></h3><p></p><figure><img src="/usr/uploads/2017/09/2674630388.jpg" alt="baidu3.jpg" /><figcaption>baidu3.jpg</figcaption></figure><p></p><p>示例所用背景图片：
pixiv: <a href="http://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=51459095" target="_blank">岛风 by みゅとん</a>
Zinsser: <a href="http://zinsser.me/web/paint/show_51.html" target="_blank">艾拉 by zinsser</a></p></section></section>
<section><h2>样式说明<a href="#样式说明"><span>#</span></a></h2><p>样式目前主要应用范围：</p><ul>
<li>百度搜索</li>
<li>百度网盘</li>
</ul><p><span><b>请将百度云的皮肤设置为除了前三个默认皮肤之外的皮肤，推荐“月半弯”，色调比较配</b></span></p><p>如果发现了什么问题或者bug，都可以在这里反馈，这样我就能第一时间收到</p></section>
<section><h2>安装<a href="#安装"><span>#</span></a></h2><p><a href="https://userstyles.org/styles/136284/baidu" target="_blank">点这里打开此stylish样式页面</a></p><p>不知道怎么使用stylish萌化请看：</p><a href="/posts/stylish/"><div><div>[Stylish] 使用教程-一个可以让网站变得萌萌哒的插件</div><div>Stylish 使用教程 Stylish 由于被爆隐私问题被下架，不再推荐使用，请换用 Stylus 大致说明下 Stylish 是给指定网站应用自己或他人编写的css样式的一款插件，根据作者的设定还可以根据个人需求进行一定程度的定制，Chrome、Firefox、Opera都可以使用。（ie表示很绝望</div><div><span>2017-09-01</span><span>教程</span><span><span>#stylish</span><span>#浏览器扩展</span><span>#网页美化</span><span>#css</span></span></div></div><div><img src="/usr/uploads/2017/09/187271807.png" alt="" loading="lazy" /></div></a></section>]]></content>
    </entry>
    <entry>
      <id>https://moe.best/posts/we-okita-souji/</id>
      <title type="text">[Wallpaper Engine 动态壁纸] FGO - 沖田総司 飘雪 1080P(waifu2x) 60fps</title>
      <published>2017-09-01T15:16:00.000Z</published>
      <updated>2018-01-30T12:38:42.000Z</updated>
      <author><name>神代綺凛</name></author>
      <link rel="alternate" href="https://moe.best/posts/we-okita-souji/"/>
      <summary type="text">WE 动态壁纸 冲田总司 说明 这是一个我自制自用的Wallpaper Engine动态壁纸</summary>
      <content type="html"><![CDATA[<hr />
<section><h2>说明<a href="#说明"><span>#</span></a></h2><p>这是一个我自制自用的Wallpaper Engine动态壁纸</p><blockquote><p>Wallpaper Engine是由Kristjan Skutta所开发的一款动态壁纸软件，区别于其他形式的壁纸软件，Wallpaper Engine可以让用户通过其引擎深度的自定义或编辑与创作出符合个人需求的壁纸样式。
支持各种类型的壁纸，包括2D和3D动画，网站，视频，甚至某些应用程序。</p></blockquote><p>Wallpaper Engine可以在Steam上购买，售价18块（不知道现在价格变了没）</p><hr /><p>本壁纸所使用的背景
</p><figure><img src="/usr/uploads/2017/09/1750154548.jpg" alt="59665299_p0.jpg" /><figcaption>59665299_p0.jpg</figcaption></figure><p></p><p>pixiv: <a href="https://www.pixiv.net/member_illust.php?mode=medium&amp;illust_id=59665299" target="_blank">FGO沖田総司 by 光崎</a>
(kousaki，是我最喜欢的画师之一</p></section>
<section><h2>使用方法<a href="#使用方法"><span>#</span></a></h2><p>首先你需要拥有Wallpaper Engine，然后
<a href="https://steamcommunity.com/sharedfiles/filedetails/?id=823342366" target="_blank">点这里打开此steam创意工坊项目页面</a>
点击绿色的“订阅”按钮即可，这时候Steam应该会自动将此壁纸添加到下载队列中</p></section>]]></content>
    </entry>
</feed>
