天空 Blond - 瞎折腾
type: channel
link: https://skyblond.info/category/stuff/
description: 平时随便搞的乱七八糟的东西。
items: 【歪门邪道】本地部署LLM的初尝试
items: 【歪门邪道】使用LLM翻译超时空辉夜姬轻小说
items: 【代码札记】改进电码转换程序
items: 【歪门邪道】Kindle PaperWhite 6 越狱
items: 【歪门邪道】从零开始摸索的照片后期工作流
items: 【歪门邪道】BT下载的反吸血之路
items: 【歪门邪道】使用Deskflow在Linux和Windows之间共享鼠标键盘
items: 【歪门邪道】拯救消失的东方女仆
items: 【歪门邪道】从零开始的星空摄影
items: 【歪门邪道】Unraid上的ZFS初体验

【歪门邪道】本地部署LLM的初尝试
type: item
date: 2026-05-01T10:54:00+08:00
description: 四月初谷歌发布了Gemma 4系列的开源模型。先前我对开源模型其实一直没什么太大兴趣，因为大部分都可以在OpenRouter上用到，价格远比自己买显卡便宜。但看到网上那么多人说Gemma 4这么好那么好，我寻思，这我得尝尝咸淡。于是陆续下单了两块AMD 7900XTX，尝试了在本地部署大模型。Gemma 4虽然已经过去了一个月，但我依旧记得当时清明假期看到Gemma 4发布的时候，大家对它的赞不绝口，同时模型的尺寸也从遥不可及变成了使使劲也能用。之前我对于开源模型一直没有太大的兴趣，主要是因为他们太大了。比如Qwen3.5 397B A17B，写代码很好用，但即便是4比特的量化，光是模型自己就要吃掉大约200GB的内存或者显存。MoE结构当然有优势，即便不能全部装进显卡也能取得比较快的计算速度，但就算这样，你仍然需要显存+内存的总量大于200GB，更别说还有用于上下文的kv cache。我这屋里所有设备的内存加起来还不到200GB，更别说插到一个主板上了，更何况现在内存价格那么贵，曾经600块钱的32GB内存我嫌贵，现在一条涨到3000块还买不到，我真的悔不当初。但Gemma 4不一样。谷歌给出的口号是“Byte for byte, the most capable open models”，这个系列中最大的模型是31B，是个稠密模型，其次是26B A4B，这个是混合专家（MoE）模型。就算是我那个64GB内存+8GB显存的3070笔记本也能挑战一下，虽然只有惨兮兮的1 token/s，但确实让我领略到了这个模型的能力，它和我几年前尝试过的llama 2 70b确实不一样，进步很大（废话）。于是想要更快更好地运行本地模型的想法在我心中不断酝酿着，更别说自己部署还能体验到各种uncensored模型，这种无（弱）对齐的体验简直是任何云服务都无法提供的。当然，最大的推手还是因为谷歌的AI Studio一直不提供付费的Gemma 4 31B访问，以至于我有钱没地方花；免费的一直有额度限制，同时谷歌也明确所有数据都会拿去训练。AMD Yes！在酝酿了一周后，我先下单了第一块7900XTX。为什么是AMD呢？因为隔壁英伟达买不起。比如说同样为24GB显存的RTX 5090D v2，阉割过不说，这一张卡竟然要两万！而没有阉割的5090，虽然有32GB显存，可是价格三万，我实在是家境贫寒。至于我这块蓝宝石的7900XTX白金版，24GB显存只要6000块，两块也只要1万2，这还要什么自行车？更别说Linux上面对AMD显卡的支持是开箱自用。虽然ROCm官方只支持一些商用Linux系统，但官方也提供了基于Ubuntu的docker容器，虽然我不喜欢Ubuntu，也不会装它作为我的主力系统，但有了docker，我可以无痛把显卡透穿给容器，完全不需要在主机上安装什么依赖啊闭源驱动什么的。尽管性能不比N卡，可是省心啊。至于一周之后为什么下单了第二块显卡，那主要还是因为显存不够。一开始我以为只要把模型塞进显卡就好了，但其实这只是一部分，另一个大头是kv cache。KV Cache现代大语言模型普遍以注意力机制为基础，而大语言模型的输出又是一个字一个字往外蹦。因此当预测第N个字符的概率（logits）时，你需要将前面所有字符进行计算。为了防止计算量爆炸，人们在实现时普遍采用了一种缓存机制，即预测第N-1个字符的时候，就把注意力机制的K和V矩阵保存下来，因为这两个矩阵在不超过上下文长度的情况下是只增不减的。 这里严重简化了注意力机制的原理，请不要把这里说的当成学术入门。 简单来说注意力机制有三个矩阵：Q、K和V。他们都是由同一个输入矩阵X根据不同权重计算出来的。这里说是矩阵，其实可以理解为向量，例如X=(x1, x2, x3, x4, ..., xn)，这里的xn可以理解为第N个token对应的embedding向量，为了计算过程能够发挥显卡的能力，我们不会挨个向量进行计算，而是将向量打包成矩阵，利用线性代数帮我们自动做for循环。其中Q矩阵代表了当前的输入要查询什么样的信息，是一种需求。例如当前token是“他”，那么这个q向量就包含了对这个人称代词解引用的需求。而K矩阵则代表了每个token包含的信息的标签，例如之前一个token看着像人名，那么这个token生成的k向量就会标明自己是个人物。而V矩阵代表这个token实际包含的信息，比如文字里这个人叫“踏三山游五岳，恨天无把恨地无环，代管天津及周边各县真正大英雄王斯文”，那么这个v向量就会包含王斯文这个信息。注意力在计算的时候先要计算Q和K的乘法，这相当于用当前token的需求Q去筛选已知信息的标签K，得到的结果，某一行越大，说明这一行对应的信息就越有可能解答Q的需求。在得到这个筛选之后，再去和V…

