<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Neokoni&#39;s Blog</title>
  
  <subtitle>write,document and share</subtitle>
  <link href="https://blog.neokoni.ink/rss.xml" rel="self"/>
  
  <link href="https://blog.neokoni.ink/"/>
  <updated>2026-08-09T05:32:53.759Z</updated>
  <id>https://blog.neokoni.ink/</id>
  
  <author>
    <name>Neokoni</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>ArchLinuxArm游玩OSU!Lazer指北</title>
    <link href="https://blog.neokoni.ink/2025/08/10/archlinuxarm%E6%B8%B8%E7%8E%A9osu/"/>
    <id>https://blog.neokoni.ink/2025/08/10/archlinuxarm%E6%B8%B8%E7%8E%A9osu/</id>
    <published>2025-08-10T16:43:14.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>Neokoni由于人在外地没有电脑, 故只能讲之前买的丐版<code>小米平板5</code>刷入<code>ArchLinuxArm</code>作为生产力</p><p>偶然想玩osu,但是似乎没有关于archlinuxarm的安装指南, 且aur直接安装当时也出了一点问题</p><p>于是便有了这篇文章…</p><p>就连这篇文章都是在小米平板5上写的, 新的First</p><h2 id="环境介绍"><a href="#环境介绍" class="headerlink" title="环境介绍"></a>环境介绍</h2><p>主包的超低配丐版小米平板5, 购买了配套键盘和一个蓝牙鼠标</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">[Neokoni@archlinux ~]$ uwufetch</span><br><span class="line">                     Neokoni@archlinux</span><br><span class="line">        /\           OWOS     Nyarch Linuwu</span><br><span class="line">       /  \          MOWODEL  Pad 5</span><br><span class="line">      /\   \         KEWNEL   Linuwu 6.14.0-1-nabu-gdefb39db31e6-dirty aarch64             </span><br><span class="line">     / &gt; ω &lt;\        CPUWU    8 Cowes</span><br><span class="line">    /   __   \       MEMOWY   4072 MiB/5344 MiB</span><br><span class="line">   / __|  |__-\      SHEWW    /bin/bash</span><br><span class="line">  /_-<span class="string">&#x27;&#x27;</span>    <span class="string">&#x27;&#x27;</span>-_\     PKGS     967: 967 (pacman)</span><br><span class="line">                     UWUPTIME 9h, 19m</span><br></pre></td></tr></table></figure><p>详细配置如<code>Banner</code>所示<br><img src="/../picture/archlinuxarm-osu/banner.png" alt="hardware-info"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><h2 id="1-安装AUR工具"><a href="#1-安装AUR工具" class="headerlink" title="1. 安装AUR工具"></a>1. 安装AUR工具</h2><p>整个安装过程都通过<code>AUR</code>来实现安装, 那么第一步就是安装<code>AUR</code>工具, 这里使用<code>yay</code></p><div class="trm-note info"><div class="trm-note-title">INFO</div><p><code>paru</code>也可以, 只不过是我觉得没有多大差别, 因此还是停留在<code>yay</code></p></div><p>那么第一步就是添加<code>ArchLinuxCN源</code></p><p>首先, 在<code>/etc/pacman.conf</code>文件中添加以下内容</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[archlinuxcn]</span><br><span class="line">Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch</span><br></pre></td></tr></table></figure><p>我这里使用<code>ustc源</code>, 其他可用的<code>ArchLinuxCN源</code>也可以使用</p><p>接着安装AUR工具yay</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo pacman -Sy</span><br><span class="line">sudo pacman -S archlinuxcn-keyring</span><br><span class="line">sudo pacman -S yay</span><br></pre></td></tr></table></figure><h2 id="从AUR安装OSU-Lazer"><a href="#从AUR安装OSU-Lazer" class="headerlink" title="从AUR安装OSU!Lazer"></a>从AUR安装OSU!Lazer</h2><p><code>OSU!Lazer</code>官方对Linux平台仅提供了<code>x86_64</code>平台的预编译产物</p><p>因此我们需要通过安装<code>osu-lazer</code>包进行本地编译打包安装</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yay -S osu-lazer</span><br></pre></td></tr></table></figure><p>安装的时候会提示<code>不支持aarch64</code>并询问是否继续, 请点击<code>确定</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">[Neokoni@archlinux ~]$ yay -S osu-lazer</span><br><span class="line">AUR Explicit (1): osu-lazer-2025.710.0-1</span><br><span class="line">:: PKGBUILD 是最新的，跳过下载: osu-lazer</span><br><span class="line">  1 osu-lazer                                (已安装) (构建文件已存在)</span><br><span class="line">==&gt; 清理哪些包的构建文件？</span><br><span class="line">==&gt; [N]没有 [A]全部 [Ab]中止 [I]已安装 [No]未安装 或 (1 2 3, 1-3, ^4)</span><br><span class="line">==&gt; </span><br><span class="line">  1 osu-lazer                                (已安装) (构建文件已存在)</span><br><span class="line">==&gt; 显示哪些包的差异？</span><br><span class="line">==&gt; [N]没有 [A]全部 [Ab]中止 [I]已安装 [No]未安装 或 (1 2 3, 1-3, ^4)</span><br><span class="line">==&gt; </span><br><span class="line">==&gt; 错误： osu-lazer 不具备 <span class="string">&#x27;aarch64&#x27;</span> 架构。</span><br><span class="line"> -&gt; 下载源文件时出错: /home/Neokoni/.cache/yay/osu-lazer </span><br><span class="line">         context: <span class="built_in">exit</span> status 12 </span><br><span class="line">         </span><br><span class="line"></span><br><span class="line">:: (1/1) 正在解析 SRCINFO: osu-lazer</span><br><span class="line"> -&gt; 下列软件包与你的系统架构不兼容:</span><br><span class="line">  osu-lazer</span><br><span class="line">:: 依然尝试构建吗？ [Y/n] y</span><br></pre></td></tr></table></figure><p>然后静待编译打包安装完成</p><h2 id="安装其他依赖"><a href="#安装其他依赖" class="headerlink" title="安装其他依赖"></a>安装其他依赖</h2><p>与<code>x86_64</code>平台不同, <code>aarch64</code>需要额外的一些依赖才能正常运行</p><p>这些依赖并未在<code>PKGBUILD</code>中声明, 因为<code>x86_64</code>平台似乎并不需要, <code>osu-lazer</code>包也只声明了支持<code>x86_64</code>平台</p><p>如果你在直接安装完<code>OSU!Lazer</code>后发现报错<code>核心已转储</code>, 会不会认为没戏了呢?</p><p>但其实在报错的开头就会提示, 找不到<code>libbass</code>的三个<code>.so</code>文件</p><p>所以我们需要通过<code>AUR</code>安装他们</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yay -S libbass libbass_fx libbassmix</span><br></pre></td></tr></table></figure><div class="trm-note info"><div class="trm-note-title">INFO</div><p><code>libbassmix</code>包在<code>2025/08/10</code>前因为<code>PKGBUILD</code>的问题并不能在非<code>x86_64</code>平台上正常使用, 即使<code>un4seen</code>打包过它们</p><p>不过这个问题已得到咱的修复, 现已可正常使用</p></div><h2 id="享受osu吧"><a href="#享受osu吧" class="headerlink" title="享受osu吧"></a>享受osu吧</h2><p>不出意外, 在你的<code>ArchLinuxArm</code>系统上应该可以正常运行<code>OSU!Lazer</code>了</p><p>如果你也是<code>小米平板5</code>用户, 我推荐你更改部分画面设置</p><p>全屏状态下,分辨率推荐<code>1920x1200</code>, 不限制帧率, 使用<code>vulkan</code>渲染器</p><h2 id="结尾"><a href="#结尾" class="headerlink" title="结尾"></a>结尾</h2><p>我还得再用一个月的小米平板5作为主要生产力QAQ…</p>]]></content>
    
    
    <summary type="html">使用AUR在ArchLinuxArm上快速安装OSU!Lazer并最终游玩</summary>
    
    
    
    
    <category term="折腾" scheme="https://blog.neokoni.ink/tags/%E6%8A%98%E8%85%BE/"/>
    
    <category term="教程" scheme="https://blog.neokoni.ink/tags/%E6%95%99%E7%A8%8B/"/>
    
  </entry>
  
  <entry>
    <title>历时N天解决Bing索引归零</title>
    <link href="https://blog.neokoni.ink/2025/03/26/%E5%8E%86%E6%97%B6N%E5%A4%A9%E8%A7%A3%E5%86%B3Bing%E7%B4%A2%E5%BC%95%E5%BD%92%E9%9B%B6/"/>
    <id>https://blog.neokoni.ink/2025/03/26/%E5%8E%86%E6%97%B6N%E5%A4%A9%E8%A7%A3%E5%86%B3Bing%E7%B4%A2%E5%BC%95%E5%BD%92%E9%9B%B6/</id>
    <published>2025-03-26T17:49:03.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="故事的开始"><a href="#故事的开始" class="headerlink" title="故事的开始"></a>故事的开始</h2><p>2024年11月末开始，bing webmaster的后台数据出现异常，索引数量开始慢慢减少，且无法在bing搜索到自己的网站</p><p>当时并未在意，直到2025年1月份，bing webmaster索引完全归零，才开始补救</p><p><img src="/../picture/bing_index/datapanel.png" alt="webmster数据"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><h2 id="症状"><a href="#症状" class="headerlink" title="症状"></a>症状</h2><p>以我自己为例子，网站被bing屏蔽会出现以下几个症状。</p><ul><li><p>无法通过site:域名 搜索到自己的网站</p></li><li><p>webmaster索引减少至0</p></li><li><p>每日可提交url数量为10</p></li><li><p>站点管理器无数据(后期)</p></li><li><p>无任何通知，包括版权删除声明</p></li></ul><p>如果你也有同样的问题，请看下方解决方法。</p><h2 id="处理网站问题"><a href="#处理网站问题" class="headerlink" title="处理网站问题"></a>处理网站问题</h2><h3 id="1-优化网站质量"><a href="#1-优化网站质量" class="headerlink" title="1.优化网站质量"></a>1.优化网站质量</h3><p>首先，你需要优化你的网站质量，确保你的网站符合bing的规则。</p><p>bing webmaster有两个提供修改意见的工具，他们会给出网站的质量问题及修改建议</p><p>对于往期的检测，可以查看<code>Recommendations</code>页面</p><p>对于即时页面质量评估，可以使用<code>网站扫描</code>功能</p><p>常见的问题包括图像未设置alt内容，H1标签过多等问题</p><p>请确保你的网站修改后可以让工具显示<code>无任何问题</code>，此时我们可以开启下一步的操作。</p><h3 id="2-确保符合bing站点要求"><a href="#2-确保符合bing站点要求" class="headerlink" title="2.确保符合bing站点要求"></a>2.确保符合bing站点要求</h3><p>bing webmaster在<code>url检查</code>页面提供了<code>实时url</code>工具，用于检测你的网站是否符合bing站点要求</p><p>使用此工具检查网站的url,确保它们符合bing的规则，并显示‘该 URL 可以由必应编制索引’</p><p><img src="/../picture/bing_index/couldindex.png" alt="该 URL 可以由必应编制索引"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>到此我们完成了对网站内容的优化，接下来，我们开始联系bing的工作人员进行审核</p><h2 id="请求审核"><a href="#请求审核" class="headerlink" title="请求审核"></a>请求审核</h2><p>虽然bing webmaster提供了网页的问题提交工具，但是十分不建议使用。</p><p>此工具大概率在发送一封提交成功的邮件后就没有然后了。如果运气好，那么问题会被提交到下一阶段</p><p>因此推荐直接使用webmaster中的<code>Copilot</code>或直接向<code>bwtsupport@microsoft.com</code>发送邮件</p><p>使用<code>Copilot</code>时请直接发送你请求的内容并附上域名，Copilot会无法识别问题，自动提交ticket</p><p>向<code>bwtsupport@microsoft.com</code>发送邮件时，也请写上你要求的内容和你的域名</p><p>无论是使用<code>Copilot</code>还是直接发送邮件，请都使用英文进行交流</p><p>在收到确认的邮件后，请耐心等待回复即可。通常确认邮件会有以下内容</p><blockquote><p>This email is confirmation that we have received your request and created the following UCM Ticket UCM0000xxxxxxxx. Your ticket is being assigned to a Global Support Webmaster Engineer who will be contacting you about the next steps to resolve your issue.</p></blockquote><div class="trm-note warning"><div class="trm-note-title">WARNING</div><p>不是所有的bing的工作人员都会通过审核。</p><p>如果提示未通过审核，且你确定你的站点绝对符合bing的要求</p><p>请在一两天后再次开启新的ticket</p><p>不要回复原邮件，这会导致原ticket持续开启，阻止新ticket创建，最终只是浪费时间</p></div><p>以下是我当时的邮件内容，仅供参考</p><blockquote><p>标题：plz check my site again</p><p>My website blog.neokonk.ink had disappeared index last year October. I had contacted bing webmaster tool team for help, you told me that I need fix mistakes of my site and enchant quality </p><p>Bing webmaster teams said that they’ll check mouth later last month, now it’s March, next month of February </p><p>Now I’ve fix everything, hope you can check again and estimate it</p></blockquote><h2 id="可能有用的事情？"><a href="#可能有用的事情？" class="headerlink" title="可能有用的事情？"></a>可能有用的事情？</h2><p>在这期间我完成了对域名的备案，这一点想法来自于我另一个当时已经备案的域名。</p><p>那一个域名的状态一切正常，因此怀疑是否与这个原因有关</p><h2 id="恢复后"><a href="#恢复后" class="headerlink" title="恢复后"></a>恢复后</h2><p>在恢复索引后，第一个特征就是‘URL提交’每日额度已经恢复了100</p><p>此时我推荐通过‘indexnow’和‘bing webmaster api‘等方式向bing主动提交url,加速索引恢复</p><p>同时在以后的文章中重视seo优化，避免再次出现类似问题</p><p>最后祝大家都能恢复自己的索引！</p>]]></content>
    
    
    <summary type="html">在一个月黑风高的夜晚，Neokoni的域名悄悄消失在了搜索引擎的世界中。起初，Neokoni并没有在意，直到Neokoni意识到不对劲。在经过长达N天的不断处理，终于，Neokoni的域名被解除了屏蔽！并写下了这篇记录。</summary>
    
    
    
    
    <category term="笔记，记录，教程" scheme="https://blog.neokoni.ink/tags/%E7%AC%94%E8%AE%B0%EF%BC%8C%E8%AE%B0%E5%BD%95%EF%BC%8C%E6%95%99%E7%A8%8B/"/>
    
  </entry>
  
  <entry>
    <title>Bukkit插件适配Folia指北</title>
    <link href="https://blog.neokoni.ink/2025/01/11/Bukkit%E6%8F%92%E4%BB%B6%E9%80%82%E9%85%8DFolia%E6%8C%87%E5%8C%97/"/>
    <id>https://blog.neokoni.ink/2025/01/11/Bukkit%E6%8F%92%E4%BB%B6%E9%80%82%E9%85%8DFolia%E6%8C%87%E5%8C%97/</id>
    <published>2025-01-11T17:04:27.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="新年快乐！"><a href="#新年快乐！" class="headerlink" title="新年快乐！"></a>新年快乐！</h2><p>作为2025年第一篇博客，我觉得我可以在这留下这句祝愿，祝你我在新的一年里事事顺利，心想事成！</p><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p><a href="https://papermc.io/software/folia">Folia</a>作为第一个正真意义上的多线程Minecraft服务端，插件系统不一定兼任Bukkit传统的插件。</p><p>但是它的发展潜力依然非常大。</p><p>随着越来越多人开始关注它，越来越多的传统Bukkit插件陆陆续续开始适配Folia。但是Slimefun却不是</p><p>可能因为其庞大的代码量或者对Folia前景并没太大希望，Slimefun<a href="https://github.com/Slimefun/Slimefun4/issues/4217">并未计划适配Folia</a></p><p>在看到友商的Folia服务端性能表现后，我决定下个周目也使用Folia或其优化分支作为服务端。  </p><p>但是作为传统玩Slimefun的服务器，Slimefun并不适配。那怎么办？自己适配</p><p>故撰写此文章大致分享适配流程，按照我适配Slimefun的插件适配Folia的流程作为例子</p><div class="trm-note warning"><div class="trm-note-title">WARNING</div><p>本指北涉及插件源代码的修改且需要具有一定的Java语法基础，请提前确定自己熟悉基础的Java语法且可以修改插件源代码</p><p>有些内容是我自己的理解，可能不一定正确</p></div><h2 id="差异性"><a href="#差异性" class="headerlink" title="差异性"></a>差异性</h2><p>先引用一段来自于PaperMC官方在Folia仓库README的描述(由边缘浏览器翻译)</p><blockquote><p>Bukkit Scheduler.Bukkit Scheduler 本身 依赖于单个主线程。Folia 的 RegionScheduler 和 Folia 的 EntityScheduler 允许将任务调度到任何 “next tick” 区域 “拥有” 位置或实体。这些是可以实现的 在常规 Paper 上，除了它们调度到主线程 - 在这两种情况下， 任务的执行将发生在 “拥有” location 或 entity。这个概念通常适用，因为目前的 Paper （单线程）可以看作是一个巨大的“区域”，它包括 所有世界中的所有区块。</p></blockquote><p>这里的<code>Scheduler</code>就是适配的关键</p><p>在Bukkit中，<code>Scheduler</code>是Bukkit插件开发中一个重要的概念，它用于管理插件中的任务调度，定义了插件中任务的基本操作，如启动、取消、延迟执行等。</p><p>可以看到，PaperMC在Folia中将<code>Scheduler</code>进行了优化，将其分为例如<code>GloablRegionScheduler</code>,<code>RegionScheduler</code>和<code>EntityScheduler</code>等不同类型的调度器，以实现对不同的调度。</p><p>在Folia的JavaDoc中，PaperMC已经将Bukkit Scheduler标记为了已弃用Deprecated。<br><img src="/../picture/bukkit-plugins-on-folia/bukkit-scheduler-deprecated.png" alt="deprecated"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><h2 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h2><p>理论上，我们只需要将原本由BukkitAPI提供的<code>BukkitScheduler</code>改写为由PaperAPI提供的<code>GloablRegionScheduler</code>，<code>RegionScheduler</code>和<code>EntityScheduler</code>，并改写<code>聊天</code>和<code>传送</code>等一起被废弃的旧API即可</p><p>如果要兼任Bukkit插件，只需要做一个服务器类型的判断，是Folia就使用<code>GloablRegionScheduler</code>,<code>RegionScheduler</code>和<code>EntityScheduler</code>，否则使用<code>BukkitScheduler</code>即可</p><h2 id="避免重复造轮子"><a href="#避免重复造轮子" class="headerlink" title="避免重复造轮子"></a>避免重复造轮子</h2><p>查看大部分插件适配Folia的代码，主要分为两类</p><ul><li><p>使用第三方包装库进行适配</p></li><li><p>自写或合并包装库适配</p></li></ul><p>例如CoreProtect自写适配Utiles类，Mcmmo使用第三方包装库FoliaLib进行适配</p><p>本篇主要以使用第三方包装库进行适配为例，使用<a href="https://github.com/TechnicallyCoded/FoliaLib">FoliaLib</a>进行适配，使用Idea作为编辑器</p><h2 id="需要支持旧版本吗"><a href="#需要支持旧版本吗" class="headerlink" title="需要支持旧版本吗"></a>需要支持旧版本吗</h2><div class="trm-note info"><div class="trm-note-title">INFO</div><p>此部分于2025-07-14加入</p></div><p>如果不考虑修改后插件对非paper服务端且服务端低于1.20.1后的兼容性，可以考虑不使用FoliaLib进行适配</p><p>以此可以降低使用FoliaLib进行适配打包的大小(x)</p><p>Paper在从1.20.1起加入了对Folia的Scheduler的兼容，使Folia的Scheduler原生可在Paper运行</p><h2 id="Folia原生Scheduler"><a href="#Folia原生Scheduler" class="headerlink" title="Folia原生Scheduler"></a>Folia原生Scheduler</h2><div class="trm-note info"><div class="trm-note-title">INFO</div><p>此部分于2025-07-14加入</p></div><p>在Folia中Scheduler分为了<code>getGlobalRegionScheduler()</code>，<code>getRegionScheduler()</code>，<code>getAsyncScheduler()</code>和需要从实体中获取的<code>getScheduler()</code></p><p>下文将从实体中获取的Scheduler称为<code>getEntityScheduler</code>作为与Bukkit中<code>getScheduler</code>的区分</p><p>其中又主要分为<code>run</code>，<code>runDelayed</code>和<code>runAtFixedRate</code></p><p>使用也很简单，除了EntityScheduler外，其他都可以使用Bukkit.’上文提到的Sceduler’进行获取，然后再使用.run的方法</p><p>以下是对Bukkit的传统Scheduler进行使用的比较</p><ul><li><p><code>Bukkit.getScheduler().runTask</code> –&gt; <code>Bukkit.getGlobalRegionScheduler().run</code></p></li><li><p><code>Bukkit.getScheduler().runTaskAsynchronously</code> –&gt; <code>Bukkit.getAsyncScheduler().run</code></p></li><li><p><code>Bukkit.getScheduler().runTaskLater</code> –&gt; <code>Bukkit.getGlobalRegionScheduler().runDelayed</code></p></li><li><p><code>Bukkit.getScheduler().runTaskTimerAsynchronously</code> –&gt; <code>Bukkit.getGlobalRegionScheduler().runAtFixedRate</code></p></li><li><p><code>Bukkit.getScheduler().runTaskLaterAsynchronously</code> –&gt; <code>Bukkit.getAsyncScheduler().runDelayed</code></p></li><li><p><code>Bukkit.getScheduler().scheduleSyncDelayedTask</code> –&gt; <code>Bukkit.getGlobalRegionScheduler().runDelayed</code></p></li><li><p><code>Bukkit.getScheduler().scheduleSyncRepeatingTask</code> –&gt; <code>Bukkit.getGlobalRegionScheduler().runAtFixedRate</code></p></li></ul><p>如果你需要使用RegionScheduler，请使用<code>getRegionScheduler()</code>，而不是使用getGlobalRegionScheduler</p><p>使用RegionScheduler比GlobalRegionScheduler需要多传入一个Location类型的参数，用于获取Region</p><p>更多请参考PaperMC的JavaDoc</p><h2 id="引入FoliaLib"><a href="#引入FoliaLib" class="headerlink" title="引入FoliaLib"></a>引入FoliaLib</h2><h3 id="添加依赖"><a href="#添加依赖" class="headerlink" title="添加依赖"></a>添加依赖</h3><p>最新版本如下，请将<code>pom.xml</code>中的<code>&lt;version&gt;</code>改为最新版本号<a href=""><img src="https://img.shields.io/github/release/technicallycoded/FoliaLib.svg?style=flat" alt="GitHub Release"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></a></p><h4 id="Maven"><a href="#Maven" class="headerlink" title="Maven"></a>Maven</h4><p>在<code>pom.xml</code>中添加依赖,如下</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">repositories</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">repository</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">id</span>&gt;</span>tcoded-releases<span class="tag">&lt;/<span class="name">id</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">url</span>&gt;</span>https://repo.tcoded.com/releases<span class="tag">&lt;/<span class="name">url</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">repository</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">repositories</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>com.tcoded<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>FoliaLib<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>改为上方标签显示的版本号<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">scope</span>&gt;</span>compile<span class="tag">&lt;/<span class="name">scope</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">build</span>&gt;</span></span><br><span class="line">    </span><br><span class="line">    <span class="tag">&lt;<span class="name">plugins</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!-- 导入shadow插件，如已导入，则将下列配置插入到plugins标签下 --&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">plugin</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.apache.maven.plugins<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>maven-shade-plugin<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">version</span>&gt;</span>3.6.0<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">executions</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">execution</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">phase</span>&gt;</span>package<span class="tag">&lt;/<span class="name">phase</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">goals</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">goal</span>&gt;</span>shade<span class="tag">&lt;/<span class="name">goal</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;/<span class="name">goals</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">execution</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">executions</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">configuration</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">relocations</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;<span class="name">relocation</span>&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">pattern</span>&gt;</span>com.tcoded.folialib<span class="tag">&lt;/<span class="name">pattern</span>&gt;</span></span><br><span class="line">                        <span class="comment">&lt;!-- !! 请确保将这里改为你插件的组名或插件名 !! --&gt;</span></span><br><span class="line">                        <span class="tag">&lt;<span class="name">shadedPattern</span>&gt;</span>组名.插件名.lib.folialib<span class="tag">&lt;/<span class="name">shadedPattern</span>&gt;</span></span><br><span class="line">                    <span class="tag">&lt;/<span class="name">relocation</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;/<span class="name">relocations</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">configuration</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">plugin</span>&gt;</span></span><br><span class="line">        <span class="comment">&lt;!-- 终止线 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">plugins</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">build</span>&gt;</span></span><br></pre></td></tr></table></figure><h4 id="Gradle"><a href="#Gradle" class="headerlink" title="Gradle"></a>Gradle</h4><p>在<code>build.gradle.kts</code>中添加依赖,如下</p><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">plugins &#123;</span><br><span class="line">    id <span class="string">&#x27;com.github.johnrengelman.shadow&#x27;</span> version <span class="string">&#x27;8.1.1&#x27;</span> <span class="comment">// Java 17使用</span></span><br><span class="line">    <span class="comment">// id &#x27;io.github.goooler.shadow&#x27; version &#x27;8.1.7&#x27; // Java 21或更高版本使用</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">repositories &#123;</span><br><span class="line">    maven &#123;</span><br><span class="line">        name = <span class="string">&quot;tcoded-releases&quot;</span></span><br><span class="line">        url = <span class="string">&quot;https://repo.tcoded.com/releases&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">dependencies &#123;</span><br><span class="line">    implementation <span class="string">&quot;com.tcoded:FoliaLib:改为上方显示的版本号&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">shadowJar &#123;</span><br><span class="line">    <span class="comment">// !! 请确保将这里改为你插件的组名或插件名</span></span><br><span class="line">    relocate <span class="string">&quot;com.tcoded.folialib&quot;</span>, <span class="string">&quot;组名.插件名.lib.folialib&quot;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// Optional: If you use minimize, make sure you exclude FoliaLib</span></span><br><span class="line">    <span class="comment">// Do not uncomment this if you don&#x27;t know what you are doing</span></span><br><span class="line">    <span class="comment">// minimize &#123;</span></span><br><span class="line">    <span class="comment">//     exclude dependency(&quot;com.github.technicallycoded:FoliaLib:.*&quot;)</span></span><br><span class="line">    <span class="comment">// &#125;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><div class="trm-note info"><div class="trm-note-title">INFO</div><p>2025-07-14改：指向FoliaLib 0.5.1后使用的自托管库</p></div><h3 id="初始化FoliaLib"><a href="#初始化FoliaLib" class="headerlink" title="初始化FoliaLib"></a>初始化FoliaLib</h3><p>编辑插件的主文件(onEnable方法的那个文件)，在项目中合理的地方合并插入以下代码<br><strong>写法并不唯一，这里只是一个示例</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> com.tcoded.folialib.FoliaLib;</span><br><span class="line"><span class="keyword">import</span> com.tcoded.folialib.wrapper.task.WrappedTask;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> class 插件名 &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> FoliaLib foliaLib;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onEnable</span><span class="params">()</span> &#123;</span><br><span class="line">        foliaLib = <span class="keyword">new</span> <span class="title class_">FoliaLib</span>(<span class="built_in">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> FoliaLib <span class="title function_">getFoliaLib</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> foliaLib;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>之后即可通过调用主类获取FoliaLib实例，如<code>Slimefun.getFoliaLib().getScheduler()</code></p><h2 id="代替BukkitScheduler"><a href="#代替BukkitScheduler" class="headerlink" title="代替BukkitScheduler"></a>代替BukkitScheduler</h2><h3 id="一般Scheduler"><a href="#一般Scheduler" class="headerlink" title="一般Scheduler"></a>一般Scheduler</h3><p>只导入是不行的，需要使用FoliaLib提供的<code>Scheduler</code>类代替才可以适配  </p><p>FoliaLib提供的<code>Scheduler</code>类与BukkitScheduler类似，但在<code>命名</code>和<code>传入参数</code>等有少许不同，如类名</p><ul><li><p><code>runTask</code> –&gt; <code>runNextTick</code></p></li><li><p><code>runTaskAsynchronously</code> –&gt; <code>runAsync</code></p></li><li><p><code>runTaskLater</code> –&gt; <code>runLater</code></p></li><li><p><code>runTaskTimerAsynchronously</code> –&gt; <code>runTimerAsync</code></p></li><li><p><code>runTaskLaterAsynchronously</code> –&gt; <code>runLaterAsync</code></p></li><li><p><code>scheduleSyncDelayedTask</code> –&gt; <code>runLater</code></p></li><li><p><code>scheduleSyncRepeatingTask</code> –&gt; <code>runTimer</code></p></li></ul><p>这并非所有的类，更多类需要按自己需求选择</p><p>在传入参数中，foliaLib并不需要输入<code>Plugin</code>类的参数，其他参数大致不变，分为<code>Runnable</code>和<code>Consumer&lt;WrappedTask&gt;</code>类的参数，其中<code>Runnable</code>和<code>Consumer&lt;WrappedTask&gt;</code>类只会出现一次，不会同时要求提供两个参数</p><h3 id="Task类"><a href="#Task类" class="headerlink" title="Task类"></a>Task类</h3><p>需要将原来使用的<code>BukkitTask</code>类替换为<code>WrappedTask</code>类，两者可以平滑替换，最多是未导入包的报错，但是BukkitScheduler并不能接受<code>WrappedTask</code>类，WrappedTask类也是一样，所以一定要一一对应</p><h3 id="Scheduler类的Lambda表达式"><a href="#Scheduler类的Lambda表达式" class="headerlink" title="Scheduler类的Lambda表达式"></a>Scheduler类的Lambda表达式</h3><p>一般的<code>() -&gt; &#123; &#125;</code>并不需要特别更改，但是如果有Idea报错的，如这种，可以参照如下示例更改</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="deletion">- Bukkit.getScheduler().scheduleSyncDelayedTask(this, new AutoUpdateTask(this, getFile()));</span></span><br><span class="line"><span class="addition">+ getFoliaLib().getScheduler().runAsync(wrappedTask -&gt;  new AutoUpdateTask(this, getFile()));</span></span><br></pre></td></tr></table></figure><h3 id="TaskID的改写"><a href="#TaskID的改写" class="headerlink" title="TaskID的改写"></a>TaskID的改写</h3><p>在BukkitScheduler中，<code>BukkitTask</code>类有<code>getTaskId()</code>方法，用于获取任务ID，而FoliaLib中，<code>WrappedTask</code>类没有<code>getTaskId()</code>方法，但是其会返回一个<code>WrappedTask</code>类型的值，可以用于<code>WrappedTask</code>中<code>cancelTask</code>方法&#96;</p><p>如下是一个示例，来自<a href="https://github.com/SlimefunGuguProject/Slimefun4/blob/master/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/player/AbstractPlayerTask.java">这个</a>文件</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="deletion">- private int id;</span></span><br><span class="line"><span class="addition">+ private WrappedTask task;</span></span><br><span class="line"></span><br><span class="line"><span class="deletion">- private void setID(int id) &#123;</span></span><br><span class="line"><span class="deletion">-    this.id = id;</span></span><br><span class="line"><span class="deletion">- &#125;</span></span><br><span class="line"><span class="addition">+ private void setCancelTask(WrappedTask task)&#123;</span></span><br><span class="line"><span class="addition">+    this.task = task;</span></span><br><span class="line"><span class="addition">+ &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="deletion">- public void schedule(long delay) &#123;</span></span><br><span class="line"><span class="deletion">-     setID(Bukkit.getScheduler().scheduleSyncDelayedTask(Slimefun.instance(), this, delay));</span></span><br><span class="line"><span class="deletion">- &#125;</span></span><br><span class="line"><span class="addition">+ public void schedule(long delay) &#123;</span></span><br><span class="line"><span class="addition">+     setCancelTask(Slimefun.getFoliaLib().getScheduler().runLater(this,delay));</span></span><br><span class="line"><span class="addition">+ &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="deletion">- public void scheduleRepeating(long delay, long interval) &#123;</span></span><br><span class="line"><span class="deletion">-     setID(Bukkit.getScheduler().scheduleSyncRepeatingTask(Slimefun.instance(), this, delay, interval));</span></span><br><span class="line"><span class="deletion">- &#125;</span></span><br><span class="line"><span class="addition">+ public void scheduleRepeating(long delay, long interval) &#123;</span></span><br><span class="line"><span class="addition">+     setCancelTask(Slimefun.getFoliaLib().getScheduler().runTimer(this,delay,interval));</span></span><br><span class="line"><span class="addition">+ &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="deletion">- public final void cancel() &#123;</span></span><br><span class="line"><span class="deletion">-     Bukkit.getScheduler().cancelTask(id);</span></span><br><span class="line"><span class="deletion">- &#125;</span></span><br><span class="line"><span class="addition">+ public final void cancel() &#123;</span></span><br><span class="line"><span class="addition">+     Slimefun.getFoliaLib().getScheduler().cancelTask(task);</span></span><br><span class="line"><span class="addition">+ &#125;</span></span><br></pre></td></tr></table></figure><h3 id="在生物或位置执行Scheduler"><a href="#在生物或位置执行Scheduler" class="headerlink" title="在生物或位置执行Scheduler"></a>在生物或位置执行Scheduler</h3><p>我们在文章开头就提到过</p><blockquote><p>Bukkit Scheduler.Bukkit Scheduler 本身 依赖于单个主线程。Folia 的 RegionScheduler 和 Folia 的 EntityScheduler 允许将任务调度到任何 “next tick” 区域 “拥有” 位置或实体。这些是可以实现的 在常规 Paper 上，除了它们调度到主线程 - 在这两种情况下， 任务的执行将发生在 “拥有” location 或 entity。这个概念通常适用，因为目前的 Paper （单线程）可以看作是一个巨大的“区域”，它包括 所有世界中的所有区块。</p></blockquote><p>因此，部分的任务需要以这种方式调度，否则无法起作用，此部分涉及的更改较多，请参考以下commit进行更改</p><ul><li><p><a href="https://github.com/Craft233MC/Slimefun4/commit/0f78ba02fd9660b9c6732bf546917a4b6bf92522">fix:grapplinghook cant use after it disappear</a></p></li><li><p><a href="https://github.com/Craft233MC/Slimefun4/commit/92155ab48db3c3a1c7a5b7eb62a2cf4b51094508">fix: runSync with entity or location</a></p></li><li><p><a href="https://github.com/Craft233MC/Slimefun4/commit/e71dbda9bef3b5964ac4a039518133dcaff2bc36">apply changes</a></p></li></ul><p>对于的方法也需要提供，可以直接复制一份原有的代码，然后修改即可，即可实现共存不同的方法<br>(这里我书写有点乱，一会要求提供的值在第一个，一会在最后一个，请见谅)</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br></pre></td><td class="code"><pre><span class="line">    public static @Nullable WrappedTask runSync(@Nonnull Runnable runnable, long delay) &#123;</span><br><span class="line">        Validate.notNull(runnable, &quot;Cannot run null&quot;);</span><br><span class="line">        Validate.isTrue(delay &gt;= 0, &quot;The delay cannot be negative&quot;);</span><br><span class="line"></span><br><span class="line">        // Run the task instantly within a Unit Test</span><br><span class="line">        if (getMinecraftVersion() == MinecraftVersion.UNIT_TEST) &#123;</span><br><span class="line">            runnable.run();</span><br><span class="line">            return null;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        if (instance == null || !instance.isEnabled()) &#123;</span><br><span class="line">            return null;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        return Slimefun.getFoliaLib().getScheduler().runLater(runnable, delay);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="addition">+     public static @Nullable WrappedTask runSyncAtEntity(@Nonnull Runnable runnable, long delay, Entity e) &#123;</span></span><br><span class="line"><span class="addition">+         Validate.notNull(runnable, &quot;Cannot run null&quot;);</span></span><br><span class="line"><span class="addition">+         Validate.isTrue(delay &gt;= 0, &quot;The delay cannot be negative&quot;);</span></span><br><span class="line"><span class="addition">+ </span></span><br><span class="line"><span class="addition">+         // Run the task instantly within a Unit Test</span></span><br><span class="line"><span class="addition">+         if (getMinecraftVersion() == MinecraftVersion.UNIT_TEST) &#123;</span></span><br><span class="line"><span class="addition">+             runnable.run();</span></span><br><span class="line"><span class="addition">+             return null;</span></span><br><span class="line"><span class="addition">+         &#125;</span></span><br><span class="line"><span class="addition">+ </span></span><br><span class="line"><span class="addition">+         if (instance == null || !instance.isEnabled()) &#123;</span></span><br><span class="line"><span class="addition">+             return null;</span></span><br><span class="line"><span class="addition">+         &#125;</span></span><br><span class="line"><span class="addition">+ </span></span><br><span class="line"><span class="addition">+         return Slimefun.getFoliaLib().getScheduler().runAtEntityLater(e ,runnable, delay);</span></span><br><span class="line"><span class="addition">+     &#125;</span></span><br><span class="line"><span class="addition">+ </span></span><br><span class="line"><span class="addition">+     public static @Nullable WrappedTask runSyncAtLocation(@Nonnull Runnable runnable, long delay, Location loc) &#123;</span></span><br><span class="line"><span class="addition">+         Validate.notNull(runnable, &quot;Cannot run null&quot;);</span></span><br><span class="line"><span class="addition">+         Validate.isTrue(delay &gt;= 0, &quot;The delay cannot be negative&quot;);</span></span><br><span class="line"><span class="addition">+ </span></span><br><span class="line"><span class="addition">+         // Run the task instantly within a Unit Test</span></span><br><span class="line"><span class="addition">+         if (getMinecraftVersion() == MinecraftVersion.UNIT_TEST) &#123;</span></span><br><span class="line"><span class="addition">+             runnable.run();</span></span><br><span class="line"><span class="addition">+             return null;</span></span><br><span class="line"><span class="addition">+         &#125;</span></span><br><span class="line"><span class="addition">+ </span></span><br><span class="line"><span class="addition">+         if (instance == null || !instance.isEnabled()) &#123;</span></span><br><span class="line"><span class="addition">+             return null;</span></span><br><span class="line"><span class="addition">+         &#125;</span></span><br><span class="line"><span class="addition">+ </span></span><br><span class="line"><span class="addition">+         return Slimefun.getFoliaLib().getScheduler().runAtLocationLater(loc,runnable, delay);</span></span><br><span class="line"><span class="addition">+     &#125;</span></span><br><span class="line"></span><br><span class="line">    public static @Nullable WrappedTask runSync(@Nonnull Runnable runnable) &#123;</span><br><span class="line">        Validate.notNull(runnable, &quot;Cannot run null&quot;);</span><br><span class="line"></span><br><span class="line">        // Run the task instantly within a Unit Test</span><br><span class="line">        if (getMinecraftVersion() == MinecraftVersion.UNIT_TEST) &#123;</span><br><span class="line">            runnable.run();</span><br><span class="line">            return null;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        if (instance == null || !instance.isEnabled()) &#123;</span><br><span class="line">            return null;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        return Slimefun.getFoliaLib().getScheduler().runLater(runnable,1);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"><span class="addition">+    public static @Nullable WrappedTask runSyncAtEntity(@Nonnull Runnable runnable, Entity e) &#123;</span></span><br><span class="line"><span class="addition">+        Validate.notNull(runnable, &quot;Cannot run null&quot;);</span></span><br><span class="line"><span class="addition">+</span></span><br><span class="line"><span class="addition">+        // Run the task instantly within a Unit Test</span></span><br><span class="line"><span class="addition">+        if (getMinecraftVersion() == MinecraftVersion.UNIT_TEST) &#123;</span></span><br><span class="line"><span class="addition">+            runnable.run();</span></span><br><span class="line"><span class="addition">+            return null;</span></span><br><span class="line"><span class="addition">+        &#125;</span></span><br><span class="line"><span class="addition">+</span></span><br><span class="line"><span class="addition">+        if (instance == null || !instance.isEnabled()) &#123;</span></span><br><span class="line"><span class="addition">+            return null;</span></span><br><span class="line"><span class="addition">+        &#125;</span></span><br><span class="line"><span class="addition">+</span></span><br><span class="line"><span class="addition">+        return Slimefun.getFoliaLib().getScheduler().runAtEntityLater(e,runnable,1);</span></span><br><span class="line"><span class="addition">+    &#125;</span></span><br><span class="line"><span class="addition">+</span></span><br><span class="line"><span class="addition">+    public static @Nullable WrappedTask runSyncAtLocation(@Nonnull Runnable runnable, Location loc) &#123;</span></span><br><span class="line"><span class="addition">+        Validate.notNull(runnable, &quot;Cannot run null&quot;);</span></span><br><span class="line"><span class="addition">+</span></span><br><span class="line"><span class="addition">+        // Run the task instantly within a Unit Test</span></span><br><span class="line"><span class="addition">+        if (getMinecraftVersion() == MinecraftVersion.UNIT_TEST) &#123;</span></span><br><span class="line"><span class="addition">+            runnable.run();</span></span><br><span class="line"><span class="addition">+            return null;</span></span><br><span class="line"><span class="addition">+        &#125;</span></span><br><span class="line"><span class="addition">+</span></span><br><span class="line"><span class="addition">+        if (instance == null || !instance.isEnabled()) &#123;</span></span><br><span class="line"><span class="addition">+            return null;</span></span><br><span class="line"><span class="addition">+        &#125;</span></span><br><span class="line"><span class="addition">+</span></span><br><span class="line"><span class="addition">+        return Slimefun.getFoliaLib().getScheduler().runAtLocationLater(loc,runnable,1);</span></span><br><span class="line"><span class="addition">+    &#125;</span></span><br></pre></td></tr></table></figure><h2 id="getNearbyEntities方法"><a href="#getNearbyEntities方法" class="headerlink" title="getNearbyEntities方法"></a><del>getNearbyEntities方法</del></h2><p><del>在Bukkit中可以用<code>getWorld().getNearbyEntities()</code>获取获取附近的实体，但是Folia中使用这个方法会出现错误，如以下报错</del></p><figure class="highlight re"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">java.lang.IllegalStateException: Cannot getEntities asynchronously</span><br><span class="line">        at io.papermc.paper.util.<span class="module-access"><span class="module"><span class="identifier">TickThread</span>.</span></span>ensure<span class="constructor">TickThread(TickThread.<span class="params">java</span>:86)</span> ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at net.minecraft.world.level.<span class="module-access"><span class="module"><span class="identifier">Level</span>.</span></span>get<span class="constructor">Entities(Level.<span class="params">java</span>:1566)</span> ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at org.bukkit.craftbukkit.<span class="module-access"><span class="module"><span class="identifier">CraftWorld</span>.</span></span>get<span class="constructor">NearbyEntities(CraftWorld.<span class="params">java</span>:1190)</span> ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at org.bukkit.craftbukkit.<span class="module-access"><span class="module"><span class="identifier">CraftWorld</span>.</span></span>get<span class="constructor">NearbyEntities(CraftWorld.<span class="params">java</span>:1176)</span> ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at Slimefun-e96a898-<span class="module-access"><span class="module"><span class="identifier">Insider</span>.</span></span>jar/io.github.thebusybiscuit.slimefun4.core.services.holograms.<span class="module-access"><span class="module"><span class="identifier">HologramsService</span>.</span></span>get<span class="constructor">Hologram(HologramsService.<span class="params">java</span>:139)</span> ~<span class="literal">[S<span class="identifier">limefun</span>-<span class="identifier">e96a898</span>-I<span class="identifier">nsider</span>.<span class="identifier">jar</span>:?]</span></span><br><span class="line">        at Slimefun-e96a898-<span class="module-access"><span class="module"><span class="identifier">Insider</span>.</span></span>jar/io.github.thebusybiscuit.slimefun4.core.services.holograms.<span class="module-access"><span class="module"><span class="identifier">HologramsService</span>.</span></span>lambda<span class="constructor">$updateHologram$0(HologramsService.<span class="params">java</span>:253)</span> ~<span class="literal">[S<span class="identifier">limefun</span>-<span class="identifier">e96a898</span>-I<span class="identifier">nsider</span>.<span class="identifier">jar</span>:?]</span></span><br><span class="line">        at Slimefun-e96a898-<span class="module-access"><span class="module"><span class="identifier">Insider</span>.</span></span>jar/io.github.thebusybiscuit.slimefun4.core.services.holograms.<span class="module-access"><span class="module"><span class="identifier">HologramsService</span>.</span></span>update<span class="constructor">Hologram(HologramsService.<span class="params">java</span>:265)</span> ~<span class="literal">[S<span class="identifier">limefun</span>-<span class="identifier">e96a898</span>-I<span class="identifier">nsider</span>.<span class="identifier">jar</span>:?]</span></span><br><span class="line">        at Slimefun-e96a898-<span class="module-access"><span class="module"><span class="identifier">Insider</span>.</span></span>jar/io.github.thebusybiscuit.slimefun4.core.services.holograms.<span class="module-access"><span class="module"><span class="identifier">HologramsService</span>.</span></span>set<span class="constructor">HologramLabel(HologramsService.<span class="params">java</span>:317)</span> ~<span class="literal">[S<span class="identifier">limefun</span>-<span class="identifier">e96a898</span>-I<span class="identifier">nsider</span>.<span class="identifier">jar</span>:?]</span></span><br><span class="line">        at Slimefun-e96a898-<span class="module-access"><span class="module"><span class="identifier">Insider</span>.</span></span>jar/io.github.thebusybiscuit.slimefun4.core.attributes.<span class="module-access"><span class="module"><span class="identifier">HologramOwner</span>.</span></span>update<span class="constructor">Hologram(HologramOwner.<span class="params">java</span>:36)</span> ~<span class="literal">[S<span class="identifier">limefun</span>-<span class="identifier">e96a898</span>-I<span class="identifier">nsider</span>.<span class="identifier">jar</span>:?]</span></span><br><span class="line">        at Slimefun-e96a898-<span class="module-access"><span class="module"><span class="identifier">Insider</span>.</span></span>jar/io.github.thebusybiscuit.slimefun4.core.attributes.<span class="module-access"><span class="module"><span class="identifier">HologramOwner</span>.</span></span>lambda<span class="constructor">$updateHologram$0(HologramOwner.<span class="params">java</span>:52)</span> ~<span class="literal">[S<span class="identifier">limefun</span>-<span class="identifier">e96a898</span>-I<span class="identifier">nsider</span>.<span class="identifier">jar</span>:?]</span></span><br><span class="line">        at Slimefun-e96a898-<span class="module-access"><span class="module"><span class="identifier">Insider</span>.</span></span>jar/io.github.thebusybiscuit.slimefun4.libraries.folialib.impl.<span class="module-access"><span class="module"><span class="identifier">FoliaImplementation</span>.</span></span>lambda<span class="constructor">$runLater$2(FoliaImplementation.<span class="params">java</span>:111)</span> ~<span class="literal">[S<span class="identifier">limefun</span>-<span class="identifier">e96a898</span>-I<span class="identifier">nsider</span>.<span class="identifier">jar</span>:?]</span></span><br><span class="line">        at io.papermc.paper.threadedregions.scheduler.<span class="module-access"><span class="module"><span class="identifier">FoliaGlobalRegionScheduler$GlobalScheduledTask</span>.</span></span>run(<span class="module-access"><span class="module"><span class="identifier">FoliaGlobalRegionScheduler</span>.</span></span>java:<span class="number">179</span>) ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:?]</span></span><br><span class="line">        at io.papermc.paper.threadedregions.scheduler.<span class="module-access"><span class="module"><span class="identifier">FoliaGlobalRegionScheduler</span>.</span></span>tick(<span class="module-access"><span class="module"><span class="identifier">FoliaGlobalRegionScheduler</span>.</span></span>java:<span class="number">37</span>) ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:?]</span></span><br><span class="line">        at io.papermc.paper.threadedregions.<span class="module-access"><span class="module"><span class="identifier">RegionizedServer</span>.</span></span>global<span class="constructor">Tick(RegionizedServer.<span class="params">java</span>:293)</span> ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at io.papermc.paper.threadedregions.<span class="module-access"><span class="module"><span class="identifier">RegionizedServer$GlobalTickTickHandle</span>.</span></span>tick<span class="constructor">Region(RegionizedServer.<span class="params">java</span>:148)</span> ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at io.papermc.paper.threadedregions.<span class="module-access"><span class="module"><span class="identifier">TickRegionScheduler$RegionScheduleHandle</span>.</span></span>run<span class="constructor">Tick(TickRegionScheduler.<span class="params">java</span>:404)</span> ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at ca.spottedleaf.concurrentutil.scheduler.<span class="module-access"><span class="module"><span class="identifier">SchedulerThreadPool$TickThreadRunner</span>.</span></span>run(<span class="module-access"><span class="module"><span class="identifier">SchedulerThreadPool</span>.</span></span>java:<span class="number">525</span>) ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at java.base/java.lang.<span class="module-access"><span class="module"><span class="identifier">Thread</span>.</span></span>run(<span class="module-access"><span class="module"><span class="identifier">Thread</span>.</span></span>java:<span class="number">1583</span>) ~<span class="literal">[?:?]</span></span><br></pre></td></tr></table></figure><p><del>因此需要重新实现这个方法</del></p><p>代码出处: <a href="https://github.com/pop4959/Bolt/commit/3a4581587dcf93be810787c0ef26ddd19a4f8307">Fix getting nearby entities on Folia</a></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> Collection&lt;Entity&gt; <span class="title function_">getNearbyEntities</span><span class="params">(<span class="keyword">final</span> Block block, <span class="keyword">final</span> BoundingBox boundingBox, <span class="keyword">final</span> Predicate&lt;Entity&gt; filter)</span>&#123;</span><br><span class="line">        <span class="keyword">final</span> <span class="type">World</span> <span class="variable">world</span> <span class="operator">=</span> block.getWorld();</span><br><span class="line">        <span class="keyword">if</span> (Slimefun.getFoliaLib().isFolia()) &#123;</span><br><span class="line">            <span class="keyword">final</span> <span class="type">int</span> <span class="variable">minChunkX</span> <span class="operator">=</span> boundingBox.getMin().getBlockX() &gt;&gt; <span class="number">4</span>;</span><br><span class="line">            <span class="keyword">final</span> <span class="type">int</span> <span class="variable">maxChunkX</span> <span class="operator">=</span> boundingBox.getMax().getBlockX() &gt;&gt; <span class="number">4</span>;</span><br><span class="line">            <span class="keyword">final</span> <span class="type">int</span> <span class="variable">minChunkZ</span> <span class="operator">=</span> boundingBox.getMin().getBlockZ() &gt;&gt; <span class="number">4</span>;</span><br><span class="line">            <span class="keyword">final</span> <span class="type">int</span> <span class="variable">maxChunkZ</span> <span class="operator">=</span> boundingBox.getMax().getBlockZ() &gt;&gt; <span class="number">4</span>;</span><br><span class="line">            <span class="keyword">final</span> List&lt;Entity&gt; nearbyEntities = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">chunkX</span> <span class="operator">=</span> minChunkX; chunkX &lt;= maxChunkX; ++chunkX) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">chunkZ</span> <span class="operator">=</span> minChunkZ; chunkZ &lt;= maxChunkZ; ++chunkZ) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (!world.isChunkLoaded(chunkX, chunkZ)) &#123;</span><br><span class="line">                        <span class="keyword">continue</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">final</span> <span class="type">Chunk</span> <span class="variable">chunk</span> <span class="operator">=</span> world.getChunkAt(chunkX, chunkZ);</span><br><span class="line">                    <span class="keyword">if</span> (!chunk.isEntitiesLoaded()) &#123;</span><br><span class="line">                        <span class="keyword">continue</span>;</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="keyword">for</span> (<span class="keyword">final</span> Entity entity : chunk.getEntities()) &#123;</span><br><span class="line">                        <span class="keyword">if</span> ((filter == <span class="literal">null</span> || filter.test(entity)) &amp;&amp; boundingBox.overlaps(entity.getBoundingBox())) &#123;</span><br><span class="line">                            nearbyEntities.add(entity);</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> nearbyEntities;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> world.getNearbyEntities(boundingBox, filter);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure><h2 id="聊天处理"><a href="#聊天处理" class="headerlink" title="聊天处理"></a>聊天处理</h2><p>这个问题发现于在使用Slimefun聊天栏搜索时，查看JavaDoc，PaperMC也给废弃了  </p><p>因此使用PaperMC提供的方法实现</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="deletion">-    public void onChat(AsyncPlayerChatEvent e) &#123;</span></span><br><span class="line"><span class="deletion">-        checkInput(e, e.getPlayer(), e.getMessage());</span></span><br><span class="line"><span class="addition">+    public void onChat(AsyncChatEvent e) &#123;</span></span><br><span class="line"><span class="addition">+        String message = PlainTextComponentSerializer.plainText().serialize(e.message());</span></span><br><span class="line"><span class="addition">+        checkInput(e, e.getPlayer(), message);</span></span><br></pre></td></tr></table></figure><p>这样实现对下游调用仍然是传入<code>Message</code>类型的值</p><h2 id="传送处理"><a href="#传送处理" class="headerlink" title="传送处理"></a>传送处理</h2><p>传送处理也存在问题，在Folia中，无法使用实体中<code>teleport</code>的方法，会抛出以下类型的值</p><figure class="highlight re"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">java.lang.UnsupportedOperationException: Must use teleportAsync <span class="keyword">while</span> <span class="keyword">in</span> region threading</span><br><span class="line">        at org.bukkit.craftbukkit.entity.<span class="module-access"><span class="module"><span class="identifier">CraftPlayer</span>.</span></span>teleport(<span class="module-access"><span class="module"><span class="identifier">CraftPlayer</span>.</span></span>java:<span class="number">1400</span>) ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at org.bukkit.craftbukkit.entity.<span class="module-access"><span class="module"><span class="identifier">CraftPlayer</span>.</span></span>teleport(<span class="module-access"><span class="module"><span class="identifier">CraftPlayer</span>.</span></span>java:<span class="number">1349</span>) ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at org.bukkit.craftbukkit.entity.<span class="module-access"><span class="module"><span class="identifier">CraftEntity</span>.</span></span>teleport(<span class="module-access"><span class="module"><span class="identifier">CraftEntity</span>.</span></span>java:<span class="number">226</span>) ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at Slimefun-<span class="number">555</span>c4e0-<span class="module-access"><span class="module"><span class="identifier">Insider</span>.</span></span>jar/io.github.thebusybiscuit.slimefun4.implementation.listeners.<span class="module-access"><span class="module"><span class="identifier">GrapplingHookListener</span>.</span></span>handle<span class="constructor">GrapplingHook(GrapplingHookListener.<span class="params">java</span>:174)</span> ~<span class="literal">[S<span class="identifier">limefun</span>-<span class="number">555</span><span class="identifier">c4e0</span>-I<span class="identifier">nsider</span>.<span class="identifier">jar</span>:?]</span></span><br><span class="line">        at Slimefun-<span class="number">555</span>c4e0-<span class="module-access"><span class="module"><span class="identifier">Insider</span>.</span></span>jar/io.github.thebusybiscuit.slimefun4.implementation.listeners.<span class="module-access"><span class="module"><span class="identifier">GrapplingHookListener</span>.</span></span>lambda<span class="constructor">$onArrowHitSurface$0(GrapplingHookListener.<span class="params">java</span>:75)</span> ~<span class="literal">[S<span class="identifier">limefun</span>-<span class="number">555</span><span class="identifier">c4e0</span>-I<span class="identifier">nsider</span>.<span class="identifier">jar</span>:?]</span></span><br><span class="line">        at Slimefun-<span class="number">555</span>c4e0-<span class="module-access"><span class="module"><span class="identifier">Insider</span>.</span></span>jar/io.github.thebusybiscuit.slimefun4.libraries.folialib.impl.<span class="module-access"><span class="module"><span class="identifier">FoliaImplementation</span>.</span></span>lambda<span class="constructor">$runAtEntityLater$18(FoliaImplementation.<span class="params">java</span>:366)</span> ~<span class="literal">[S<span class="identifier">limefun</span>-<span class="number">555</span><span class="identifier">c4e0</span>-I<span class="identifier">nsider</span>.<span class="identifier">jar</span>:?]</span></span><br><span class="line">        at io.papermc.paper.threadedregions.scheduler.<span class="module-access"><span class="module"><span class="identifier">FoliaEntityScheduler$EntityScheduledTask</span>.</span></span>accept(<span class="module-access"><span class="module"><span class="identifier">FoliaEntityScheduler</span>.</span></span>java:<span class="number">168</span>) ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:?]</span></span><br><span class="line">        at io.papermc.paper.threadedregions.scheduler.<span class="module-access"><span class="module"><span class="identifier">FoliaEntityScheduler$EntityScheduledTask</span>.</span></span>accept(<span class="module-access"><span class="module"><span class="identifier">FoliaEntityScheduler</span>.</span></span>java:<span class="number">115</span>) ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:?]</span></span><br><span class="line">        at io.papermc.paper.threadedregions.<span class="module-access"><span class="module"><span class="identifier">EntityScheduler</span>.</span></span>execute<span class="constructor">Tick(EntityScheduler.<span class="params">java</span>:173)</span> ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at net.minecraft.server.<span class="module-access"><span class="module"><span class="identifier">MinecraftServer</span>.</span></span>tick<span class="constructor">Server(MinecraftServer.<span class="params">java</span>:1688)</span> ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at io.papermc.paper.threadedregions.<span class="module-access"><span class="module"><span class="identifier">TickRegions$ConcreteRegionTickHandle</span>.</span></span>tick<span class="constructor">Region(TickRegions.<span class="params">java</span>:407)</span> ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at io.papermc.paper.threadedregions.<span class="module-access"><span class="module"><span class="identifier">TickRegionScheduler$RegionScheduleHandle</span>.</span></span>run<span class="constructor">Tick(TickRegionScheduler.<span class="params">java</span>:404)</span> ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at ca.spottedleaf.concurrentutil.scheduler.<span class="module-access"><span class="module"><span class="identifier">SchedulerThreadPool$TickThreadRunner</span>.</span></span>run(<span class="module-access"><span class="module"><span class="identifier">SchedulerThreadPool</span>.</span></span>java:<span class="number">525</span>) ~<span class="literal">[<span class="identifier">folia</span>-<span class="number">1.20</span>.<span class="number">6.</span><span class="identifier">jar</span>:<span class="number">1.20</span>.<span class="number">6</span>-DEV-<span class="number">9</span><span class="identifier">a19e42</span>]</span></span><br><span class="line">        at java.base/java.lang.<span class="module-access"><span class="module"><span class="identifier">Thread</span>.</span></span>run(<span class="module-access"><span class="module"><span class="identifier">Thread</span>.</span></span>java:<span class="number">1583</span>) ~<span class="literal">[?:?]</span></span><br></pre></td></tr></table></figure><p>一种简单的修复方法如下</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="deletion">- player.teleport(location);</span></span><br><span class="line"><span class="addition">+ player.teleportAsync(location);</span></span><br></pre></td></tr></table></figure><h2 id="结尾"><a href="#结尾" class="headerlink" title="结尾"></a>结尾</h2><p>到这里就是文章结尾了，我尽量对整个过程进行回忆，以想到尽可能多的修改部分，如果有漏掉的地方，欢迎提出。  </p><p>整个过程是我个人主观的修改过程，如果有不对或需要修改的地方，欢迎通过以下方式提出</p><ul><li><p><a href="https://github.com/Craft233MC/Slimefun4/issues">Craft233MC&#x2F;Slimefun4&#x2F;issues</a></p></li><li><p><a href="mailto:&#x6d;&#x65;&#64;&#110;&#x65;&#x6f;&#107;&#111;&#110;&#x69;&#46;&#x69;&#110;&#107;">me@neokoni.ink</a></p></li></ul><p>如果你觉得这个项目对您有帮助，欢迎给我一个star或<a href="https://dq.neokoni.ink/">DonateMe</a>支持！</p>]]></content>
    
    
    <summary type="html">在互联网尝试搜索让Bukkit插件适配Folia的教程，但是没找到任何结果。在自己的摸索后写了这篇文章。</summary>
    
    
    
    
    <category term="折腾" scheme="https://blog.neokoni.ink/tags/%E6%8A%98%E8%85%BE/"/>
    
    <category term="教程" scheme="https://blog.neokoni.ink/tags/%E6%95%99%E7%A8%8B/"/>
    
    <category term="开发" scheme="https://blog.neokoni.ink/tags/%E5%BC%80%E5%8F%91/"/>
    
    <category term="Minecraft" scheme="https://blog.neokoni.ink/tags/Minecraft/"/>
    
  </entry>
  
  <entry>
    <title>一加9R刷机完整教程:从ColorOS到类原生</title>
    <link href="https://blog.neokoni.ink/2024/10/12/%E4%B8%80%E5%8A%A09R%E5%88%B7%E6%9C%BA%E5%AE%8C%E6%95%B4%E6%95%99%E7%A8%8B-%E4%BB%8EColorOS%E5%88%B0%E7%B1%BB%E5%8E%9F%E7%94%9F/"/>
    <id>https://blog.neokoni.ink/2024/10/12/%E4%B8%80%E5%8A%A09R%E5%88%B7%E6%9C%BA%E5%AE%8C%E6%95%B4%E6%95%99%E7%A8%8B-%E4%BB%8EColorOS%E5%88%B0%E7%B1%BB%E5%8E%9F%E7%94%9F/</id>
    <published>2024-10-12T16:51:59.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>因为以前一直用的红米K30 5G坏了，换了个二手的<code>一加9R</code></p><p>因为刚开始刷机时找不到相关资料或相关资料较老，所以走了点弯路，浪费了一下午的时间</p><p>在刷机完成后，出现了这一篇文章</p><h2 id="提醒"><a href="#提醒" class="headerlink" title="提醒"></a>提醒</h2><p>先强调一点，刷机有风险，请慎重，若出现问题，请自行解决</p><p>底包首先，不能用<code>ColorOS</code>做底包，不然大多数事情都干不了</p><p>需要先刷入<code>OxygenOS</code>再进行正式的刷机步骤</p><p>原因是我试过了，系统是<code>ColorOS14</code>，带有安卓2024.9安全补丁的那个版本</p><p>启动recovery直接卡住，除了xda上下载的那个twrp</p><h2 id="流程"><a href="#流程" class="headerlink" title="流程"></a>流程</h2><p>先介绍一下本次刷机的流程，有一个大概的框架</p><p><code>刷入OxygenOS</code> &gt; <code>解锁Bootloader</code> &gt; <code>刷入基础文件</code> &gt; <code>启动recovery</code> &gt; <code>刷入复制分区文件</code> &gt; <code>刷入刷机包</code> &gt; <code>清除数据并重启</code></p><p>为什么是先刷入<code>OxygenOS</code>再解锁<code>Bootloader</code>呢？</p><p>因为在使用9008工具从ColorOS转移到OxygenOS，在刷入完成后似乎会回锁Bootloader，这个就导致没必要先解锁一次</p><p>那么接下来，就是刷入的过程了</p><h2 id="刷入OxygenOS"><a href="#刷入OxygenOS" class="headerlink" title="刷入OxygenOS"></a>刷入OxygenOS</h2><h3 id="过渡降级法-未测试"><a href="#过渡降级法-未测试" class="headerlink" title="过渡降级法(未测试)"></a>过渡降级法(未测试)</h3><p>参看b站视频<a href="https://www.bilibili.com/video/BV1KA411L7X1">BV1KA411L7X1</a></p><h3 id="9008线刷法"><a href="#9008线刷法" class="headerlink" title="9008线刷法"></a>9008线刷法</h3><p>首先，我们要获取线刷包，这里可以到<a href="https://yun.daxiaamu.com/OnePlus_Roms/%E4%B8%80%E5%8A%A09R/9008%E7%BA%BF%E5%88%B7%E6%95%91%E7%A0%96%E5%8C%85%E6%B0%A7OS%2011.2.8.8/">大侠阿木</a>下载救砖包恢复</p><p>解压后会得到如下图所示的文件</p><p><img src="/../picture/Oneplus9R_flash/9008firmware.png" alt="9008刷机文件"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>这一步需要在Windows环境下进行</p><p>接下来，安装9008驱动，此处资源来自<a href="https://www.thecustomdroid.com/qualcomm-hs-usb-qdloader-9008-drivers/">网站</a></p><ul><li><p><a href="https://www.mediafire.com/file/5wc5nk5adevatrj/QDLoader_HS-USB_Driver_64bit_Setup.exe/file">64位版本</a></p></li><li><p><a href="https://www.mediafire.com/file/q1uynnim8arbim9/QDLoader_HS-USB_Driver_32bit_Setup.exe/file">32位版本</a></p></li></ul><p>安装完成后运行解压后的刷机包中的<code>MsmDownloadTool V4.0.exe</code></p><p>你将看到以下内容</p><p><img src="/../picture/Oneplus9R_flash/flash_tool_login.png" alt="登录选项"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>因为我们并没有工厂账号，因此我们只能使用游客号</p><p>点击<code>Factory</code>所处的选择栏，选择<code>Other</code>并点击<code>Next</code></p><p>接下来就是软件的主界面</p><p><img src="/../picture/Oneplus9R_flash/9008_tool_main.png" alt="工具界面"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>接着，将手机关机，关机状态下按住<code>音量+</code>和<code>音量—</code>并同时插入与电脑连接的数据线</p><p>听到电脑响一声并且软件显示出设备就是进入9008了</p><p>接着点击左上角的<code>Start</code>开始刷入OxygenOS</p><p>这一步可能会报错<code>invalid try id()</code>应该是这个，有点记不清了</p><p>一部分人说这个需要去售后刷一次机，以后刷就不会报错了</p><p>但是这里，点击<code>Enum</code>右边的<code>Target</code>，在弹出的选项中选择<code>India</code>，然后重新点击<code>Start</code></p><p>现在刷入就应该没什么问题了，刷入完成后手机会重启，但不一定是直接进入系统</p><p>我的手机重启后在Bootloader，当显示绿色的Start时点击电源键启动手机</p><p>不是start可以按音量键切换</p><p>重启后第一次启动可能会提示<code>abnormal state</code>的提示以及一个<code>exit</code>的选项</p><p>选择<code>exit</code>接着选择<code>reboot</code>即可正常进入系统，目前是氧11,版本还是比较低</p><p>此时你可以选择一路使用系统的软件升级到最新版本或者手动选择固件本地升级</p><p>本地固件升级软件在<a href="https://yun.daxiaamu.com/files/%E5%B8%B8%E7%94%A8APP/%E6%9C%AC%E5%9C%B0%E5%8D%87%E7%BA%A7/">大侠阿木</a>可以下载</p><h2 id="解锁Bootloader"><a href="#解锁Bootloader" class="headerlink" title="解锁Bootloader"></a>解锁Bootloader</h2><p>正常进入系统，打开开发者选项，点击打开oem解锁</p><p>手机进入Bootloader,输入以下命令解锁</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fastboot oem unlock</span><br></pre></td></tr></table></figure><p>如果oem解锁为灰色，且显示”请连接互联网或联系您的运营商”</p><p>尝试登陆Google账号后重新查看，若登陆后依然为灰色，可以尝试直接解锁</p><p>我的手机就是这样，直接执行就解锁了</p><p>执行完命令，使用音量键切换选项，电源键选择，选择有”UNLOCK”字样的选项</p><p>之后会自动恢复出厂设置，并且开机显示<code>Orange State</code>就是成功了</p><h2 id="刷入基础文件"><a href="#刷入基础文件" class="headerlink" title="刷入基础文件"></a>刷入基础文件</h2><p>找到你刷机包下载的地方，一般应该会自带<code>dtbo.img``vbmeta.img``recovery.img</code>这三个文件</p><p>我们这里先刷入<code>dtbo</code>与<code>vbmeta</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">fastboot flash dtbo dtbo.img</span><br><span class="line">fastboot flash vbmeta vbmeta.img</span><br></pre></td></tr></table></figure><p>文件适当替换为你自己的文件路径</p><h2 id="启动Recovery"><a href="#启动Recovery" class="headerlink" title="启动Recovery"></a>启动Recovery</h2><p>这里直接启动就够了，刷入完成后会自动使用刷机包带的rec</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fastboot boot recovery.img</span><br></pre></td></tr></table></figure><p>文件适当替换为你自己的文件路径</p><h2 id="刷入复制分区文件"><a href="#刷入复制分区文件" class="headerlink" title="刷入复制分区文件"></a>刷入复制分区文件</h2><p>这一步来自<a href="https://wiki.lineageos.org/devices/lemonades/install/#ensuring-all-firmware-partitions-are-consistent">LineageOS的教程</a></p><p>引用下直译的话:</p><p><code>在某些情况下，非活动插槽可能未填充或包含比活动插槽旧得多的固件，从而导致各种问题，包括潜在的硬砖。我们可以通过将活动槽的内容复制到非活动槽来确保不会发生这些情况。</code></p><p>首先下载复制分区的文件<a href="https://mirrorbits.lineageos.org/tools/copy-partitions-20220613-signed.zip">copy-partitions-20220613-signed.zip</a></p><p>然后手机选择<code>Apply update</code>再选择<code>From ADB</code></p><p>此时手机为adb sideload模式，此时运行adb命令，文件适当替换为你自己的文件路径</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">adb sideload copy-partitions-20220613-signed.zip</span><br></pre></td></tr></table></figure><p>完成后选择<code>Advance</code>,再选择<code>Reboot to Bootloader</code></p><p>之后再次启动Recovery，步骤一样</p><h2 id="刷入刷机包"><a href="#刷入刷机包" class="headerlink" title="刷入刷机包"></a>刷入刷机包</h2><p>这里依然是使用adb sideload的方式刷入</p><p>然后手机选择<code>Apply update</code>再选择<code>From ADB</code></p><p>此时手机为adb sideload模式，此时运行adb命令，文件适当替换为你自己的文件路径</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">adb sideload file.zip</span><br></pre></td></tr></table></figure><p>file.zip替换为你自己的文件路径</p><p>比如我这里刷入我自编译的系统，则命令为</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">adb sideload /home/Neokoni/Downloads/EverestOS-1.6-Lukla-EOL-lemonades-UNOFFICIAL-GAPPS-1700-20241010.zip</span><br></pre></td></tr></table></figure><h2 id="清除数据并重启"><a href="#清除数据并重启" class="headerlink" title="清除数据并重启"></a>清除数据并重启</h2><p>刷入完成后，找到<code>Factory reset</code>并选择<code>Format data/factory reset</code>即可清除</p><p>选择<code>Reboot to system</code>，刷机完成</p>]]></content>
    
    
    <summary type="html">第一次刷一加的手机，也是第一台一加。算是记录，也算是教程，也算是自己理解的教程了。希望可以帮到你</summary>
    
    
    
    
    <category term="折腾" scheme="https://blog.neokoni.ink/tags/%E6%8A%98%E8%85%BE/"/>
    
    <category term="教程" scheme="https://blog.neokoni.ink/tags/%E6%95%99%E7%A8%8B/"/>
    
    <category term="Android" scheme="https://blog.neokoni.ink/tags/Android/"/>
    
    <category term="刷机" scheme="https://blog.neokoni.ink/tags/%E5%88%B7%E6%9C%BA/"/>
    
  </entry>
  
  <entry>
    <title>OneShot壁纸分享</title>
    <link href="https://blog.neokoni.ink/2024/10/02/OneShot_Wallpaper/"/>
    <id>https://blog.neokoni.ink/2024/10/02/OneShot_Wallpaper/</id>
    <published>2024-10-02T08:02:21.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>之前有意去找过，但是还是挺难找的，现在自己有游戏本体了，也保存了一下，也许以后有需要的呢？</p><p>所有壁纸都提取自游戏<a href="https://store.steampowered.com/app/2915460">OneShot World Machine Edition</a></p><p>且均为原分辨率与质量，未压缩</p><p>如果你觉得这个游戏不错，也请支持一下正版～</p><h2 id="用到的工具"><a href="#用到的工具" class="headerlink" title="用到的工具"></a>用到的工具</h2><ul><li><p><a href="https://store.steampowered.com/app/2915460">OneShot World Machine Edition</a>本体</p></li><li><p><a href="https://github.com/LeonBlade/xnbcli">xnbcli</a></p></li></ul><h2 id="图片-按字母排列"><a href="#图片-按字母排列" class="headerlink" title="图片(按字母排列)"></a>图片(按字母排列)</h2><p><img src="/../picture/Oneshot_Wallpaper/barrens.png" alt="barrens"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/black.png" alt="black"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/cafe.png" alt="cafe"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/catwalks.png" alt="catwalks"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/courtyard.png" alt="courtyard"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/default.png" alt="default"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/desktop.png" alt="desktop"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/factory.png" alt="factory"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/from_niko.png" alt="from_niko"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/glen.png" alt="glen"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/lamp.png" alt="lamp"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/lamplighter.png" alt="lamplighter"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/library.png" alt="library"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/minecart.png" alt="minecart"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/navigate.png" alt="navigate"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/niko.png" alt="niko"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/planet.png" alt="planet"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/plant.png" alt="plant"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/refuge.png" alt="refuge"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/ruins.png" alt="ruins"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/secret.png" alt="secret"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/siblings.png" alt="siblings"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/title.png" alt="title"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/tower.png" alt="tower"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/Oneshot_Wallpaper/world_machine.png" alt="world machine"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p>]]></content>
    
    
    <summary type="html">以前保存的已有的网站找不到了，没法下载壁纸。现在购买了游戏正版，有能力去自己提取壁纸并分享出来。</summary>
    
    
    
    
    <category term="Game!" scheme="https://blog.neokoni.ink/tags/Game/"/>
    
  </entry>
  
  <entry>
    <title>使用Ubuntu为设备构建安卓系统</title>
    <link href="https://blog.neokoni.ink/2024/08/24/ubuntu%E7%B3%BB%E7%BB%9F%E6%90%AD%E5%BB%BA%E5%AE%89%E5%8D%93%E6%9E%84%E5%BB%BA%E7%8E%AF%E5%A2%83/"/>
    <id>https://blog.neokoni.ink/2024/08/24/ubuntu%E7%B3%BB%E7%BB%9F%E6%90%AD%E5%BB%BA%E5%AE%89%E5%8D%93%E6%9E%84%E5%BB%BA%E7%8E%AF%E5%A2%83/</id>
    <published>2024-08-24T04:06:34.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>之前在kvm虚拟机编译安卓，但是由于qemu虚拟磁盘的特性，最终磁盘文件大小已经大于设置的磁盘文件的最大容量，然后盘就满了  </p><p>kvm虚拟机就直接暂停了，也没法使用其他Linux的livecd，一挂载也会暂停  </p><p>使用各种办法挽救，速度忒慢，索性直接重建环境，比那些操作快，毕竟没什么重要文件  </p><p><code>本篇算是一个笔记，给自己记录，方便以后使用</code></p><h2 id="环境介绍"><a href="#环境介绍" class="headerlink" title="环境介绍"></a>环境介绍</h2><p>系统: <code>ubuntu 24.04 LTS</code>  </p><p>示例系统源码: Avium16</p><h2 id="更换源与更新系统"><a href="#更换源与更新系统" class="headerlink" title="更换源与更新系统"></a>更换源与更新系统</h2><p>此处默认已进行更换，如果没有，更换源在镜像站一般都有教程<br>推荐两个<a href="https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/">清华源</a>和<a href="https://mirrors.ustc.edu.cn/help/ubuntu.html">中科大源</a></p><p>更新系统:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt update &amp;&amp; sudo apt upgrade</span><br></pre></td></tr></table></figure><h2 id="安装依赖"><a href="#安装依赖" class="headerlink" title="安装依赖"></a>安装依赖</h2><p>在这解释一下各个包，基础列表来自<a href="https://source.android.google.cn/docs/setup/start/initializing?hl=zh-cn#installing-required-packages-ubuntu-1804">安卓官方文档1</a>和<a href="https://source.android.google.cn/source/initializing?hl=zh-cn#installing-the-jdk">安卓官方文档2</a>  </p><p>然后是做出的修改，修正找不到包的问题，包括<code>git-core</code>，<code>libncurses5</code>和<code>lib32ncurses5-dev</code>，由于ubuntu已经占不到这些包了，所以替换成<code>git</code>，<code>libncurses6</code>和<code>lib32ncurses-dev</code>  </p><p>然后是同步源码的工具<code>repo</code>，不需要手动设置PATH来用，源里有，就是deb系的似乎更新比较慢，会报版本不是最新的警告，其他的发行版没见过有这个  </p><p><code>ccache</code>这个在<code>build/envsetup.sh</code>没定义或手动启用是不会自动开的，介于大多类原生的编译脚本里有，所以也带了</p><p>然后是构建内核需要用的的包<code>libssl-dev</code>，解决编译内核时提示&lt;openssl&#x2F;bio.h&gt;缺失的问题</p><p><code>git-lfs</code>这个在部分仓库需要用到，缺少可能会导致部分依赖它同步的文件打开后显示lfs信息。而不是本体文件</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install git gnupg flex bison build-essential zip curl zlib1g-dev libc6-dev-i386 libncurses6 lib32ncurses-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig libssl-dev openjdk-8-jdk repo ccache git-lfs libelf-dev rsync</span><br></pre></td></tr></table></figure><h2 id="设置git信息"><a href="#设置git信息" class="headerlink" title="设置git信息"></a>设置git信息</h2><p>源码同步会提示要求设置git的信息，这里就不多说了，直接设置一下就行  </p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git config --global user.email 你的GITHUB邮箱(或其他?)</span><br><span class="line">git config --global user.name  你的GITHUB用户名(或其他?)</span><br></pre></td></tr></table></figure><h2 id="初始化repo同步清单"><a href="#初始化repo同步清单" class="headerlink" title="初始化repo同步清单"></a>初始化repo同步清单</h2><p>首先，创建一个文件夹用来存放源码，然后进入这个文件夹，比如我这叫<code>android</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> android &amp;&amp; <span class="built_in">cd</span> android</span><br></pre></td></tr></table></figure><p>接着设置repo的下载地址，默认是被墙的谷歌源，我们可以替换为<a href="https://mirrors.tuna.tsinghua.edu.cn/help/git-repo/">清华大学的git-repo</a>源</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> REPO_URL=<span class="string">&#x27;https://mirrors.tuna.tsinghua.edu.cn/git/git-repo&#x27;</span></span><br></pre></td></tr></table></figure><p>接着就是初始化repo，比如我这里同步<code>AviumUI</code>源码，可以执行这条命令。</p><p>这里<code>https://github.com/AviunUI/android_manifests</code>是清单地址，在前面加上<code>https://gh-proxy.com/</code>以使用国内加速，也可以<a href="https://github.com/hunshcn/gh-proxy">自建</a>  </p><p>结尾加上<code>--depth=1</code>设置克隆深度为1,减少不必要的空间占用</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">repo init -u https://gh-proxy.com/https://github.com/AviumUI/android_manifests -b avium-16 --git-lfs --depth=1</span><br></pre></td></tr></table></figure><p>如果是AOSP官方源码或者lineages源码，可以使用国内镜像源，教程参考<a href="https://mirrors.tuna.tsinghua.edu.cn/help/lineageOS/">清华源文档</a></p><p>可用的源推荐<a href="https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/">清华源</a>和<a href="https://mirrors.ustc.edu.cn/help/aosp.html">中科大源</a>，不同之处就是替换<code>url</code>的问题</p><h2 id="修改清单指向加速源"><a href="#修改清单指向加速源" class="headerlink" title="修改清单指向加速源"></a>修改清单指向加速源</h2><p>使用你喜欢的编辑器编辑<code>.repo/manifests</code>文件夹，依次编辑<code>default.xml</code>和存在的其他<code>.xml</code>文件</p><p>对于<code>https://github.com</code>的链接，在<code>链接</code>最前面加上<code>https://gh-proxy.com/</code></p><p>对于<code>https://android.googlesource.com</code>的链接，将<code>链接</code>更换为<code>AOSP镜像源</code>所要求的url</p><p>示例：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">remote</span>  <span class="attr">name</span>=<span class="string">&quot;aosp&quot;</span></span></span><br><span class="line"><span class="tag">         <span class="attr">fetch</span>=<span class="string">&quot;https://mirrors.ustc.edu.cn/aosp&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">...</span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">remote</span> <span class="attr">name</span>=<span class="string">&quot;avium&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">fetch</span>=<span class="string">&quot;https://gh-proxy.com/https://github.com/AviumUI/&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">sync-c</span>=<span class="string">&quot;true&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">sync-j</span>=<span class="string">&quot;4&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">revision</span>=<span class="string">&quot;refs/heads/avium-16&quot;</span> /&gt;</span></span><br></pre></td></tr></table></figure><h2 id="同步源码"><a href="#同步源码" class="headerlink" title="同步源码"></a>同步源码</h2><p>这一步应该都会，因为大多数的清单里都会包含同步源码</p><p>此处为<a href="https://github.com/AviumUI/android_manifests/blob/avium-16/README_CN.mkdn#to-sync">AviumUI</a>的清单里的同步命令</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">repo <span class="built_in">sync</span> -c -j$(<span class="built_in">nproc</span> --all) --force-sync --no-clone-bundle --no-tags</span><br></pre></td></tr></table></figure><p><code>-j</code>后的线程数这个命令是默认按照CPU的核心数，但是按照镜像源的说法，比如这里的中科大源，请酌情设置线程数</p><div class="trm-note warning"><div class="trm-note-title">WARNING</div><p>由于硬盘 I&#x2F;O 资源有限，Git 服务器每 IP 限制 5 个并发连接。 repo sync 命令默认使用 4 个并发连接，请勿使用 -j 参数增加并发连接数。</p></div><h2 id="小脚本？"><a href="#小脚本？" class="headerlink" title="小脚本？"></a>小脚本？</h2><p>虽然设置完加速与镜像后，可以做到不开<code>魔法</code>也可以顺利克隆，但是如果你的网络实在不好，容易失败</p><p>这里有个简单的<code>bash脚本</code>可以帮助你自动重试，直到同步成功或手动退出</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;======start repo sync======&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 执行 repo sync 命令</span></span><br><span class="line">repo <span class="built_in">sync</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用 while 循环检查命令的退出状态</span></span><br><span class="line"><span class="keyword">while</span> [ $? -eq 1 ]; <span class="keyword">do</span></span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;======sync failed, re-sync again======&quot;</span></span><br><span class="line">    <span class="built_in">sleep</span> 3</span><br><span class="line">    repo <span class="built_in">sync</span></span><br><span class="line"><span class="keyword">done</span></span><br></pre></td></tr></table></figure><p>使用方法就是将脚本保存为<code>repo_sync.sh</code>，然后<code>chmod +x repo_sync.sh</code>，然后执行<code>./repo_sync.sh</code>即可</p><h2 id="🌳获取设备树文件"><a href="#🌳获取设备树文件" class="headerlink" title="🌳获取设备树文件"></a>🌳获取设备树文件</h2><blockquote><p>注，此部分内容为2025-12-08追加<br>什么是树呢？树即描述设备情况的一些列文件，包括平台配置，内核，专有驱动等</p></blockquote><p>用于告诉安卓构建系统有哪些要求，应该使用什么</p><p>由于AviumUI是完全兼容LineageOS的设备树的，所以这里以LineageOS设备树作为演示</p><p>tips: 设备树仓库一般以一定规律命名，如android_device_(oem)_(product)</p><h3 id="设备描述device"><a href="#设备描述device" class="headerlink" title="设备描述device"></a>设备描述device</h3><p>这里以一加9R作为示例，它的设备厂商为oneplus，代号为lemonades</p><p>那么打开LineageOS组织的仓库 <a href="https://github.com/LineageOS">LineageOS</a></p><p>搜索lemonades， 将会看见它的代码仓库<a href="https://github.com/LineageOS/android_deivce_oneplus_lemonades">android_device_oneplus_lemonades</a></p><p>在仓库主页，复制它的链接，然后回到安卓源码的目录克隆源码</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/LineageOS/android_device_oneplus_lemonades device/oneplus/lemonades</span><br></pre></td></tr></table></figure><p>等待克隆完成后进入目录，打开<code>lineage.dependencies</code>，这个文件包含其他需要获取的设备树文件（如果规范）</p><p>比如按照lemonades的lineageos设备树，还需要获取sm8250-common设备树文件，那么也需要克隆下来</p><p>与上次一样，目录就应该是device&#x2F;oneplus&#x2F;sm8250-common</p><p>这就是设备树仓库一般的命名方式</p><h3 id="内核Kernel"><a href="#内核Kernel" class="headerlink" title="内核Kernel"></a>内核Kernel</h3><p>如<code>lineage.dependencies</code>里列出，此处同样获取kernel源码</p><p>因为内核一般提交信息非常多，如果没有额外的维护需求，可以加上–depth&#x3D;1减少下载的大小</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/lineageos/android_kernel_oneplus_sm8250 kernel/oneplus/sm8250 --depth=1</span><br></pre></td></tr></table></figure><div class="trm-note info"><div class="trm-note-title">INFO</div><p>如果你所使用的内核包含KernelSU且将KernelSU作为子模块，请务必在克隆内核后初始化KernelSU</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git submodule init</span><br><span class="line">git submodule update</span><br></pre></td></tr></table></figure></div><h3 id="厂商私有文件vendor"><a href="#厂商私有文件vendor" class="headerlink" title="厂商私有文件vendor"></a>厂商私有文件vendor</h3><p>LineageOS组织是没有vendor内容的，如果你翻阅lineageos wiki</p><p>它会告诉你让你从设备提取，但其实lineageos的vendor内容似乎保存在另一个地方</p><p><a href="https://github.com/themuppets">TheMuppets</a>里面包含了LineageOS维护的设备的vendor文件</p><h3 id="硬件特性hardware"><a href="#硬件特性hardware" class="headerlink" title="硬件特性hardware"></a>硬件特性hardware</h3><p>都在LineageOS仓库, 具体参考<code>lineage.dependencies</code>, 比如一加9R是<code>android_hardware_oplus</code></p><p>那么就需要克隆这样的</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/lineageos/android_hardware_oplus hardware/oplus</span><br></pre></td></tr></table></figure><h2 id="初始化编译"><a href="#初始化编译" class="headerlink" title="初始化编译"></a>初始化编译</h2><p>首先确保使用的shell为bash，如果不是，请手动切换为bash</p><p>然后执行以下内容</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">source build/envsetup.sh</span><br><span class="line">lunch lineage_lemonades-bp2a-user</span><br></pre></td></tr></table></figure><p>其中user是构建类型，bp2a是代表安卓16初始版本(qpr0)</p><p>lineage_lemonades是目标名称，这里定义在device&#x2F;oneplus&#x2F;lemonades&#x2F;lineage_lemonades.mk文件</p><p>然后开始编译系统</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make bacon</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">自用的教程，方便自己快速在Ubuntu24.04上搭建安卓系统编译环境。</summary>
    
    
    
    
    <category term="折腾" scheme="https://blog.neokoni.ink/tags/%E6%8A%98%E8%85%BE/"/>
    
    <category term="教程" scheme="https://blog.neokoni.ink/tags/%E6%95%99%E7%A8%8B/"/>
    
    <category term="Android" scheme="https://blog.neokoni.ink/tags/Android/"/>
    
    <category term="笔记" scheme="https://blog.neokoni.ink/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>使用1panel搭建blessing skin皮肤站且不使用外置登录</title>
    <link href="https://blog.neokoni.ink/2024/02/25/%E4%BD%BF%E7%94%A81panel%E6%90%AD%E5%BB%BAblessing-skin%E7%9A%AE%E8%82%A4%E7%AB%99%E4%B8%94%E6%97%A0%E5%A4%96%E7%BD%AE%E7%99%BB%E9%99%86%E6%98%BE%E7%A4%BA%E7%9A%AE%E8%82%A4/"/>
    <id>https://blog.neokoni.ink/2024/02/25/%E4%BD%BF%E7%94%A81panel%E6%90%AD%E5%BB%BAblessing-skin%E7%9A%AE%E8%82%A4%E7%AB%99%E4%B8%94%E6%97%A0%E5%A4%96%E7%BD%AE%E7%99%BB%E9%99%86%E6%98%BE%E7%A4%BA%E7%9A%AE%E8%82%A4/</id>
    <published>2024-02-25T03:47:25.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="实现效果"><a href="#实现效果" class="headerlink" title="实现效果"></a>实现效果</h2><p>服务器与客户端均不使用外置登录，服务器为离线模式，可自行选择使用mojang的皮肤或使用皮肤站定义的皮肤</p><h2 id="需要的插件或环境"><a href="#需要的插件或环境" class="headerlink" title="需要的插件或环境"></a>需要的插件或环境</h2><ul><li><p><a href="https://1panel.cn/">1Panel</a></p></li><li><p>支持插件的Minecraft核心或代理</p></li><li><p><a href="https://skinsrestorer.net/">SkinsRestorer</a></p></li><li><p><a href="https://github.com/hank9999/UseBlessingSkin">UseBlessingSkin</a></p></li><li><p>php8.1环境(1Panel安装)</p></li><li><p>数据库(MySQL等)</p></li></ul><h2 id="部署皮肤站"><a href="#部署皮肤站" class="headerlink" title="部署皮肤站"></a>部署皮肤站</h2><h3 id="安装1panel"><a href="#安装1panel" class="headerlink" title="安装1panel"></a>安装1panel</h3><p>使用<a href="https://1panel.cn/">1Panel</a>提供的一键安装脚本一键安装，安装时会自动安装docker</p><h3 id="使用1panel部署php环境"><a href="#使用1panel部署php环境" class="headerlink" title="使用1panel部署php环境"></a>使用1panel部署php环境</h3><p>选择网站-&gt;运行环境-&gt;扩展模板-&gt;创建，创建一个扩展模板，模板名称可自定义，”扩展”内填入以下内容，图中末尾多写了个”D”</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pdo_dblib,pdo_firebird,pdo_mysql,pdo_oci,pdo_odbc,pdo_pgsql,pdo_sqlsrv,mbstring,tokenizer,gd,xml,ctype,json,fileinfo,zip</span><br></pre></td></tr></table></figure><p>这一步主要是因为创建环境时的扩展并不能批量导入，只能使用扩展功能</p><p>当然，你也可以手动输入</p><p><img src="/../picture/blessing_skin/1panel_php.png" alt="安装php插件"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>接着返回”创建运行环境”来创建一个php8.1的环境，并选择刚刚创建的模板，点击创建，等待创建完毕</p><p><img src="/../picture/blessing_skin/1panel_php2.png" alt="php插件选择完成"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><div class="trm-note warning"><div class="trm-note-title">WARNING</div><p>不要选择更高的版本！blessing skin可能不支持，导致运行blessing skin的安装页出现500错误！</p><p>详情查看<a href="https://github.com/bs-community/blessing-skin-server/issues?q=is:issue+500">issue区</a></p></div><h3 id="获取blessing-skin-server"><a href="#获取blessing-skin-server" class="headerlink" title="获取blessing skin server"></a>获取blessing skin server</h3><p>打开<a href="https://github.com/bs-community/blessing-skin-server/releases/latest">blessing skin server</a>的release，并下载最新版本</p><div class="trm-note info"><div class="trm-note-title">INFO</div><p>你应该下载文件名类似 <code>blessing-skin-server-xxx.zip</code>的文件，而不是下载<code>Source Code</code></p></div><h3 id="创建网站"><a href="#创建网站" class="headerlink" title="创建网站"></a>创建网站</h3><p>转到网站-&gt;网站，创建网站，选择运行环境，类型php,运行环境选择之前创建的环境，域名看实际情况填写，内网的话0.0.0.0都行，可以指定端口</p><p><img src="/../picture/blessing_skin/1panel_php3.png" alt="创建网站"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>接着配置刚创建的网站，点击网站目录，打开主目录的文件夹，在<code>index</code>文件夹里上传blessing skin server的压缩包并解压。</p><p>接着回到网站设置 -&gt; 网站目录，更改为<code>/public</code>文件夹</p><p>接着点击<code>伪静态</code>并填入以下规则</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">location / &#123;</span><br><span class="line">      try_files $uri $uri/ /index.php?$query_string;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>点击保存并重载</p><p><img src="/../picture/blessing_skin/1panel_php4.png" alt="保存设置"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/blessing_skin/1panel_php5.png" alt="伪静态配置"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><h3 id="初始化blessing-skin"><a href="#初始化blessing-skin" class="headerlink" title="初始化blessing skin"></a>初始化blessing skin</h3><p>不出意外，访问你的主机ip(端口)就可以看到皮肤站的安装页面，按照提示完成即可</p><p>皮肤站需要连接数据库</p><div class="trm-note info"><div class="trm-note-title">INFO</div><p>若数据库通过1Panel面板部署，请在填写数据库地址一栏使用1panel中数据库的连接信息中的内部连接地址，而不是本机主机ip或本地ip</p></div><h2 id="使游戏离线使用皮肤站皮肤"><a href="#使游戏离线使用皮肤站皮肤" class="headerlink" title="使游戏离线使用皮肤站皮肤"></a>使游戏离线使用皮肤站皮肤</h2><p>选择皮肤类似于skinsrestorer的那种，但是指令为bskin</p><h3 id="安装服务器插件"><a href="#安装服务器插件" class="headerlink" title="安装服务器插件"></a>安装服务器插件</h3><p>下载<a href="https://github.com/hank9999/UseBlessingSkin/releases/latest">UseBlessingSkin</a>和<a href="https://skinsrestorer.net/">SkinsRestorer</a>并放入服务器或代理端的plugins文件夹</p><p>并使用插件管理插件加载或重启服务端或代理</p><p>在useblessingskin配置文件中，将开头的<code>csl</code>,<code>ctexture</code>,<code>url</code>更改成你自己或别人皮肤站的域名</p><p>不要更改后面的内容，将<code>name</code>改成你自己的皮肤站名称(似乎不改也不会怎样)</p><p>其他选项按自己情况更改</p><h3 id="服务器中应用皮肤"><a href="#服务器中应用皮肤" class="headerlink" title="服务器中应用皮肤"></a>服务器中应用皮肤</h3><p>UseBlessingSkin并不会像Skinsrestorer一样自动应用皮肤，您需要自行使用<code>/bskin set 玩家名</code>设置皮肤，玩家名为您在皮肤站的档案里的玩家名</p><p>UseBlessingSkin的皮肤使用后会覆盖Skinsrestorer的皮肤，并不会和Skinsretorer”打架”</p>]]></content>
    
    
    <summary type="html">介绍了一下自己在1Panel下搭建blessing skin皮肤站的过程。当时搜索的教程只有宝塔面板的，并不符合我自己的需要，在自己摸索中完成了搭建</summary>
    
    
    
    
    <category term="折腾" scheme="https://blog.neokoni.ink/tags/%E6%8A%98%E8%85%BE/"/>
    
    <category term="教程" scheme="https://blog.neokoni.ink/tags/%E6%95%99%E7%A8%8B/"/>
    
    <category term="Minecraft" scheme="https://blog.neokoni.ink/tags/Minecraft/"/>
    
  </entry>
  
  <entry>
    <title>Arch To Go制作指南</title>
    <link href="https://blog.neokoni.ink/2023/11/03/arch-to-go%E5%88%B6%E4%BD%9C%E6%8C%87%E5%8D%97/"/>
    <id>https://blog.neokoni.ink/2023/11/03/arch-to-go%E5%88%B6%E4%BD%9C%E6%8C%87%E5%8D%97/</id>
    <published>2023-11-03T08:02:54.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>在学校机房信息课每次配置环境麻烦，还因为某些东西第一次登陆要手机验证，于是想到了在U盘内安装的系统</p><p>本次安装由Ventoy启动，兼顾linux to go和正常安装其他系统的功能</p><h2 id="要求"><a href="#要求" class="headerlink" title="要求"></a>要求</h2><p>1.一个USB3.x的U盘，最好64G及以上以可以划分足够的剩余的空间，U盘速度越快越好</p><div class="trm-note warning"><div class="trm-note-title">WARNING</div><p>不要为了便宜而买低价产品，速度会非常慢</p><p>购买时注意<code>写入速度</code>，商家宣传大多写的读取速度，注意分辨</p><p>不要使用<code>gnome</code>及<code>gdm</code>,实测会导致系统在U盘内启动很慢(<code>GDM及GNOME</code>)</p><p>也有可能是我自己的特殊的奇奇怪怪的问题？</p></div><p>2.一台正常使用的电脑</p><p>3.<code>ventoy</code>及<code>virtual box</code>虚拟机</p><p>4.创建虚拟磁盘时选择分配完全部空间</p><h2 id="虚拟机设置及其他"><a href="#虚拟机设置及其他" class="headerlink" title="虚拟机设置及其他"></a>虚拟机设置及其他</h2><p>打开virtual box,点击新建，选择完基本的信息，选择勾选<code>启用EFI</code>，磁盘这里要选择分配全部空间</p><p>我这里就分配70G,剩余空间用来存放东西</p><p><img src="/../picture/archtogo/vir1.png" alt="virbox1"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/archtogo/vir2.png" alt="virbox2"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/archtogo/vir3.png" alt="virbox3"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>之后正常安装ArchLinux或者其他的Linux系统即可</p><div class="trm-note warning"><div class="trm-note-title">WARNING</div><p>运行<code>grub-install</code>时需要带上<code>--removable</code>参数</p><p>一般像ubuntu installer这种有图形化安装工具的都自带这个参数</p><p>否则直接从硬盘启动(非GRUB创建的磁盘引导)会报错<code>No bootfile found for UEFI! Maybe the image does not support X64 UEFI.</code></p></div><h2 id="处理系统及放入U盘"><a href="#处理系统及放入U盘" class="headerlink" title="处理系统及放入U盘"></a>处理系统及放入U盘</h2><p>这里需要用到一个对ventoy的插件，<a href="https://www.ventoy.net/cn/plugin_vtoyboot.html">这里</a>有对处理的解释</p><p>1.到<a href="https://github.com/ventoy/vtoyboot/releases">Vtoyboot</a>下载vtoyboot文件</p><p>并挂载到虚拟机，复制到主目录解压后，终端内以root权限执行文件夹内的vtoyboot.sh</p><p><img src="/../picture/archtogo/vtoyboot.png" alt="挂载vtoyboot"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>2.复制虚拟磁盘镜像到U盘的Ventoy分区并改为.vtoy后缀</p><p><img src="/../picture/archtogo/U.png" alt="放入udisk"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>不出意外的话现在已经可以从U盘启动Linux了，此方法适用于大多数Linux系统</p>]]></content>
    
    
    <summary type="html">起初是在学校机房信息课每次配置环境麻烦，还因为某些东西第一次登陆要手机验证，于是想到了在U盘内安装的系统。本次安装由Ventoy启动，兼顾linux to go和正常安装其他系统的功能</summary>
    
    
    
    
    <category term="折腾" scheme="https://blog.neokoni.ink/tags/%E6%8A%98%E8%85%BE/"/>
    
    <category term="系统" scheme="https://blog.neokoni.ink/tags/%E7%B3%BB%E7%BB%9F/"/>
    
  </entry>
  
  <entry>
    <title>四川南充联通开通动态公网IPv4并更改桥接全过程</title>
    <link href="https://blog.neokoni.ink/2023/09/29/%E5%9B%9B%E5%B7%9D%E5%8D%97%E5%85%85%E8%81%94%E9%80%9A%E5%BC%80%E9%80%9A%E5%8A%A8%E6%80%81%E5%85%AC%E7%BD%91iPv4%E5%B9%B6%E6%9B%B4%E6%94%B9%E6%A1%A5%E6%8E%A5%E5%85%A8%E8%BF%87%E7%A8%8B/"/>
    <id>https://blog.neokoni.ink/2023/09/29/%E5%9B%9B%E5%B7%9D%E5%8D%97%E5%85%85%E8%81%94%E9%80%9A%E5%BC%80%E9%80%9A%E5%8A%A8%E6%80%81%E5%85%AC%E7%BD%91iPv4%E5%B9%B6%E6%9B%B4%E6%94%B9%E6%A1%A5%E6%8E%A5%E5%85%A8%E8%BF%87%E7%A8%8B/</id>
    <published>2023-09-29T04:55:55.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>今年的8月30日下午，开学的前一天，脑子一抽想再看下公网ip有没有戏</p><p>移动和广电没考虑过，都说移动很难搞，大多数根本不给，广电更难说，以前问的直接说只能开专线</p><p>再想到说电信早更改政策了，免费是不可能的了(即使有人还尝试让我看下)</p><p>所以最终选择了查询下联通</p><p><img src="/../picture/%E5%8D%97%E5%85%85%E8%81%94%E9%80%9A%E5%85%AC%E7%BD%91/dianxin.jpg" alt="中国电信客服"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>这是当时问电信客服的截图，有这价格我都买省内云服搭Frp了</p><h2 id="询问"><a href="#询问" class="headerlink" title="询问"></a>询问</h2><div class="trm-note info"><div class="trm-note-title">INFO</div><p>最好还是电话客服，在线客服并没有电话客服熟悉业务</p><p>电话客服有些也会套话术，比如”目前全球的IPv4地址都已经枯竭不拉布拉布拉”，直接换一个问即可</p></div><p>刚开始我只是下载<code>中国联通</code>客户端并在那询问，等的比较久，而且似乎并不是很熟悉这一方面，说他们那是无法查询这一块的</p><p>然后跑去看了下网页上的客服(应该和软件的差不多)，遇到个熟悉的，说了下区域他那边查了一下说没问题的，可以开</p><p>我还问”有没有像电信那样，要指定价位以上的套餐然后有额外收费之类的”，也回答没问题</p><p>我还有点不信，晚点又打电话问了下客服，确实可以</p><h2 id="办理"><a href="#办理" class="headerlink" title="办理"></a>办理</h2><p>在办理之前有在手机App上联系最近的官方营业厅问下套餐，套餐对我来说刚好，价格至少比我买云服务器做<code>内网穿透</code>便宜</p><p>然后在开学后的第二个周末就去携号转网+办理宽带了(携号免安装调试费还送流量这些)</p><p>一切办完后因为我赶时间说了一声，宽带师傅也很快来了，半个小时以内</p><h2 id="申请动态公网IPv4"><a href="#申请动态公网IPv4" class="headerlink" title="申请动态公网IPv4"></a>申请动态公网IPv4</h2><p>下午5点多要走了才想起申请公网，打了个电话给10010转人工客服，说明了下申请动态公网IPv4，说给我反馈了下就让我等电话了。</p><p>此时手机收到一条报障短信且提示微信关注XXX可以查看进度</p><p><img src="/../picture/%E5%8D%97%E5%85%85%E8%81%94%E9%80%9A%E5%85%AC%E7%BD%91/wx.jpg" alt="联通报障"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>可能是比较晚，联通那边等到第二天才给我回电话</p><h2 id="波折"><a href="#波折" class="headerlink" title="波折"></a>波折</h2><p>因为上学的原因，我手机必须关机，这使我错过了联通客服的电话</p><p>星期一中午一看，一堆未接，我尝试打回，但是没人接，只能晚上再试</p><p>晚上一开机，又是一堆未接电话，并且带一条短信</p><p><img src="/../picture/%E5%8D%97%E5%85%85%E8%81%94%E9%80%9A%E5%85%AC%E7%BD%91/lt.jpg" alt="未回复提醒"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>我对此非常抱歉</p><p>当然，第二天中午一开机，仍然一堆未接电话，但是好在这次打过去有人接听了</p><p>我说明了下情况，他也确定了我是那个要开公网的。</p><p>刚开始还说周末吧，说要怎样怎样，我问到流程时，他说那边改完要改一下光猫上网的<code>VLAN ID</code></p><p>我想这不对口了嘛，直接说这个没问题，我能进光猫超级账户后台。</p><p>他这听到后直接就谈成了下午就改，方便说改成什么，我们加了下微信</p><div class="trm-note info"><div class="trm-note-title">success</div><p>这里得给南充联通点个赞，没有问为什么，也没多层转接询问。直接开通了。</p></div><h2 id="设置光猫"><a href="#设置光猫" class="headerlink" title="设置光猫"></a>设置光猫</h2><p>晚上到家，发现家里的联通宽带上不了网了，登陆光猫后台，拨号显示”ISP服务器认证失败”</p><p>联通那边微信上说把VLAN ID从原来的XX改成XX，然后拨号</p><div class="trm-note info"><div class="trm-note-title">INFO</div><p>超级账户的信息，一般只有安装前一个月内可以，后面密码会随机更换，联系宽带师傅询问即可</p><p>超级账户登陆页: <code>http://192.168.1.1/cu.html</code></p><p>超级账户密码: <code>CUAdmin</code></p><p>这里的更改VLAN ID是在上网的那个网络设置里的</p></div><p>更改后保存，等待拨号成功，片刻后，ip地址就已经从原来的100.xx.xx.xx变成了124开头正宗的公网ip</p><p><img src="/../picture/%E5%8D%97%E5%85%85%E8%81%94%E9%80%9A%E5%85%AC%E7%BD%91/ip.jpg" alt="光猫界面"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/%E5%8D%97%E5%85%85%E8%81%94%E9%80%9A%E5%85%AC%E7%BD%91/chat.jpg" alt="联通人员聊天记录"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><h2 id="更改桥接"><a href="#更改桥接" class="headerlink" title="更改桥接"></a>更改桥接</h2><p>测试发现光猫的<code>虚拟服务器</code>似乎不能用，因此要想公网访问，只能使用运营商这个合约购买的Tp-Link路由器(已经是家里最好的了)</p><div class="trm-note warning"><div class="trm-note-title">WARNING</div><p>不要在无线桥接下Tp-Link设置宽带拨号，根本不行！</p></div><p>改桥接还是一样无法拨号，到光猫的超级后台找到<code>连接模式</code>改为”桥接”</p><p>路由器上网设置改为”宽带拨号上网”即可</p><p>片刻之后，就获取到了ip,即完成了所有步骤</p><p><img src="/../picture/%E5%8D%97%E5%85%85%E8%81%94%E9%80%9A%E5%85%AC%E7%BD%91/ht.jpg" alt="完成光猫设置"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/%E5%8D%97%E5%85%85%E8%81%94%E9%80%9A%E5%85%AC%E7%BD%91/tplink.jpg" alt="tplink状态"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><h2 id="吐槽"><a href="#吐槽" class="headerlink" title="吐槽"></a>吐槽</h2><p>非常好Tp-Link这个路由器，使我的IPv6地址消失</p><p>我测试过Openwrt的固件，可以正常获取IPv6</p><p>问为啥不用Openwrt的那个，Openwrt转发端口返回的是Openwrt的iP地址，而不是真实的访问者ip。</p><p>实在找不到解决办法，只能忍受这个Tp-Link</p>]]></content>
    
    
    <summary type="html">终于获得了家宽的动态公网IPv4，写下了这篇记录的文章，希望我的案例也可以帮助你申请家宽动态公网IPv4</summary>
    
    
    
    
    <category term="折腾" scheme="https://blog.neokoni.ink/tags/%E6%8A%98%E8%85%BE/"/>
    
    <category term="网络" scheme="https://blog.neokoni.ink/tags/%E7%BD%91%E7%BB%9C/"/>
    
  </entry>
  
  <entry>
    <title>1Panel搭建Uptime Kuma并配置https</title>
    <link href="https://blog.neokoni.ink/2023/07/26/1Panel%E6%90%AD%E5%BB%BAUptime-Kuma%E5%B9%B6%E9%85%8D%E7%BD%AEhttps/"/>
    <id>https://blog.neokoni.ink/2023/07/26/1Panel%E6%90%AD%E5%BB%BAUptime-Kuma%E5%B9%B6%E9%85%8D%E7%BD%AEhttps/</id>
    <published>2023-07-26T01:53:58.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>在用Vuepress搭建完服务器的文档站后准备搭建一个服务器状态监控站</p><p>静态网页用Uptime Robot的API发现只是tcping,不能监控mc服务器在线状态</p><p>于是搭建Uptime Kuma监控</p><p>环境部署均在1Panel面板进行</p><h2 id="安装软件"><a href="#安装软件" class="headerlink" title="安装软件"></a>安装软件</h2><p>第一步就是安装Uptime Kuma和OpenResty</p><p>登录1Panel,点击应用商店，找到Uptime Kuma和OpenResty点击安装</p><p>因为是Docker容器的安装方式，所以直接安装很快就能完成</p><p><img src="/../picture/1Panel%E6%90%AD%E5%BB%BAUptime-kuma/app.jpg" alt="1panel应用商店"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><h2 id="配置反向代理"><a href="#配置反向代理" class="headerlink" title="配置反向代理"></a>配置反向代理</h2><p>Uptime kuma默认端口是3001而且是http，外网访问总显示不安全</p><p>看不惯提示，所以还是配置下https</p><h3 id="新建反向代理"><a href="#新建反向代理" class="headerlink" title="新建反向代理"></a>新建反向代理</h3><p>1Panel选择”网站”，点击”创建网站”，选择”反向代理”</p><p>主域名可以随便写，与后续无关，写0.0.0.0都行</p><p>代号的话如果你是写的域名，应该会自动填充，写的ip的话就自行修改</p><p>代理地址填写<code>http://0.0.0.0:3001</code></p><p>点击确认就完成项目创建了</p><h3 id="配置反向代理-1"><a href="#配置反向代理-1" class="headerlink" title="配置反向代理"></a>配置反向代理</h3><p>找到刚创建的项目，点击”操作”中的”配置”进入配置页面</p><p>域名设置建议新建一个域名+端口。因为最终通过frp实现外网访问，所以填写<code>0.0.0.0</code>端口<code>3010</code></p><p>后续内网访问可以使用 http:&#x2F;&#x2F;主机地址:3010进入Uptime Kuma,能打开就说明反代理配置完成</p><h3 id="配置ssl证书"><a href="#配置ssl证书" class="headerlink" title="配置ssl证书"></a>配置ssl证书</h3><p>https肯定还是要一个ssl证书的，1Panel自带Acme一键生成且自动续签</p><p>1Panel点击”证书” 没有Acme账户要创建一个，很简单，输入邮箱就可以了</p><p>然后点击”DNS账户”用于自动验证域名所有权进行DNS认证(不添加也行，可以手动解析验证)</p><p><img src="/../picture/1Panel%E6%90%AD%E5%BB%BAUptime-kuma/auth.png" alt="dns验证方式"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>DNS账号支持添加阿里云，DNSPod和CloudFlare</p><p>完成后点击添加证书，主域名是你后续要外部访问的域名，其他域名顾名思义，按需要添加</p><p>acme账户选择刚添加的</p><p>验证方式按自己需要选择，并选择”自动续签”</p><p>等一会就会有证书已经颁发了</p><h3 id="配置https"><a href="#配置https" class="headerlink" title="配置https"></a>配置https</h3><p>点击1Panel内的网站，点击”操作”中的”配置”进入配置页面</p><p>点击”Https”，选择”启用Https”,HTTP选项按需要选择</p><p>“ssl选项”选择”选择已有证书”，”Acme账户”选择之前添加的</p><p>“证书”选择刚才注册的，其他的默认就行</p><p>然后点击保存</p><div class="trm-note warning"><div class="trm-note-title">WARNING</div><p>大坑，如果你本地访问不是警告而是停止连接就没有自动配置，需要手动启用https连接</p></div><p>之前我们在”域名设置”里设置了反代理到的域名+端口</p><p>但是如果访问有问题，https连接拒绝，就需要手动改配置文件</p><p>点击”网站设置”旁边的”配置文件”进行编辑</p><p><img src="/../picture/1Panel%E6%90%AD%E5%BB%BAUptime-kuma/peizhi.png" alt="编辑文件按钮"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>打开后能看见只为监听的443端口开启了https连接</p><p><img src="/../picture/1Panel%E6%90%AD%E5%BB%BAUptime-kuma/config.png" alt="编辑配置文件"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>因为我们是监听3010端口并开启https,所以在3010端口后内容和443端口一样就行</p><p>就像这样</p><p><img src="/../picture/1Panel%E6%90%AD%E5%BB%BAUptime-kuma/config2.png" alt="示例配置"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>点击”保存并重载”，就会发现3010端口已经可以连接并使用https了</p><p><img src="/../picture/1Panel%E6%90%AD%E5%BB%BAUptime-kuma/done.jpg" alt="ssl警告"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>出现警告是因为我们使用的IP进行访问，而不是域名。浏览器检测到SSL证书的域名与访问的地址不一致，所以出现了警告</p>]]></content>
    
    
    <summary type="html">在用Vuepress搭建完服务器的文档站后准备搭建一个服务器状态监控站，静态网页用Uptime Robot的API发现只是tcping,不能监控MC服务器在线状态，于是开始搭建Uptime Kuma监控</summary>
    
    
    
    
    <category term="折腾" scheme="https://blog.neokoni.ink/tags/%E6%8A%98%E8%85%BE/"/>
    
  </entry>
  
  <entry>
    <title>Minecraft生存服开服大致</title>
    <link href="https://blog.neokoni.ink/2023/07/23/Minecraft%E7%94%9F%E5%AD%98%E6%9C%8D%E5%BC%80%E6%9C%8D%E5%A4%A7%E8%87%B4/"/>
    <id>https://blog.neokoni.ink/2023/07/23/Minecraft%E7%94%9F%E5%AD%98%E6%9C%8D%E5%BC%80%E6%9C%8D%E5%A4%A7%E8%87%B4/</id>
    <published>2023-07-23T03:06:41.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>折腾了一个月的Minecraft服务器，看到有萌新问写了这一篇应该还算有用的文章</p><p>主要大致讲一下开一个MC生存服需要的一些东西</p><p>本文仅仅是阐述个人感受，不代表所有服务器</p><h2 id="用途"><a href="#用途" class="headerlink" title="用途"></a>用途</h2><p>这点的话大致可以分为两个类别</p><ul><li><p>好友服(好友之间一起联机，外人一般不知道有这个服务器)</p></li><li><p>公开的生存服(想长期开下去，让更多人加入一起玩)</p></li></ul><p>大概的就分这两类了，临时的服务器也算在好友服里</p><h2 id="好友服"><a href="#好友服" class="headerlink" title="好友服"></a>好友服</h2><p>好友服那成本就很小了，只是几个好朋友玩玩</p><p>好友服的话选择一些面板服就行了，但是怕的是服务商超开，所以也不要看那种便宜到离谱的了</p><p>关于面板服的选择，配置的话，按每天能保持在线5个人算</p><p>内存建议4G及以上，也不用太高,CPU核心在2到4核左右应该是差不多的。当然，需要按照实际需求来</p><p>面板服每月价格应该不会有多高</p><p>一般面板服也是E5的玩意，有些也有更好的CPU,但是几个人E5也够了</p><p>但是如果你每天消耗的服务器上行流量能稳定超过几个GB, 就看能力用算额外流量的服务商了  </p><p>如果你不想朋友看端口号别扭，几块钱甚至免费一年的域名也可以弄一个做<code>SRV解析</code>（只有Java版可以这样做）</p><p>但是如果朋友的电脑无法解析，那让他设置一下<code>DNS服务器</code></p><p>或者检查家里网络中是否有就2021年来说太老旧的路由器，尝试切换网络或者更换路由器</p><p>当然，也有免费的方案，自己已有设备开服务器，然后用免费的内网穿透让朋友连接</p><p>然后记得定期备份，好友服就到这里了</p><h2 id="公开生存服"><a href="#公开生存服" class="headerlink" title="公开生存服"></a>公开生存服</h2><h3 id="考虑"><a href="#考虑" class="headerlink" title="考虑"></a>考虑</h3><p>开这种服大概考虑以下几点</p><ul><li><p>玩家连接稳定(延迟与网络环境)</p></li><li><p>玩家游玩流畅(配置和网络)</p></li><li><p>一定的反作弊(至少别破坏公平性，看个人需求)</p></li><li><p>服务器宣传(不说别人都不知道你有服务器)</p></li></ul><h3 id="机器"><a href="#机器" class="headerlink" title="机器"></a>机器</h3><p>服务器可以选择云服务器，也可以是物理机</p><p>选择云服务器的话就是稳定，但是每月价格也是非常离谱的</p><p>云服务器能大厂选大厂，不行也能选小厂，但是配置不能落下，但是超开仍然存在</p><p>CPU至少有个4核心左右，也可以多，但如果不是用folia这种多线程端也不是要很多很有必要，多线程主要是给插件用的</p><p>内存建议在8GB及以上吧(给游戏服务器的)，要上的插件还是很多的</p><p>CPU性能也重要，都知道的那Minecraft服务器主要吃单核性能</p><p>单核的话CPU-Z在500及以上，Geekbench 5 CPU单核1200及以上，带点人还是可以的</p><p>当然，性能和机器能承载的人数成正比，越高越好</p><p>上物理机也是一样的</p><h3 id="网络方面"><a href="#网络方面" class="headerlink" title="网络方面"></a>网络方面</h3><h3 id="防火墙通过"><a href="#防火墙通过" class="headerlink" title="防火墙通过"></a>防火墙通过</h3><p>像阿里云，腾讯云这种在控制面板有出入口设置安全组的，只需要在控制面板设置就行了</p><p>但是如果安装了1panel,宝塔这种带防火墙的面板，也需要在面板内设置一下(出入方向)</p><p>以下是一些常见的设置</p><ul><li><p>基岩版 名称备注自取 端口对应配置文件端口(默认19132) 外部端口尽量一致 策略放行 类型UDP</p></li><li><p>Java版 名称备注自取 端口对应配置文件端口(默认25565) 外部端口尽量一致 策略放行 类型TCP</p></li></ul><h3 id="带宽"><a href="#带宽" class="headerlink" title="带宽"></a>带宽</h3><p>云服务器一般不限制下行，但上行带宽有限制</p><p>如果一个服务器10人在线，那最好带宽在10Mbps以上，至少一人1~2Mbps</p><p>不要信什么1Mbps可以带几个人</p><p>可以参考某乎上这个<a href="https://zhuanlan.zhihu.com/p/161211542">例子</a></p><h3 id="FRP内网穿透-云服务器跳过"><a href="#FRP内网穿透-云服务器跳过" class="headerlink" title="FRP内网穿透(云服务器跳过)"></a>FRP内网穿透(云服务器跳过)</h3><p>这一步为物理机开服玩家看，云服务器不需要(不可能你的服务商不给公网端口吧~)</p><p>相信能用物理机就是因为减少开销和更好的自定义了吧？</p><p>ipv4在国内比较紧缺，友友们可以尝试向运营商索要动态公网ip开服，这成本也是最小的</p><p>部分地区可能要不到，可以方法仅供联通和电信用户尝试，移动似乎也有小概率可以？</p><p>当然也可以使用纯IPv6开服，只是部分玩家无法加入（没有IPv6）</p><p>frp公共服务商可以用，但尽量选最近的，权限看情况选择，可以在对应服务商的交流群问，不然容易延迟大，高峰期卡顿</p><p>自己买云服务器搭建frp也是可以的，这个只要求带宽和线路，配置不重要，毕竟我用1核0.5GB的服务器都够</p><p>小云服务商买前建议联系客服测试一下，如果连接卡顿离谱就别买了或者连续ping出现不稳定现象，就不要考虑了，免得不好退款</p><p>另外一点，小白看到云服务商选地区那里说”可覆盖xx地区的用户”不要说为了更多人连接就选华中或者其他，选择离自己近的地区！！不然延迟就上来了</p><h3 id="反作弊"><a href="#反作弊" class="headerlink" title="反作弊"></a>反作弊</h3><p>这个东西的话，看需求，也有服务器完全靠人工的</p><p>但是有些东西比如反矿透还是需要开的</p><p>一般是靠插件实现，命令方块也行</p><p>市面上也有很多插件，看需求选择，找人定制或者自研也行</p><h3 id="宣传"><a href="#宣传" class="headerlink" title="宣传"></a>宣传</h3><p>比较重要，不说别人都不知道有你这个服务器</p><p>平常可以去<code>苦力怕论坛</code>，<code>Mine论坛</code>等网站宣传</p><h3 id="服务器系统"><a href="#服务器系统" class="headerlink" title="服务器系统"></a>服务器系统</h3><p>服务器系统最好Linux为主，Windows也可以</p><p>Linux建议选择Debian,Ubuntu,RockyLinux等口碑不错的服务器系统</p><p>Windows就别去装家用的什么专业版家庭版了，乖乖去装Windows Server</p><h3 id="资料备份"><a href="#资料备份" class="headerlink" title="资料备份"></a>资料备份</h3><p>定期备份数据，物理机建议多硬盘组除了raid0以外的类型的raid保护数据安全</p><h3 id="服务端优化"><a href="#服务端优化" class="headerlink" title="服务端优化"></a>服务端优化</h3><p>服务器配置优化非常重要，优化的好能大大减轻服务器负担并提升一定的性能</p><h2 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h2><p>希望你可以运营一个不错的Minecraft服务器!</p>]]></content>
    
    
    <summary type="html">折腾了一个月的Minecraft服务器，看到有萌新问写了这一篇文章，大致自述一下开一个MC生存服需要的一些东西，仅仅是个人感受，不代表所有服务器 。</summary>
    
    
    
    
    <category term="Minecraft服务器" scheme="https://blog.neokoni.ink/tags/Minecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/"/>
    
  </entry>
  
  <entry>
    <title>记录一次ArchLinux的重装过程</title>
    <link href="https://blog.neokoni.ink/2023/04/08/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1ArchLinux%E7%9A%84%E9%87%8D%E8%A3%85/"/>
    <id>https://blog.neokoni.ink/2023/04/08/%E8%AE%B0%E5%BD%95%E4%B8%80%E6%AC%A1ArchLinux%E7%9A%84%E9%87%8D%E8%A3%85/</id>
    <published>2023-04-08T11:42:47.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>1.虽然一般都是用的默认内核或者zen的内核(听说也可加点性能)，但我有点厌倦了默认内核的快速更新，所以本次内核使用的LTS长期支持版内核。</p><p>2.我为什么记录？有些东西不是很好找，比如某个主题，顺便也当写个教程</p><p>3.本文章适用于UEFI启动，非传统BIOS。显卡是amd的,使用有线网络连接</p><p>因此这个文章也可以当教程看，也是一步一步跟着wiki来的</p><p>吐槽一句:Arch Linux的中文wiki在某些地方与其他语言不一样，比如timedatectl和pacstrap</p><h2 id="一些可以说是初始化的步骤"><a href="#一些可以说是初始化的步骤" class="headerlink" title="一些可以说是初始化的步骤"></a>一些可以说是初始化的步骤</h2><h3 id="1-确认下联网"><a href="#1-确认下联网" class="headerlink" title="1 确认下联网"></a>1 确认下联网</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ping bing.com</span><br></pre></td></tr></table></figure><p>能正常上网就继续吧</p><h3 id="2-同步时间"><a href="#2-同步时间" class="headerlink" title="2 同步时间"></a>2 同步时间</h3><p>错误的系统时间会带来一些问题，所以最好同步一下时间</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">timedatectl set-ntp <span class="literal">true</span></span><br></pre></td></tr></table></figure><h2 id="2-挂载硬盘"><a href="#2-挂载硬盘" class="headerlink" title="2.挂载硬盘"></a>2.挂载硬盘</h2><p>UEFI启动的linux至少有个启动分区，还有个根目录分区(挂载点&#x2F;)。选加swap和home，但我推荐还是有</p><h3 id="先用lsblk查看一下硬盘分区"><a href="#先用lsblk查看一下硬盘分区" class="headerlink" title="先用lsblk查看一下硬盘分区"></a>先用lsblk查看一下硬盘分区</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">lsblk</span><br></pre></td></tr></table></figure><p>比如说我的分区就是这样</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS</span><br><span class="line">sda           8:0    0 465.8G  0 disk </span><br><span class="line">├─sda1        8:1    0    90G  0 part </span><br><span class="line">└─sda2        8:2    0 375.8G  0 part </span><br><span class="line">sdb           8:16   0 465.8G  0 disk </span><br><span class="line">├─sdb1        8:17   0   300M  0 part </span><br><span class="line">├─sdb2        8:18   0    10G  0 part </span><br><span class="line">├─sdb3        8:19   0    57G  0 part </span><br><span class="line">└─sdb4        8:20   0 398.5G  0 part </span><br><span class="line">sdc           8:32   1  57.7G  0 disk </span><br><span class="line">├─sdc1        8:33   1  57.6G  0 part /run/media/neokoni/neokoni-U</span><br><span class="line">└─sdc2        8:34   1    32M  0 part </span><br><span class="line">nvme0n1     259:0    0 238.5G  0 disk </span><br><span class="line">├─nvme0n1p1 259:1    0   300M  0 part </span><br><span class="line">├─nvme0n1p2 259:2    0 188.2G  0 part </span><br><span class="line">└─nvme0n1p3 259:3    0    50G  0 part </span><br></pre></td></tr></table></figure><p>我要安装的硬盘在是sdb的那块</p><h3 id="分区"><a href="#分区" class="headerlink" title="分区"></a>分区</h3><p>2TB以下可以使用cfdisk进行分区，我的500G用也刚好</p><div class="trm-note warning"><div class="trm-note-title">WARNING</div><p>多硬盘使用cfdisk时需要指定要分区的硬盘，不然默认会打开lsblk里的第一块硬盘</p></div><p>比如</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cfdisk /dev/sdb</span><br></pre></td></tr></table></figure><h3 id="格式化分区"><a href="#格式化分区" class="headerlink" title="格式化分区"></a>格式化分区</h3><p>Linux还是那几样的文件系统，boot的fat32,常见的ext4。当然你也可以使用btrfs等文件系统</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">mkfs.fat -F 32 /dev/sdb1 <span class="comment">#格式化为fat32文件系统，&quot;/dev/sdb1&quot;换成你自己需要的</span></span><br><span class="line"></span><br><span class="line">mkswap /dev/sdb2 <span class="comment">#格式化为交换分区，&quot;/dev/sdb2&quot;改成你自己的</span></span><br><span class="line"></span><br><span class="line">mkfs.ext4 /dev/sdb3</span><br><span class="line"></span><br><span class="line">mkfs.ext4 /dev/sdb4 <span class="comment">#格式化根目录和home分区，还是按自己需要改</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="挂载"><a href="#挂载" class="headerlink" title="挂载"></a>挂载</h3><h3 id="第一步是挂载根目录，此后才可以挂载其他的分区，比如boot和home"><a href="#第一步是挂载根目录，此后才可以挂载其他的分区，比如boot和home" class="headerlink" title="第一步是挂载根目录，此后才可以挂载其他的分区，比如boot和home"></a>第一步是挂载根目录，此后才可以挂载其他的分区，比如boot和home</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mount /dev/sdb3 /mnt <span class="comment">#挂载根目录</span></span><br></pre></td></tr></table></figure><h3 id="为其他挂载点创建文件夹"><a href="#为其他挂载点创建文件夹" class="headerlink" title="为其他挂载点创建文件夹"></a>为其他挂载点创建文件夹</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> -p /mnt/home <span class="comment">#创建home分区的挂载点</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">mkdir</span> -p /mnt/boot/efi <span class="comment">#创建boot分区的挂载点，也可以是/mnt/boot</span></span><br></pre></td></tr></table></figure><h3 id="接下来依次挂载"><a href="#接下来依次挂载" class="headerlink" title="接下来依次挂载"></a>接下来依次挂载</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">mount /dev/sdb4 /mnt/home <span class="comment">#挂载home</span></span><br><span class="line"></span><br><span class="line">mount /dev/sdb1 /mnt/boot/efi <span class="comment">#挂载boot</span></span><br><span class="line"></span><br><span class="line">swapon /dev/sdb2 <span class="comment">#启用swap分区</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>再次运行lsblk你就会发现已经挂载了</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS</span><br><span class="line">sda           8:0    0 465.8G  0 disk </span><br><span class="line">├─sda1        8:1    0    90G  0 part </span><br><span class="line">└─sda2        8:2    0 375.8G  0 part </span><br><span class="line">sdb           8:16   0 465.8G  0 disk </span><br><span class="line">├─sdb1        8:17   0   300M  0 part /mnt/boot/efi</span><br><span class="line">├─sdb2        8:18   0    10G  0 part [SWAP]</span><br><span class="line">├─sdb3        8:19   0    57G  0 part /mnt</span><br><span class="line">└─sdb4        8:20   0 398.5G  0 part /mnt/home</span><br><span class="line">sdc           8:32   1  57.7G  0 disk </span><br><span class="line">├─sdc1        8:33   1  57.6G  0 part /run/media/neokoni/neokoni-U</span><br><span class="line">└─sdc2        8:34   1    32M  0 part </span><br><span class="line">nvme0n1     259:0    0 238.5G  0 disk </span><br><span class="line">├─nvme0n1p1 259:1    0   300M  0 part </span><br><span class="line">├─nvme0n1p2 259:2    0 188.2G  0 part </span><br><span class="line">└─nvme0n1p3 259:3    0    50G  0 part</span><br></pre></td></tr></table></figure><h2 id="换源"><a href="#换源" class="headerlink" title="换源"></a>换源</h2><p>默认的镜像源位于国外，下载速度也非常不乐观，所以要换成国内源</p><p>输入以下命令就能编辑镜像文件</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/pacman.d/mirrorlist</span><br></pre></td></tr></table></figure><p>按下<code>A</code>键就进入了编辑模式</p><p>因为文件是从上往下检索的，所以直接编辑最上面的那个镜像源就行了</p><p>请确保第一个镜像源是，被注释的内容是蓝色的</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Server = https://mirrors.bfsu.edu.cn/archlinux/<span class="variable">$repo</span>/os/<span class="variable">$arch</span></span><br></pre></td></tr></table></figure><p>我个人喜欢用北外源</p><p>按下<code>ESC</code>键再按下<code>Shift</code>键输入<code>:wq</code>就可以保存并退出了</p><h2 id="安装软件包"><a href="#安装软件包" class="headerlink" title="安装软件包"></a>安装软件包</h2><h3 id="安装archlinux-keyring"><a href="#安装archlinux-keyring" class="headerlink" title="安装archlinux-keyring"></a>安装archlinux-keyring</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pacman -Sy</span><br><span class="line">pacman -S archlinux-keyring</span><br></pre></td></tr></table></figure><p>这一步不知道从什么时候成了需要，不装上的话pacstrap有些包可能会校验失败</p><h3 id="正式安装"><a href="#正式安装" class="headerlink" title="正式安装"></a>正式安装</h3><p>人们总喜欢在这里只安装基本包，但我喜欢这里能装的都装上</p><p>这里是官方wiki上的</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pacstrap /mnt base linux linux-firmware</span><br></pre></td></tr></table></figure><p>有点少，所以下面这个是某乎教程上的包</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pacstrap /mnt linux linux-firmware linux-headers base base-devel vim git bash-completion</span><br></pre></td></tr></table></figure><p>我说过，我喜欢在这里装很多的包,而且我说了我要LTS内核，接下来是我常用的</p><p>tips: 桌面环境为gnome,别的请自行替换</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">pacstrap /mnt base linux-lts linux-lts-headers linux-firmware base-devel \</span><br><span class="line">        neovim iwd networkmanager ttf-dejavu sudo bluez nano usbmuxd dhcpcd \</span><br><span class="line">        ntfs-3g wqy-zenhei grub efibootmgr jdk17-openjdk jdk8-openjdk intel-ucode amd-ucode \</span><br><span class="line">        pulseaudio xorg pacman gnome fcitx5 fcitx5-chinese-addons fcitx5-gtk fcitx5-qt fcitx5-configtool \</span><br><span class="line">        zsh zsh-autosuggestions zsh-syntax-highlighting zsh-theme-powerlevel10k zsh-completions </span><br></pre></td></tr></table></figure><h2 id="生成fstab文件"><a href="#生成fstab文件" class="headerlink" title="生成fstab文件"></a>生成fstab文件</h2><h3 id="what’s-fstab"><a href="#what’s-fstab" class="headerlink" title="what’s fstab?"></a>what’s fstab?</h3><p>fstab是linux下记录挂载的文件系统的文件，linux会在开机时依次挂载</p><h3 id="生成"><a href="#生成" class="headerlink" title="生成"></a>生成</h3><p>Arch Linux为我们提供了生成fstab的脚本，运行以下命令就会自动生成</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">genfstab -U &gt;&gt; /mnt/etc/fstab</span><br></pre></td></tr></table></figure><p>至此第一阶段的安装就算完成了</p><p>输入一下命令进入第二阶段的安装</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">arch-chroot /mnt</span><br></pre></td></tr></table></figure><h2 id="链接vim"><a href="#链接vim" class="headerlink" title="链接vim"></a>链接vim</h2><p>如果你使用的是我的pacstrap包，如果不是，请忽略这一步</p><p>我们安装的是neovim,启动命令是nvim,为了方便，我们可以软连接一下</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">ln</span> -s /bin/nvim /bin/vim</span><br><span class="line"><span class="built_in">ln</span> -s /bin/nvim /bin/vi</span><br></pre></td></tr></table></figure><h2 id="设置时区"><a href="#设置时区" class="headerlink" title="设置时区"></a>设置时区</h2><p>不出意外的话，咱们应该是在中国吧？</p><p>所以这里照样以上海举例(别怀疑，就是上海)</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">ln</span> -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime </span><br><span class="line">hwclock --systohc</span><br></pre></td></tr></table></figure><h2 id="设置语言"><a href="#设置语言" class="headerlink" title="设置语言"></a>设置语言</h2><p>这里涉及两个文件<code>/etc/locale.gen</code>和<code>locale.conf</code></p><p>至于locale.gen，使用以下命令编辑</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/locale.gen</span><br></pre></td></tr></table></figure><p>这里有很多标准，我们只需要管下面的这几个</p><p>这次不用按<code>A</code>，按下<code>X</code>就可以删除指向的字符</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">en_US.UTF-8 UTF-8  </span><br><span class="line">en_US ISO-8859-1</span><br><span class="line">zh_CN.GB18030 GB18030  </span><br><span class="line">zh_CN.GBK GBK  </span><br><span class="line">zh_CN.UTF-8 UTF-8  </span><br><span class="line">zh_CN GB231</span><br></pre></td></tr></table></figure><p>照样按<code>Shift</code>后输入<code>:wq</code>保存并退出</p><p>运行下面的命令就可以启用刚才的配置了</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">locale-gen</span><br></pre></td></tr></table></figure><p>然后再设置下语言</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> LANG=en_US.UTF-8 &gt;&gt; /etc/locale.conf</span><br></pre></td></tr></table></figure><p>不要疑问，就是英文。控制台下不要设置中文，会乱码！</p><h2 id="设置设备名"><a href="#设置设备名" class="headerlink" title="设置设备名"></a>设置设备名</h2><p>最直观的就是bash显示的这个</p><p><img src="/../picture/ArchLinux%E5%AE%89%E8%A3%85%E8%AE%B0%E5%BD%95/1.png" alt="bash显示的用户名"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>输入下面的命令就可以设置了，<code>archlinux</code>可以换成你准备用的</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">&quot;archlinux&quot;</span> &gt;&gt; /etc/hostname</span><br></pre></td></tr></table></figure><h2 id="添加用户以及设置hosts文件"><a href="#添加用户以及设置hosts文件" class="headerlink" title="添加用户以及设置hosts文件"></a>添加用户以及设置hosts文件</h2><p>linux默认只有一个root账户，但这显然是不安全的</p><p>使用下面的命令添加一个用户，<code>neokoni</code>可以换成你自己的用户名</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">useradd -m -G wheel -s /bin/zsh neokoni  <span class="comment">#如果使用bash就将zsh换成bash</span></span><br></pre></td></tr></table></figure><p>然后就是设置hosts文件</p><p>输入以下命令编辑hosts文件</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/hosts</span><br></pre></td></tr></table></figure><p>输入以下内容</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">127.0.0.1 localhost</span><br><span class="line">::1 localhost</span><br></pre></td></tr></table></figure><h2 id="设置pacman-conf"><a href="#设置pacman-conf" class="headerlink" title="设置pacman.conf"></a>设置pacman.conf</h2><p>这里我们将会设置两个东西，一个是archlinuxcn,另一个是系统对32位包的支持</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/pacman.conf</span><br></pre></td></tr></table></figure><p>找到最后一部分，去掉multilib的注释，然后设置成如图</p><p><img src="/../picture/ArchLinux%E5%AE%89%E8%A3%85%E8%AE%B0%E5%BD%95/2.png" alt="pacman.d配置"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>然后更新下源</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">pacman -Syyu</span><br><span class="line">pacman -S archlinuxcn-keyring</span><br></pre></td></tr></table></figure><h2 id="安装aur管理器"><a href="#安装aur管理器" class="headerlink" title="安装aur管理器"></a>安装aur管理器</h2><p>aur有很多用户上传的包，也算arch系发行版的特色之一，使用下面的命令安装yay</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pacman -S yay</span><br></pre></td></tr></table></figure><h2 id="设置sudo"><a href="#设置sudo" class="headerlink" title="设置sudo"></a>设置sudo</h2><p>不设置不能正常使用sudo,设置也很简单</p><p>编辑&#x2F;etc&#x2F;sudoers</p><p>取消注释掉下面这一行的内容就可以了</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%wheel ALL=(ALL:ALL) ALL</span><br></pre></td></tr></table></figure><p>大概就这个样子</p><p><img src="/../picture/ArchLinux%E5%AE%89%E8%A3%85%E8%AE%B0%E5%BD%95/3.png" alt="sudoers配置"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>保存退出即可</p><h2 id="设置开机启动的服务"><a href="#设置开机启动的服务" class="headerlink" title="设置开机启动的服务"></a>设置开机启动的服务</h2><p>保存这些设置可以让他们开机后自动启动，以免造成一些功能的无法使用</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">systemctl <span class="built_in">enable</span> systemd-resolved.service</span><br><span class="line">systemctl <span class="built_in">enable</span> bluetooth.service</span><br><span class="line">systemctl <span class="built_in">enable</span> NetworkManager</span><br><span class="line">systemctl <span class="built_in">enable</span> dhcpcd</span><br><span class="line">systemctl <span class="built_in">enable</span> gdm</span><br></pre></td></tr></table></figure><h2 id="设置fcitx5的环境"><a href="#设置fcitx5的环境" class="headerlink" title="设置fcitx5的环境"></a>设置fcitx5的环境</h2><p>我们使用fcitx5在linux输写中文，这里可以顺便配置一下</p><p>可跳过</p><p>将下面内容添加到&#x2F;etc&#x2F;environment即可</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">GTK_IM_MODULE=fcitx</span><br><span class="line">QT_IM_MODULE=fcitx</span><br><span class="line">XMODIFIERS=@im=fcitx</span><br><span class="line">INPUT_METHOD=fcitx</span><br><span class="line">SDL_IM_MODULE=fcitx</span><br><span class="line">GLFW_IM_MODULE=ibus</span><br></pre></td></tr></table></figure><h2 id="设置开机引导"><a href="#设置开机引导" class="headerlink" title="设置开机引导"></a>设置开机引导</h2><p>不设置开机引导可是无法进入系统的</p><p>这里使用grub进行引导，pacstrap已经安装了</p><p>&#x2F;dev&#x2F;sdb1是你的引导分区，按需求改</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">grub-install --target=x86_64-efi --efi-directory=/dev/sdb1 --bootloader-id=<span class="string">&quot;Arch Linux&quot;</span></span><br><span class="line">grub-mkconfig -o /boot/efi/grub/grub.cfg  <span class="comment">#生成配置文件，&quot;/boot/efi&quot;按需要改</span></span><br></pre></td></tr></table></figure><h2 id="设置密码"><a href="#设置密码" class="headerlink" title="设置密码"></a>设置密码</h2><p>这里包括root账户密码和个人账户密码</p><p>使用passwd进行设置，也可以进行更改</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">passwd root  <span class="comment">#设置root账户密码</span></span><br><span class="line">passwd neokoni  <span class="comment">#设置个人账户密码，&quot;neokoni&quot;改成自己的用户名</span></span><br></pre></td></tr></table></figure><h2 id="重启"><a href="#重启" class="headerlink" title="重启"></a>重启</h2><p>到此Arch Linux就算安装完了，输入exit就退出了arch-chroot环境</p><p>再输入reboot就重启了！基本的系统就已经安装完成啦！</p>]]></content>
    
    
    <summary type="html">自用的archlinux重装过程记录，方便自己后续使用</summary>
    
    
    
    
    <category term="折腾" scheme="https://blog.neokoni.ink/tags/%E6%8A%98%E8%85%BE/"/>
    
    <category term="系统" scheme="https://blog.neokoni.ink/tags/%E7%B3%BB%E7%BB%9F/"/>
    
    <category term="记录" scheme="https://blog.neokoni.ink/tags/%E8%AE%B0%E5%BD%95/"/>
    
  </entry>
  
  <entry>
    <title>联想TB-X504F 9008刷机指南</title>
    <link href="https://blog.neokoni.ink/2023/02/04/%E8%81%94%E6%83%B3TB-X504F-9008%E5%88%B7%E6%9C%BA%E6%8C%87%E5%8D%97/"/>
    <id>https://blog.neokoni.ink/2023/02/04/%E8%81%94%E6%83%B3TB-X504F-9008%E5%88%B7%E6%9C%BA%E6%8C%87%E5%8D%97/</id>
    <published>2023-02-04T03:24:04.000Z</published>
    <updated>2026-08-09T05:32:53.759Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><div class="trm-note warning"><div class="trm-note-title">WARNING</div><p>1.刷机包文件仅适用于Lenovo TB-X504F,不适用于其他机型</p><p>2.教程仅分享个人经验，刷机有风险，操作需谨慎！</p><p>3.所有文件均来自互联网，此处仅为转载使用</p></div><h2 id="Step-1-准备好需要的文件"><a href="#Step-1-准备好需要的文件" class="headerlink" title="Step 1 准备好需要的文件"></a>Step 1 准备好需要的文件</h2><p>Driver.exe : 9008驱动</p><p>Qualcomm_Flash_Image_Loader_v1.0.0.2.zip : 刷机工具</p><p>Lenovo_Tab_4_10_REL_TB-X504F_S000007_180621_ROW_QDLE.zip : 刷机包本体</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/11.png" alt="刷机文件"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>文章末尾有下载链接</p><h2 id="Step-2-安装9008驱动"><a href="#Step-2-安装9008驱动" class="headerlink" title="Step 2 安装9008驱动"></a>Step 2 安装9008驱动</h2><p>双击Driver.exe文件，应该会出现这个界面，选择默认的第一个(WWAN-DHCP)再点Next就行</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/12.png" alt="驱动安装"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>之后的操作也很简单,一直默认Next就行了</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/13.png" alt="驱动安装开始"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/14.png" alt="选择安装类型"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/15.png" alt="选择安装路径"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>到了最后一步点Install等待安装完成就行了</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/16.png" alt="安装完成"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>安装完后可能会有重启的提示，但可有可无</p><h2 id="Step-3-准备好刷机的工具"><a href="#Step-3-准备好刷机的工具" class="headerlink" title="Step 3 准备好刷机的工具"></a>Step 3 准备好刷机的工具</h2><p>解压Qualcomm_Flash_开头的那个文件</p><p>解压完后双击打开文件夹，再双击打开里面的QFIL.exe</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/111.png" alt="QFIL文件"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>应该会看到这样一个界面</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/112.png" alt="QFIL主界面"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>不要随意操作，跟着教程来就行了</p><h2 id="Step-4-进入9008刷机模式"><a href="#Step-4-进入9008刷机模式" class="headerlink" title="Step 4 进入9008刷机模式"></a>Step 4 进入9008刷机模式</h2><p>平板关机状态下按住电源键和音量加减键，同时将数据线与电脑连接</p><p>如果屏幕闪了一下，电脑出现提示音，平板前置摄像头附近的红灯在闪就进入了刷机模式</p><p>这个时候电脑打开设备管理器，就可以看到9008端口啦</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/118.png" alt="9008端口"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><div class="trm-note info"><div class="trm-note-title">INFO</div><p>有一定几率进入9008模式后又退出9008，重新操作进入9008这一步就可以了</p></div><h2 id="Step-5-选择文件并开始刷机"><a href="#Step-5-选择文件并开始刷机" class="headerlink" title="Step 5 选择文件并开始刷机"></a>Step 5 选择文件并开始刷机</h2><p>解压刷机包本体并输入解压密码等待解压完成</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/19.png" alt="压缩包密码"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><div class="trm-note warning"><div class="trm-note-title">WARNING</div><p>解压密码: <code>password</code></p></div><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/110.png" alt="uncompressing"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>QFIL软件中点击Browse</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/1.png" alt="select1"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>文件选中刷机包中的.mbn文件</p><p>确定后差不多是这个样子</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/114.png" alt="selectmbn"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>接着点击右下角的Load XML</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/2.png" alt="selectxml"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>文件选择的窗口会弹出两次，分别选择对应的文件就好了</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/115.png" alt="selectdoe1"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/116.png" alt="selectdone22"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>选好之后大概这样</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/121.png" alt="selectdone"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>点击右下角的Download就开始刷机了</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/3.png" alt="startflash"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/122.png" alt="flashing"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><p>刷机完会自动重启，直到出现这个界面就算刷机完成了</p><p><img src="/../picture/TB-X504F%E5%88%B7%E6%9C%BA/4.jpg" alt="booted"  data-tag='post-image' onload='this.onload=null;this.style.opacity=1;' loading="lazy" onerror='this.onerror=null;this.src="/img/404.jpg"'></p><h2 id="Q-A"><a href="#Q-A" class="headerlink" title="Q&amp;A"></a>Q&amp;A</h2><ol><li></li></ol><p>Q:为什么因为乱刷包变砖刷回官方系统后会无限卡死重启？</p><p>A:可能是因为之前刷机包修改了设备的某些数据，但这部分在本刷机包中不存在</p><p>联想官方系统可能出于保护系统的目的，会无限卡死重启。这种情况恢复原因目前不详</p><p>可暂时强刷<a href="https://forum.xda-developers.com/f/thinkpad-tablet-android-development.1435/">xda论坛</a>中X304系列机型的卡刷包(毕竟配置一样)，就是相机不能用</p><h2 id="文件下载"><a href="#文件下载" class="headerlink" title="文件下载"></a>文件下载</h2><ul><li><p>link1:<a href="https://h5.cloud.189.cn/share.html#/t/fY7JviqqIbYb">天翼云盘</a>  访问码：03lm</p></li><li><p>link2:<a href="https://www.123pan.com/s/81d8Vv-Szomd">123网盘</a></p></li></ul>]]></content>
    
    
    <summary type="html">本站第一篇文章。刷机包来自于自己在pdd商家自费购买，其他工具源于互联网。文中提到的所有东西都会免费的</summary>
    
    
    
    
    <category term="刷机" scheme="https://blog.neokoni.ink/tags/%E5%88%B7%E6%9C%BA/"/>
    
  </entry>
  
</feed>