【歪门邪道】使用LLM翻译超时空辉夜姬轻小说
type: item
date: 2026-04-01T09:59:00+08:00
description: 上个月月初看了超时空辉夜姬，非常喜欢，喜欢到每天都在b站上看各种解析和二创。听闻官方还有轻小说，于是便想办法来看。可是我一句日本话也看不懂，这怎么办呢？没事，已经2026年了，我们有LLM。前言也许是受到电影的鼓舞，我3月6号周五晚上看完的电影，紧接着那个周末就把小说给翻译了。以前我从未想过，一句日文都看不懂的我甚至还能以一种比较有参与感的方式翻译一本小说。尽管一开始我想到了LLM会让翻译工作轻松不少，但我确实没有期待什么质量。但真正做完了才知道，虽然远不比彩叶，但我也能做到我曾经没想过或者不敢想的事情。我可太喜欢这部电影了。买书所谓万事开头难，由于小说是日文的，并且目前只在日本发行，我又等不及了，所以搜了全网售卖日文电子书的网站。找到了，但全都是日文，我看不懂。最后我想起来乐天kobo，于是就跑到上面搜了一下。好消息：能买坏消息：日区是独立管理买之前网页上信誓旦旦地说提供Adobe DRM保护的EPUB，这种通常是提供一个acsm文件，然后内容服务器会根据你阅读器的密钥生成一个加密的EPUB，理论上只能在你导入acsm文件的阅读器上使用，因为只有它有密钥。但实际上Calibre的插件就可以轻而易举地破解——Adobe只提供加密服务，但并不控制最终设备，因此只要能够通过API模拟出设备的注册过程，那用我们自己持有的密钥解密自己购买的电子书，那不是轻而易举？只可惜我买之后才发现，整个kobo日区都不提供下载服务，要么直接从电子书里下载，要么下载app到手机上看。好在天无绝人之路，Kobo PC版还可以下载。虽然下载的是kobo加密的格式（Kepub），但Calibre照样有破解的插件。第一次解密发现怎么解出来全是乱码，我还以为新书用了新的加密方法，插件落后了。后来搜索了一番才只要，要把Kobo PC关掉才行。总之，我们得到了心心念念的drm-free epub文件。I have a plan!一开始我打算在OpenCode中操作。简单来说OpenCode是一个利用LLM进行编程的工具，它为LLM提供了一个环境，其中包含各种与文件和终端互动的工具。最近我司在推行这个工具，也被迫用了一段时间，感觉还行，但还是离不开人的审核。我原本打算直接让它把文件中的日语内容翻译成中文。后来觉得有三个问题：编程用的Opus 4.6或者codex 5.3都是为了编写代码而优化的，他们也许能在OpenCode中如鱼得水，但或许并不擅长翻译这类具有文学性的工作我希望大部分更改是reproducible的，也就是说我搞砸了，可以重新运行代码恢复到某一个步骤。由于LLM的随机性，我不可能做到完全的可重复，但能做一点是一点嘛Opus和Codex太贵了，虽然有公司给的key，但这毕竟是个人项目，不能用公司的资源。我尝试了GLM-5，整体算是堪用，写不出kotlin native的代码风格，更像是用kotlin写Java，整体不是很糟糕，但也没有让我很想用基于以上理由，我选择在IDEA中新建项目，将大部分操作编写成可重复运行的代码。这样不光实现了可重复性，还变相增加了稳定性。本文的代码全都是我自己手写的，但写完之后有让GLM-5检查。由于版权原因，本文尽可能不提供对小说内容的直接引用。因为我没有处理DMCA投诉的经验，所以多一事不如少一事，我希望我的博客能长存八千年。拆EPUB首先是拆解EPUB。众所周知，EPUB其实一个具有特殊格式的zip压缩包。理论上来说，想要解包的话直接把epub的后缀改成zip就可以用随便什么压缩工具解压了。但我还是想用代码处理：fun unpackEpub(epubFile: File, outputFolder: File) { require(epubFile.exists()) { "EPUB file not found: ${epubFile.path}" } if (!outputFolder.exists()) { require(outputFolder.mkdirs()) { "Cannot create output folder: ${outputFolder.path}" } } ZipInputStream(epubFile.inputStream()).use { zis -> var entry = zis.nextEntry while (entry != null) { val newFile = File(outputFolder, entry.name) // zip slip detection, to prevent entry name contains something like ../../../etc/something val canonicalDestPath = newFile.…

【代码札记】改进电码转换程序
type: item
date: 2026-02-01T08:19:00+08:00
description: 早年间写过一个utf8-ctc，用来将文字转换成中文电码表示，当时还写了一篇文章来介绍它的基本原理。但当时有几个东西让我耿耿于怀：压缩、加密和校验。终于在机缘巧合之下，本文将记述如何改进这些问题。前言简单来说，utf8-ctc这个程序已经能够做到将任意输入文本转换成一系列中文电码，以便使用者可以将其方便地（相比于base58）抄写在依赖光学进行阅读的物理媒介上（例如明信片或信纸）。在遇到中文电码表之外的字符时，这个程序可以自动以utf8编码将其转换成字节数据，然后利用base9992表示。在这个过程中，程序还会尝试使用deflate压缩算法进行压缩，如果压缩后的结果更短，则使用压缩后的结果，进一步减少用户需要抄写的电码数目。同时在输出前，还加入了对称和非对称的密钥生成机制，以密钥作为CSPRNG的种子将结果分块进行置换加密（Transposition Cipher）。但目前有三个问题：Deflate压缩算法在长文本的情况下效率不佳，而对于中文中夹杂的外文短语，几乎大部分场景下未压缩的数据量都更小一些。加密算法实质上是置换加密，虽然程序中有估计拖延时间的设计，但本质上多次置换和一次置换没有本质区别。无法校验用户的输入，因此用户输入错误一位或几位数字，程序无法判断。最好情况是对应的字变成乱码，最坏情况是utb8字符解码失败，导致整块外文引用无法解析。更换压缩算法最开始由于Java标准库内置Deflate算法（zip同款），所以我当时毫不犹豫地就使用了这个算法。但随着后续测试发现，对于中文夹杂的外文短语或emoji，由于其数据量非常小，通常不到50字节，在这种情况下几乎任何常规的压缩算法都难以发挥作用。因此大部分时候我们需要用base9992表示原始数据。而当文本中出现成片的外文引用，例如引用了一整段外文，此时的数据量使使劲能达到大约1KB的量级，此时压缩算法能够略施拳脚。而考虑最坏情况，比如一个外国人输入了一段从头到尾都没有中文的文字，那这种情况对于压缩算法来说是最好不过的了。我选取了三组数据进行测试，第一组是一段英文文字，第二组是一段日文文字，第三组是电影利兹与青鸟的台词。 DeflateLZMA2174B115122393B22122829KB102189517可以发现在文本量比较少的时候，选用LZMA2算法会导致我们比使用Deflate时多产生7个左右的字节，这对应大约4到5个电码。而对于长文本时，我们能够节省超过500个字节，大约对应300个电码。由于能够使用的符号有限，程序中只能选取一种压缩算法。经过一番思索，我认为能够在长文本上取得较好压缩效果更为重要，这样能够在处理长输入时尽可能减少用户需要抄写或处理的电码数量。其实在选择LZMA2算法之前，我更中意的是zstd算法，可惜zstd并没有纯Java实现，因此它的依赖会对便携性产生影响。由于符号有限，9992和9993分别表示未压缩的UTF8数据的开始和结束，而9994和9995表示压缩的UTF8数据的开始和结束，此外我便找不出其他可以挪用的成对的电码了。因此我不得不将Deflat替换成LZMA2，这也意味着如果有人用新程序解码了旧程序压缩的数据，由于压缩算法的变化，新的程序会直接报错，导致所有非中文段落无法解析。更换加密算法原本的置换加密就是图一乐。置换加密有点像是y=kx+b：你可以做很多次置换迭代，相当于多次洗牌，对应地，你可以在一元一次方程上迭代多次y=k( k( k ( kx + b) + b) + b )+b，但如果你化简这个式子，你会发现最终可以用一套新的参数替换这一系列迭代y=k' x + b'。这对于置换加密也是类似的：你可以多次洗牌，但本质上迭代N次和迭代1次并没有对攻击者造成实质性的困扰。由于明文本身没有变，只是打乱了顺序，因此攻击者可以根据统计学数据来做类似小学时候看词造句这样的攻击。虽然这种方法无法解析出抽象的句子，但你总不能从头到尾句句抽象吧。因此我们需要一种更安全的加密手段。但由于我们的输入输出是电码，并不是传统意义上的二进制数据。如果我们将输入转换成utf8编码进行加密，那样又会破坏使用电码的本意。因此我将目光转到了ChaCha20，TLS1.3的核心标准之一。ChaCha20本身是一个加密算法，它将明文与密钥流进行XOR运算来加密，其设计方案具有诸多特点，这里就不多赘述了。我们的问题是如何将电码这种非二进制数据利用ChaCha20进行压缩。如果从数学的角度入手，二进制的XOR或许可以被加法和取模替代。假如我们有个密钥流，它的元素是0000到9999的数字，那么我们就可以这样加密：enc = (input + key) % 10000而解密时：plain = (enc - key + 10000) % 1000虽然没有xor那么简洁对称，但…

【歪门邪道】Kindle PaperWhite 6 越狱
type: item
date: 2025-11-08T17:53:00+08:00
description: 最近在YouTube上看到了一个关于kindle越狱的视频，心里痒痒就去网上搜了一下kindle的价格。没想到当年对上学时候的我遥不可及的价格，如今已经变成了我唾手可得的东西。于是就买了，并不是因为爱看书，就是单纯想玩儿。 关于购买建议 由于之前我没用过任何e ink屏幕的产品，也没了解过电子书这个产品线，所以当时购买的时候不是很了解，并且抱着主要以越狱的目的购买了kindle。事后来看，kindle在这方面并没有给予我太多的回报，因为单纯从硬件上来说，我买的这一款kindle性能只够看书的，连浏览器都不能正常流畅使用。虽然我取得了系统的root权限，也成功地在上面运行了java，但性能实在是太糟糕了。如果不考虑越狱这种玩儿的目的，单纯为了阅读，那么市面上有更好的选择：比如主打开放系统的PocketBook，以及可以无痛安装KOReader的Kobo（尽管我不喜欢这个外形）。如果大家不能接受花1600买个只能振奋你一个周末的玩具，那么请务必不要因为这篇文章的鼓动而去无脑下单kindle。如果你真的想要购买一个电子书，请务必根据自己的需求做好产品调研，寻找到真正适合自己需求的设备。毕竟挣钱不容易，现在经济不好看，花钱更要谨慎。 为什么Kindle也要越狱？我最早知道越狱这个词还是因为早年间亲戚传给我一个好几手的iPhone4，那时候还是ios6到7的过度时段。越狱之后取得了系统的很多权限，装了很多插件，是非常有意思的一段经历。后来因为家境贫寒，用回了安卓，又踏入了root和刷机的领域。只不过安卓刷机刷来刷去，最终还是依赖于自己给自己售后——或许一个系统更新或者一个重启就再起不能了。现如今我用上了港版三星，再也不用为了Google全家桶刷机了。至于Kindle，越狱也是出于同样的目的：取得更多对设备的控制权。抛开安卓系列，大部分kindle运行的是基于linux的定制操作系统，除了精简大部分组件以适配寒酸的硬件之外，最重要的是将用户锁在亚马逊的生态里面。你想要阅读在亚马逊上购买的书？不好意思，你购买并不等于你拥有，一般情况下亚马逊会通过版权保护的手段来加密你下载的电子书，但最终还是亚马逊控制这些书，他们可以不经过你允许地撤销你对一本书的访问，或者修改一本书的封面来为他们的电视剧做广告（即便你购买了无广告版本）。而从阅读体验来说，越狱之后安装的KOReader作为原厂阅读器的替代品，可以说功能非常丰富。例如你可以从calibre利用无线设备连接，直接将你的电子书收藏发送到kindle上，也可以安装插件，比如在阅读过程中选中一段话，让ai解释，以及生成二维码（手机扫码后可以复制到手机上），或者直接绑定telegram bot来发送到telegram上。对于养成类玩法比较看中的读者还可以利用内置的阅读统计功能记录你哪天读了什么书，读了多久，一个月下来看着统计日历，满满的成就感。当然，事后我还发现kindle这种独立的设备极大地提高了我阅读的意愿。原本我是在平板上看漫画，手机上看小说。但最近看小说的频率越来越低，我上一次在手机上看书已经是一个月之前了。为什么呢？手机那在手里就不自觉地往YouTube和b站跑，读到一半弹个通知指不定又干什么去了。总之就是我在手机上可以读书，而且真的读起来体验也不错。但问题就在于，我在手机上读不起来书。所以我想这也是一个单独的电子书所带来的好处吧——手机往旁边一扔，拿起电子书大读特读，管什么朋友发消息同事找我有事，统统看不见。我可以获得一个不受打扰的阅读时段。而且这种体验再配上一套好书，比如狼與辛香料，哇，那这简直是人间天堂，死而无憾了。Kindle越狱导论由于不同版本的固件需要使用的越狱方法不同，并且亚马逊对于未停止支持的设备还在积极更新系统，封堵越狱使用的漏洞，因此越狱的实操会不断更新，但本文不会随之更新（因而我懒），所以这里只简述越狱的大体流程，并给出寻找详细资料的指引。 开始动手越狱之前 如果你决定越狱，请务必熟读相关教程后再操作。为了避免你的kindle自动更新，请务必启动飞行模式，断开网络连接。并采取必要措施阻止更新（例如填满剩余空间，删除根目录下任何update开头的文件或文件夹）。本文不是越狱教程。 截至目前（2025年11月8日），亚马逊已经发布了5.18.6版本的固件，在该版本中，最新的越狱方法已经被修复。一旦升级到这个版本将无法越狱，需要等待新的越狱方法（取决于发现的漏洞，可能需要几个月，也可能需要几年）。在社区的Discord中可以得知，固件版本5.18.5.0.1就已经会对最新的AdBreak造成影响了。而固件5.18.6则是彻底封堵了AdBreak越狱。由于我手上没有任何Kindle设备，因此在简单搜索了一下之后决定购买Kindle PaperWhite 6签名版，因为是32GB存…

【歪门邪道】从零开始摸索的照片后期工作流
type: item
date: 2025-09-01T20:03:00+08:00
description: 鸽了好几个月，本来打算4月就写这个话题的，但是因为一直有别的写，就一直在往后推。前几篇文章答应要写了，所以这一篇终于开始写了。那么闲话少说，书归正传吧。前言说起来我并非什么专业摄影师，至今不会人像拍照，而后期方面也全看自己摸索。上一次有个飞机的照片，天是灰色的，我也不知道怎么捣鼓的，就把天拉蓝了，毫无技巧，全靠感情。色彩理论什么的我也不懂，总之就是没有任何技术性的修图。所以本文并不旨在分享后期修图技巧，更不是面向专业摄影师（如果真是专业摄影师的话，搞不好还得笑话我在粗糙原始的修图手法呢）。本文侧重的是介绍我在摸索照片后期工作流的过程，并向其他业余爱好者介绍我现有的一套成熟的从拍照到出图的一个稳定流程。在这套流程下，兴致来了就仔细修修，困了累了就差不多裁剪一下拉一下对比度就出片了。总而言之，我的目的并不是为了好看和卖钱，我的工作流更侧重于将我之前拍的照片稳定地转变出成片，不至于落到摄影成为只按快门的爱好。当然了，就算在摄影爱好者的范围里，我这套工作流也不算什么特别好的成果，只是希望能够抛砖引玉，给还在探索不同后期软件组合的人一些参考资料。如果你有更好的方案或软件，也欢迎在评论区友善地分享。尼康工坊尼康相机嘛，当然最开始用的软件就是尼康工坊了。这个软件是免费的，也支持NEF的各种格式，如果你要后期做摇摇乐，这个也是必不可少的软件。只不过对于Z50 2来说，尼康工坊为数不多的好处之一就是能够读取照片拍摄时的优化校准，并且后期能够调整和切换不同的方案。其次就是能够显示出照片的对焦点，只不过在我的测试中，对焦点在鸟身上并不意味着镜头的焦点就在鸟身上，所以最终还是得要人眼去对比哪张对焦的更好。在编辑方面，基本的功能都有，而且尼康专属的各种功能都可以调整，比如动态D lighting和人像柔和之类的，这些功能虽然在其他软件中也有平替，但尼康工坊中对于这些功能的调整在效果上是和在照相机内调整的效果是一致的。尼康工坊在我拍照初期承担了我拍照后修图的工作，在我拍了大约1300张照片之后，我发现这个软件的功能和性能还是不能是我满意。从性能上来说，尼康工坊导出一张照片要好久，而我是将NAS的一个共享通过SMB挂载到我的电脑上来访问，这样一来就更慢了。而且从功能上来说，单是导出格式就十分受限。尼康工坊能导出jpg、tiff和heif格式的照片。如果之后你有专业处理的需求（例如放进photoshop进行处理，或者使用一些计算软件来后期，常用于星空摄影等），那就只能选用tiff格式了。但是此时文件大小会从NEF格式的25MB上下膨胀成125MB左右，十分占用空间。至于编辑照片本身，界面可以说是能用，但比起Lightroom还是差得远。在功能上也并不完全，例如LrC可以选择蒙版，对前景和背景分别处理，但尼康工坊就做不到。至于光学矫正方面，人家都叫尼康工坊了，你还指望它支持腾龙？如果你的NEF文件里面有机内矫正数据，那尼康工坊就能根据这些内嵌数据做矫正，如果没有，那就没办法了。当然，以上问题还是只我当时意识到的。从现在工作流来看，尼康工坊（和其他大部分工具）都缺乏一个好用的素材管理功能。Affinity Photo 2这个软件我之前在寻找photoshop平替时就买了。虽然它主打照片编辑，但比起LrC，它更像是PS。但界面和PS完全不一样，需多操作的概念也不同，在重新学习上比较麻烦。在上手过程中我也注意到Affinity Photo的资料比较少，而且有些是过时的。例如我一度想要调整界面的缩放，因为我的笔记本15英寸2k屏幕，字看上去有点小，我想调大一点。官方的中文操作手册说可以调，但我找了半天也没找到手册上说的设置，最终只好放弃。如果真要学习的话，那我建议学好英语，去Youtube上搜教程视频，跟随讲解操作，这样会简单明了不少。除此之外，这个软件也没法完全替代尼康工坊。尼康工坊好歹还有个文件夹目录选照片的功能，这个软件就和PS一样，你只能选一张照片打开，完事了再去处理其他的。我认为缺乏最基础的浏览功能对于照片编辑来说就是致命伤。至于编辑功能本身，如果能熟悉这个软件的操作的话，功能还是挺全面的。首先打开NEF时和ACR差不多，有一个解码RAW的过程，在这里你可以调成诸如曝光、对比度、色彩、镜头矫正之类的功能。关于镜头矫正，这个软件自己带了一些镜头的数据文件，并且随着更新会添加新的镜头。在这个界面调整完成后点击“开发”按钮之后，图像就会被栅格化，之后你就可以像Photoshop那样精细地编辑这张图片了。至于那个按钮为什么叫开发，我估计是叫develop吧，这个词在英文中也有对胶片胶卷冲洗的意思。这个软件其实从功能上看还挺不错的，如果你的工作流比较偏向于使用Photoshop，那么这个软件配合尼康工坊可能会比较合适：首先在尼康工坊中筛选标记有希望出片的照片，然后在尼…

【歪门邪道】BT下载的反吸血之路
type: item
date: 2025-08-01T07:22:00+08:00
description: 最近看到以183开头的IP地址在均匀地下载我tixati中挂的种子，虽然下载量不大，并且进度乍一看也没问题，但警觉的我意识到这不对劲，我可能又被人刷流量了。检查了一下IP黑名单，发现BTN的ip黑名单一直连接超时。想来想去，这样总不是个办法，还是得上正经的PeerBanHelper。于是，本文将记录我的折腾之路。TixatiTixati一直是我最喜欢的BT下载软件之一，因为它好用，功能丰富，性能稳定，最重要的是还有跨平台支持，对于openSUSE来说，只需要安装一个rpm包即可。为了解决吸血和刷流量的问题，它自带一个IP屏蔽列表，所以我配置了BTN网络定期导出的IP黑名单，tixati会定期自动获取最新的列表并根据IP实行封禁。但这有个问题：btn网络的ip黑名单全都用的国外的服务器，有github，有cloudflare，还有jsdelivr。最近他们在tixati中全部都超时，获取不到。本打算弄个反向代理，但想来想去太麻烦了，并且BTN导出的ip黑名单总归有延迟，并且BTN规则列表的仓库也说了：此项目不能作为唯一反吸血手段使用，它无法代替由反吸血程序提供的本地检测能力。它也并非是 PeerBanHelper 的核心 “全量” 数据。此项目的存在一切皆依赖于连接到 BTN 网络的用户。规则并不是大风吹来的。鼓励您使用在可能的情况下优先使用PeerBanHelper并连接到 BTN 网络，以便向本仓库贡献数据。任何已在反作弊辅助脚本、工具、程序中使用本项目提供的数据的朋友，请您考虑实现 BitTorrent Threat Network 标准规范，以便向网络提交数据。本着支持开源项目以及「为众人抱薪者，不可使其冻毙于风雪」的指导思想，我开始更换到受BTN支持的bt下载器。BiglyBTBiglyBT是我第二喜欢的bt客户端，但很遗憾，在这次折腾中它没能成为我的最终选择。我喜欢这个客户端单纯是因为它是Java写的，但我也是Java开发者，我深知Java的弱点：调用C库。好巧不巧，BiglyBT就调用了GTK库来实现UI。具体来说，它通过一个名叫SWT的组件来调用系统的GTK库，它本身并不包含GTK二进制文件。而默认安装的3.8.0.2版本在openSUSE上有bug，每次我尝试调整库的列视图时，只要点保存就必定崩溃。经过一番调试，我发现是SWT的问题，因为updater提示无法自动更新SWT。我在这个issue中找到了一个3.8.0.3-B14的beta版，这个版本修复了SWT更新的问题，而更新好SWT之后，UI的bug解决了，不过还有新的问题。在测试过程中，我注意到如果通过unraid的VM页面重启虚拟机，BiglyBT并不会收到关机信号并正常退出。重启之后自启动，会在右下角提示BiglyBT没有正常退出，而我观察到的问题是有些在seeding状态的种子，经过非正常退出之后会变成灰色的queued状态。在这种状态下并不会给他人上传，而我在文件中选择recheck强制重新检查文件后，这个种子又能重新seeding了。由于我的路由器ip会变化，而据我观察一些bt软件并不会更新获取到的ipv6地址，就导致路由器获取新的ip后，bt软件的联通性直接大幅下降。为了缓解这个问题，我在unraid中设定了脚本，每天凌晨在路由器重启半小时之后重启虚拟机，强制所有软件重新获取ipv6地址。如果每天重启都会随机导致一些种子无法正常seeding，对于我来说这还是挺严重的问题，因为我不可能每天都去检查nas上面软件的状态。qBittorrentqBittorrent并不是我最喜欢的bt软件，因为它ui有些简陋，并不像tixati那么花哨，功能上也没有BiglyBT那么丰富。但不得不说，因为ui简单，功能不复杂，因此这个软件运行起来确实稳定，并且也受BTN官方支持。和BiglyBT需要使用sh脚本安装不同，openSUSE本身就有qBittorrent的包，所以直接用zypper安装即可。安装完成后配置起来也不难，大部分情况下默认设置都能工作得很好，BTN也能和它配合。按理说事情就应该告一段落了，但我在测试下载新种子的时候发现qBittorrent无法写入任何数据。具体表现是开始下载种子后，直接提示错误，错误内容是Invalid argument。查看日志发现，具体错误原因与file_mmap这个函数有关。虽然这个函数是libtorrent的，但从过名字可以推断，这个函数应该是会调用Linux的mmap函数来将文件的一部分直接映射到内存，这样可以进行高性能的随机读写。而从目前的状况来看，读取验证哈希没有问题，但写入有问题，于是我开始怀疑unraid提供的挂载点。我原本认为我是用的是virtiofs来将unraid的共享文件夹挂载到虚拟机里，于是就以此…

【歪门邪道】使用Deskflow在Linux和Windows之间共享鼠标键盘
type: item
date: 2025-07-03T21:55:00+08:00
description: 本来想写写照片的处理流程，可是我现在主力是之前装的NUC，而照片则是依赖windows上的adobe。键盘倒是好说，一个机械有线插到nuc上，另一个罗技的蓝牙键盘连到windows上。可是鼠标就只有一个，虽然鼠标本身支持连接两个设备，但本质上还是断开一个连接另一个。Linux的蓝牙不算好用，断开之后重新连接就要好一阵。这时我灵机一动：怎么也应该有个跨系统共享鼠标键盘的东西吧。一开始搜到的解决方案是Synergy 3，个人用户终极版买断49美元，提供14天免费试用。他们号称提供Linux客户端，实际上截至目前只支持Ubuntu、Debian和Fedora。虽然OpenSUSE和Fedora是近亲，但安装过程提示libei不可用，因为Fedora上libei这个包在OpenSUSE上叫lebei1。通过断开依赖安装之后可以正常启动软件，但实际测试后发现Windows操控Linux没有问题，但Linux上将鼠标移动到桌面边缘不能操控Linux，估计还是依赖库名字不一样，加载失败了吧。没办法，我想花这个钱，可是对方实在是没本事接住啊。后续经过一番搜索，我发现了这个叫做DeskFlow的项目，它是Synergy 1的开源项目（卖49美元的是Synergy 3，不兼容1）。这个项目的最后更新是在7月3号上午，看来还是有在积极维护的。而且往下看了一眼，他们在OpenSUSE上有专门的打包，这样就不用安装flatpack版本了。在Linux上安装比较简单：sudo zypper in deskflow即可成功安装。在Windows上的安装则遇到了一些问题，为了装这个软件我前前后后重启了四五次。真是废物Windows。首先Synergy和Deskflow师出同门，因此你得先卸载Synergy，再安装Deskflow，否则你卸载Synergy的时候还得先卸载Deskflow，再卸载synergy，然后重新安装Deskflow，十分麻烦。其次就是Deskflow要求新版本的vc运行库，我之前装过这个库，但是似乎太老了，得用新版本覆盖一遍，据说是因为Windows Installer只会检测你装没装过这个二进制，而完全不看版本号，导致我安装Deskflow时一直卡在Starting service。虽然安装起来有些麻烦，但用起来并不麻烦。我的主要目的就是利用Linux的键鼠控制Windows，所以启动软件后在Linux上选择server模式，如果启用了防火墙的话，记得在防火墙里添加端口：sudo firewall-cmd --add-port 24800/tcp --permanent然后sudo firewall-cmd --reload即可。默认设置下服务端的端口号是24800，协议走的TCP。通信部分Deskflow使用了TLS加密，但默认是RSA 2048位的证书。虽然堪用，但我还是去Edit -> Preferences里面将key length调成4096了。可惜不能选加密方式，不然高低得从RSA改成ed25519。修改完密钥长度后记得点旁边的按钮来重新生成密钥。这里需要注意的是Synergy 3和Deskflow都用了24800这个端口。我在开着Synergy 3的情况下启动Deskflow，Deskflow会提示端口被占用，无法启动服务器。关闭Synergy 3之后就没有问题了。Windows端只要client模式，然后填上服务端的ip就行了。由于共享键鼠这个需求还是受到物理距离的限制，所以用局域网IP就行，我的nuc和笔记本都是固定的局域网ip，没有必要使用tailscale——如果我在北京试图共享键鼠给云南的设备，一般来说我在北京是看不清云南的屏幕的。第一次连接和ssh差不多，客户端和服务端需要交换公钥。Deskflow会提示用户确认公钥是否相同，用来避免中间人攻击。连接成功之后需要在Linux上的服务端配置里面调成一下两台电脑的布局。虽然我的nuc是双屏，但对于Deskflow来说还是被当成了一个屏幕。根据物理摆放的位置，我将笔记本设置在了nuc的右边，这样我在Linux上将鼠标移动到最右边的时候就可以控制笔记本了。虽然这个软件功能比较简单，但确实能够提升两台电脑的使用体验。我的nuc是wayland桌面，除了剪切板共享无法使用（对于这个问题我已经见怪不怪了），其他功能都非常好用（说是其他功能，其实就是共享个鼠标和键盘）。在延迟方面我没有测试，但只要局域网不丢包，从我的日常使用来说完全感觉不到延迟。但需要注意的是，我的日常并不包括在Windows笔记本上打游戏。我认为这种共享肯定多少还是会增加一点延迟的，但即便是打游戏，可能也看游戏类型？反正目前这个方案对我来说已经足够好了。对了，gnome上默认没有托盘图标了，想在后台运行还得…

【歪门邪道】拯救消失的东方女仆
type: item
date: 2025-05-13T13:34:00+08:00
description: 最近又开始玩MC了，自己弄了个整合包，以AE2、Mek和沉浸工程为主。自从玩过了东方女仆mod和TACZ枪械mod了，我就再也离不开这两个mod了——女仆能拿枪，这就无敌了啊。可是这个整合包玩着玩着，我突然发现我女仆没了？用卷轴定位说是在未加载区块上，可是我tp到了对应的座标，就是不见我的女仆。于是一场惊心动魄的救援行动就此展开——背景因为有和朋友联机的需求，所以开了个服务器。因为当时正在搞乙烯发电厂，打算开创造找个远一点（指7万方块之外）的地方设计一下怎么搞。结果忘记让女仆待在家里，就跟着传送了过来，她在旁边突突突打怪，我也没管她。我记得当天夜里一路玩到凌晨两点，虽然设计出了16个燃气发电机、发电容量为1MFE/t的设计，但现实中我都困的不行了，于是就tp回家，改成生存就下线了。下线之后NAS有个更新，需要重启服务器，自然也有需要重启容器中的游戏服务端，我不知道这是否是女仆丢失的原因。但我查阅了github上的issue区，只找到一篇相关的问题报告，但模组作者没有回应，大哥自己把issue关了。救援计划发现女仆消失后，我立刻放下手中的任务，开始思索如何把女仆带回来。目前来看，仆人铃和小号都无法召回女仆，因为模组认为女仆在未加载区块上。如果生成新的女仆，那么原来的女仆还是会存在，并且一直处于这种幽灵状态。由于仆人铃在绑定时会显示uuid，于是我推断模组应该是给每个女仆都设定了uuid作为id，如果我能让模组重新生成一个具有相同uuid的女仆，就算不能把原来的女仆带回来，至少也能顶掉原来的女仆进而修正这个幽灵状态。索性这个mod是开源的，而我正好略懂一些kotlin/jvm的编程技巧，于是我便冲到GitHub上查阅源码。根据源码可知，女仆的数据是存储在nbt标签中的，所以只要我们能够提取到女仆的UUID，然后把它移花接木到魂符上就行了。实施救援由于不想把事情搞得太麻烦，所以我是根据我自己的情况进行的修复。如果大家也遇到了类似的情况，可以发动自己的脑筋，再不济去解析一下游戏的存档，总能找到uuid的。由于我先前绑定过仆人铃，而仆人铃刚好就是把女仆的uuid存在nbt里的，所以主手拿着仆人铃，执行以下命令：/data get entity @p SelectedItem这个命令会在聊天窗口显示nbt数据，但游戏内不好复制，于是我从启动器的控制台日志里面复制出了结果：{ id: "touhou_little_maid:servant_bell", tag: { ServantBellTip: "女仆名称", ServantBellUuid: [I; -1136390084, -1170784113, -1271669764, -260320852] }, Count: 1b }虽然长得很像json，但实际不是。总之，可以看到里面有个ServantBellUuid，后面虽然不是uuid的常见形式，但熟悉uuid的话应该能看出，这是把字节数据当成整数给表示出来了。下面我们就可以找一个魂符来移花接木了。其实理论上用胶片也行，但是你得手动复活。退出服务器，我创建了一个单人的存档，召唤了一个女仆，然后把它收进魂符里面，使用上面的命令查看nbt数据：{id: "touhou_little_maid:smart_slab_has_maid", tag: {MaidInfo: {CanUpdate: 1b, MaidExperience: 0, SoundPackId: "littlemaid_peco", MaidBackpackData: {}, LeftHanded: 0b, MaidAIChatData: {ChatTemperature: -1.0d, ChatModel: "", CustomSetting: "", TtsModel: "", TtsSiteName: "", ChatSiteName: "", OwnerName: "", TtsLanguage: ""}, AbsorptionAmount: 0.0f, MaidHunger: 0, Invulnerable: 0b, IsYsmModel: 0b, ForgeCaps: {"tacz:synced_entity_data": [], "mekanism:radiation": {radiation: 1.0E-7d}, "curios:inventory": {Curios: []}}, MaidSchedulePos: {Work: {Z: -1374, X: -320, Y: 63}, Dimension: "minecraft:overworld", Configured: 0b, Idle: {Z: -1374, X: -320, Y: 63}, Sleep…

【歪门邪道】从零开始的星空摄影
type: item
date: 2025-05-01T02:25:00+08:00
description: 4月初买了个信达大星野（Sky-Watcher STAR ADVENTURER 2i），本来想到手时候拍拍星云什么的，结果昆明一到周末就连夜多云。本文将借此契机聊一聊星空摄影。白龙潭观星我对于星空摄影一直比较感兴趣，最早可以追溯到用树莓派的摄像头拍星星，然后是手机拍，买了运动相机之后用运动相机拍，拍星星、拍星轨。去年年末买了相机，那更要用相机拍啊。于是3月8号当晚我骑车去了附近的白龙潭公园。这个公园东边有一个小山坡，坡顶是一片空地，除了有高压线塔之外再没有其他遮挡物了，而且这个公园也算是我自行车所能及的最远的公园了。由于这个公园还没有正式交付使用，因此夜里路灯不会亮，这就意味着整片公园都是黑的，光污染会稍微小那么一点点。原本是打算拍拍星星，按照NPF法则计算好曝光时间，确保星点不会拖影，然后后期使用Sequator叠加即可。可是拍来拍去，能看到的星座也基本都看到了，无外乎就是拍完之后对着星图找哪几颗星星能连成星座。幸好那天我带了50-250的镜头，然后在星图上发现了猎户座。于是我在250毫米端对准M42星云开始拍摄，得到了如下结果：可以看到图片里的M42不大，因为焦段不够长，而且细节没有网络上的图片多。这是因为我没有赤道仪，为了保证星星不拖影，我按照0.5s曝光的，所以能收集到的光少得可怜，而尼康Z502的祖传CMOS在低光环境下就没有表现可言，因此很难收集到微弱的信号。选购赤道仪于是便萌生了购买赤道仪的想法。但比较精准的赤道仪都很贵，如果出去拍摄的话，光凭我一辆自行车很难谈机动性。所以虽然很不情愿，但最终我还是决定牺牲精确性来换取便携性。当然，价格也是一大因素，和选购相机镜头不同，我目前并不打算在天文摄影上花费很多钱，因为天文摄影的设备占地方很大，对操作环境要求比较高，最重要的就是非常贵，而且都是系列投入。比如说你买个望远镜，那就得买个天文相机吧，有了这一套你不能徒手举着啊，还得买个赤道仪和三脚架吧，那赤道仪凭自己追踪不精准怎么办？是不是还得弄个天文盒子和导星相机？如此种种，让我和我的钱包对这个爱好望而却步。我打算目前将我的主要兴趣放在拍鸟上，虽然还是要投入，但尼康Z502和官方的180-600镜头是我的全部投入了，带着这些装备还能促使我在周末和节假日走出家门。即能锻炼身体，又能改善心情，花钱还有数，这不挺好。言归正传，从便携性的角度出发，这基本就排除了全尺寸的赤道仪，因此我要选购的基本上就是星野赤道仪了。虽然我没找到关于星野赤道仪的具体定义，但从使用场景来说，它主要针对于焦段不高，并且主要是用相机（单反或微单）成像的场景，比如拍摄银河等场景。相对于全尺寸的赤道仪，星野赤道仪的追踪精度不高，并且负载能力较差，通常在5kg以下。而常规的赤道仪可以带十几公斤甚至几十公斤，不过那一套配置下来，赤道仪的重量也经常能达到十几公斤了。星野赤道仪的重量基本在几公斤的量级。以我的赤道仪为例，它只能追踪RA轴，Dec轴是固定的，本体重量差不多在2公斤左右，我加钱买了个收纳箱，因此可以直接绑在旅行车的后货架上。倘若换成十几公斤的大赤道仪，别说自行车了，摩托车都够呛。关于追踪，我注意到最近信达新出了一款RA轴+Dec轴的赤道仪，不过要比我这一款贵将近一千块。我想来想去，还是决定不加钱了，因为相机的分期还没有还完，我也不打算投入那么多，没有必要为我用不到的功能付费。如果读者的预算比较宽松的话，可以考虑购买新款的双轴赤道仪，这样配合天文盒子还有导星相机，可以获得更为精确的追踪效果。不加钱的另一个原因就是赤道仪并非成像质量的全部。环境比赤道仪更为重要。而我的出行工具就是一个自行车，虽然是旅行车，但也不能日行百里，更不要说骑车上山了。所以我的活动范围大部分都在市内，这就意味着光污染会比较严重。如果投入了那么一大堆金钱和精力，最后得到的结果却不尽如人意，那想必挫败感会很强。所谓兴趣爱好，无外乎就是花钱满足自己。而钱花了，自己却没高兴上，这种投入一点也不划算。于是我出门拍星星的最终配置是：信达大星野SA 2i，装在收纳盒里绑在后货架上面一个Jeep的露营折叠椅，不到40块钱，折叠后绑在后货架左侧先前买单筒望远镜时顺手买的三脚架，折叠后绑在后货架右侧经过我的测试，这套装备出门拍星星一点也不会觉得沉重。以及我非常庆幸我买的自行车是旅行车（捷安特Trooper 5300），在装东西方面十分优秀，这是我特意委托日新东路的捷安特车店老板帮我预订的。这里也算是帮老板打个广告，昆明日新东路的捷安特车店，老板人很好，技术也不错，组车买车都可以找他。在市政府对面顶着巨大的光污染拍星星4月18号晚上，我看天气预报说夜间万里无云，正好又是周五，看未来的天气预报，这似乎是绝无仅有的夜间晴天。于是我收拾行囊骑着车就出去了。但是因为感冒还没有好利落，不想跑太远，因此就没有去白龙潭。这次…

【歪门邪道】Unraid上的ZFS初体验
type: item
date: 2025-04-01T08:40:00+08:00
description: 原本打算组完NAS之后慢慢扩容，这正好也是Unraid的优势所在。可是计划永远赶不上变化，我朋友扩容了他的NAS，换下来了3块8TB和2块6TB的硬盘，我想着与其去网上买来路不明的二手硬盘，不如就把我朋友换下来的硬盘收了。于是乎掐指一算，我之前自己买的2块，加上收来的5块，正好7块，马上就要把我的8盘位吃满了。想来想去，不如折腾个ZFS吧！前言先前我在文章里提过没有选择TrueNAS是因为DDR5 ECC平台太贵了，而且没有小主板。后来我也仔细查阅了不少资料，最终得出的结论是ECC会让内存变得更安全，但是没有ECC并不意味着ZFS会变得脆弱。正相反，其实ZFS从设计上就是为了尽最大努力保证它读出来的数据要和你当初交给它时一致。顺带一提，我今天才知道ZFS也是Sun公司制作的。我越发觉得这个公司真的很酷，没有坚持到现在真的很遗憾。没错，不要怀疑自己，Java也是这个公司搞的。虽然Java本身的语法和其衍生品相比并不酷，但JVM很酷，它作为一个平台支持了其他更酷的东西，比如kotlin、scala这些语言。而ZFS最初于2001年开始研发，它的目的就是不相信任何存储设备，因此ZFS也包含了大量措施来检测数据完整性，如果ZFS没有100%的把握确定它交给你的数据是正确的，它就不会稀里糊涂的把数据给你，而是通过报错让你知道系统出问题了。太酷了！尽管Unraid的阵列在扩展性和易用性上都比ZFS好，可最大的问题就是它无法甄别出现问题时哪块盘或者哪个文件出问题了，这也是我自己编写文件校验工具的动机。虽然大部分情况下硬盘要坏都是有征兆的，比如频繁报错、smart自检失败、掉盘等，但有一种错误是静悄悄的：bit rot。折腾NAS的玩家应该对这个词并不陌生，它描述了一种存储介质的一种物理翻转，也就是说硬盘在没人动它的情况下，可能某一位就会自己从0翻转到1，或者反过来。原因嘛，可能是生产瑕疵，或者是宇宙射线恰好命中了你的硬盘，又或者过年的时候亲戚家的熊孩子拿着强力磁铁吸你的NAS机箱。总之这种物理的问题完全无法避免，而这种又不算硬盘故障，诸多自检都对此无能为力。当你访问到了包含bit rot的区块，硬盘控制器自己也不知道这里的数据出问题了，它只能忠实地将它从磁盘上读出来的数据写到总线上，进而由操作系统呈现给用户，直到用户发现他珍藏多年的家庭合影再也打不开了。对于Unraid来说，定期计算磁盘校验有助于发现这种错误，比如当bit rot发生时，unraid可能会注意到阵列读出来的数据计算出的校验位和校验盘中存储的不一致，这个时候用户有两种选择：查找问题，或者将新的校验位写入校验盘。即便有两块校验盘也无法确定到底是哪块盘的数据出问题了，甚至你都无法得知是哪个文件出问题了——这就是我自己写文件校验工具的目的，虽然校验和本身也存在硬盘上，也有遭受bit rot的风险，但密码学领域的哈希计算确保了任何一点微小的改动（哪怕只有1bit）也会导致计算出和原来完全不同的哈希。因此在很大概率上可以通过文件级别的哈希来发现错误，然后从备份中找到完好的文件然后恢复。是的，无论是Unraid、RAID还是ZFS都不能替代备份。尽管ZFS有更强大的数据完整性校验和自恢复功能，如果数据损坏超过一定程度，ZFS也无力回天，而且它还会拒绝给你不完整的数据，因此拥有一个备份是十分必要的。当然，很大概率并不意味着万无一失。如果恰好出现多个bit rot使得奇偶校验没变，而其中一些bit rot又出现在一个同一个文件，恰好导致了哈希冲突，那么恭喜你：这虽然不是什么露脸的事儿，但确实非常稀有，值得你向那些搞IT运维的人还有用NAS不做备份的人炫耀，坏事是会发生的。为了确保万无一失，我还是要考虑ZFS。ECC内存的问题解决了，下面就要考虑扩展和易用的问题了。易用性在Unraid支持了ZFS之后变得好了许多，你可以直接通过网页面板来扩容和管理ZFS存储池，配合插件ZFS Master for Unraid来管理ZFS的dataset和快照。扩容嘛，正好我是3块8TB，2块6TB，再去买一块6TB，刚好做两个3盘raidz1的vdev。什么？你问vdev是什么？简单地说，在ZFS里面，最顶层的结构是zpool，也就是一个存储池，但是和群辉以及lvm中存储池的概念不同，ZFS的zpool是由vdev组成的。所谓vdev就是virtual device，虚拟设备。这些虚拟设备是由多个硬盘在不同配置下组成的。比如说你可以用两块硬盘按照mirror模式组成vdev，这和传统的raid1差不多。你也可以用stripe模式组成类似raid0效果的vdev，或者用ZFS独家的raidz（1，2，3）来确保vdev在丢失1、2、3块硬盘的情况下还能够读出数据。当然，ZFS中vdev的种类也有所不同，比如数…