GitHub 上的开源项目 d2r-mobile,能把你自己手里的 Switch 版《暗黑破坏神 II:狱火重生》连同「术士君临」资料片,装到 iPhone 和 iPad 上离线玩。项目是 MIT 协议开源,仓库里不含任何游戏内容——游戏程序、美术、文本、数据表,全部要你自己用自己机器上的文件生成。
网上已经有人在流传「打包好的 IPA + 5.4GB 游戏数据」,那是侵权分发,我不会在本文提供任何这类资源。下面写的是正规路线:自己买游戏、自己提取、自己构建。
这点很重要,也是它跑得这么快的原因。
iPhone 和 Switch 用的是同一类 ARM 处理器,能执行同一套机器指令。所以这个项目没走模拟器的路子——游戏的原程序直接在手机芯片上执行,只改写了极少数在苹果系统下无法原样运行的指令(涉及线程寄存器、系统调用和定时器),其余部分逐字节保持原样。
图形部分在苹果的 Metal 接口上重新实现,着色器(负责渲染的小程序)提前从游戏原版离线翻译好,进游戏时不需要现场编译。
直观的区别:模拟器要在游戏和硬件之间加一层实时翻译,这里没有这一层。所以职业、符文之语、掉落规则、任务流程,全部和 Switch 原版一致——因为它跑的就是原版程序。
| 设备 | 能不能玩 | 说明 |
|---|---|---|
| iPhone 15 Pro 及以后 / M 系列 iPad | 能 | 主力设备,A17 Pro 起步体验最好 |
| iPhone 14 全系、iPhone 15 / 15 Plus | 能,需额外一步 | 需要自己制作纹理包(见下文第四步) |
| iPhone 13 系列 | 勉强 | A15 芯片,30fps 模式下可玩 |
| 4GB 内存设备(如 iPad Air 4) | 不行 | 启动几秒后会因内存不足被系统杀掉 |
| iPhone 11 系列、2020 款 iPad Pro | 不行 | 图形芯片不支持 Metal 3,App 会直接提示 |
硬性门槛:芯片最低 A14 / M1(图形层需要 Metal 3),内存至少 6GB。
实测性能(iPhone 17 Pro Max):稳定 60fps,主菜单进游戏约 1 秒,整机功耗约 3.8W——满电大约能连玩 5 小时。开省电模式降到 30fps,功耗约 1.85W,续航翻倍。
游戏
Apple 账号
电脑:看下面两条路线
需要安装 Xcode。全程三步:
第一步,把游戏文件放到位
在 Mac 上建立工作目录(默认 ~/dm-work),把从自己游戏里提取的文件按这个结构放好:
~/dm-work/data/switch/3.3.94012/Update/ExeFS/ main、sdk、subsdk0
~/dm-work/data/switch/3.3.94012/Update/RomFS/ data/…如果你手上是完整的 .xci / .nsp 包,先装 hactool,然后直接让脚本帮你提取:
./setup.sh <游戏包路径> <prod.keys路径>第二步,准备工作区
./setup.sh
source ~/dm-work/build/cache/dm/venv/bin/activatesetup.sh 会检查工具、重写游戏程序、把着色器翻译成 Metal 格式。第一次跑比较慢,之后会跳过已完成的步骤。
跑完不确定有没有问题的话,可以先用 ./setup.sh check 做个健康检查——它会逐项报告电脑、工具、游戏文件和签名配置的状态,只读不改。
第三步,填签名信息并构建
cp dm/ios/local.env.example dm/ios/local.env在 dm/ios/local.env 里填 DM_TEAM_ID 和 DM_BUNDLE_ID。如果用的是免费 Apple ID,还要加两行:
DM_FREE_ACCOUNT=1
DM_IOS_UDID=你的设备UDID构建时保持手机连着电脑。然后:
cd dm/ios && ./run.sh build默认同时构建 iPhone 和 iPad 版本。只要 iPhone 的话:DM_DEVICE_FAMILY=1 ./run.sh build。
顺带一提:同样跑完 setup.sh 之后,还能一条命令构建出 Mac 上直接双击运行的原生 App,不需要开发者账号:
dm/tools/mac_app.shWindows 或 Linux 都能走这条路,不需要 Xcode。
D2RMobile-shell-build-input.zip;iOS 18~25 用 D2RMobile-shell-ios18-build-input.zip)。这个 shell 不含任何游戏内容注意两点:shell 是构建用的输入文件,不是能直接装的 App;这条路线的包因为没有 Apple 的着色器编译器,首次启动要在手机上花约 7 分钟编译着色器(带进度条,一次性)。走路线 A 的包没有这一步。
项目文档 docs/GAME_FILES.md 专门写了要哪些文件、怎么从你自己的主机取、放在哪里。
用 hactool 之类的工具从自己的 Switch 提取,工具只检查主程序版本,不区分 .xci 还是 .nsp 封装格式。
这一步对普通玩家确实有门槛,需要你自己的 Switch 已经做过相应准备。具体操作请以项目文档为准——我只能告诉你需要 ExeFS 下的 main、sdk、subsdk0 和 RomFS/data/ 这些内容。
A16 及更早的设备(iPhone 14 系列、iPhone 15 / 15 Plus):游戏原版的压缩纹理格式不被支持,需要用你自己的游戏文件额外制作一个纹理包(Legacy Device Pack,见 docs/LEGACY_DEVICES.md),做好后一样能满帧运行。
App 第一次打开会要求你选择「game resource folder」——就是从你游戏文件里整理出来的 18 个资源归档,需要单独放到手机上。
之后:
安装包本身只有 100MB 出头,游戏资源约 5.6GB 单独存放——更新 App 不会影响你的存档和资源。
这不是把手柄布局硬贴到屏幕上。作者的原则是:保留原版界面语言,用手势代替往屏幕上堆按钮。
| 坑 | 说明 |
|---|---|
| 游戏版本 | 必须是 1.0.34.0 且含术士君临资料片,少了资料片不支持 |
| 免费 Apple ID | 每 7 天要重新签名安装,且没有 iCloud 存档同步 |
| 旧芯片 | A16 及更早必须做 Legacy Device Pack,否则纹理有问题 |
| 内存不足 | 4GB 内存设备跑不起来,别在这上面浪费时间 |
| 着色器编译 | 无 Mac 路线首次启动要等 6~7 分钟,别以为是卡死了 |
| App 更新 | 换新版本要重新构建安装包,但存档和资源不用动 |
| 侵权资源 | 网上的「打包版 IPA + 游戏数据」是侵权分发,且有安全风险 |
第一,门槛比想象中高。 项目文档写得很清楚,但「从自己 Switch 提取游戏文件」这一步就会劝退大部分人。加上要 Mac + Xcode(或走无 Mac 打包 + 侧载),这不是一个「下载装上就能玩」的东西。
第二,它确实快。 因为不是模拟器,60fps 稳定、功耗只有 3.8W,这两点是模拟器方案比不了的。作者还做了完整的指令等价性校验和回归测试,工程质量在线。
第三,法律边界要清楚。 项目与暴雪、任天堂没有任何关联,也不被它们认可,只能配合你自己拥有的正版游戏使用。游戏完全离线运行,没有联机,也不需要登录任何账号。
说白了:适合手上有正版、电脑环境齐全、又想在手机上躺着刷牛场的人。如果你只是想找个免费的暗黑2手机版,这条路大概率不适合你。
项目地址:github.com/jhaizhou-ops/d2r-mobile(MIT 协议)
刷机过程不算难,但坑不少——尤其是短接这一步,很多人卡在这里反复失败。这篇把完整流程和我踩过的坑都记下来。
先搞清楚你要刷的是什么:
| 项目 | 规格 |
|---|---|
| SoC | 瑞芯微 RK3566,四核 A55,最高 1.8GHz |
| 内存 | 4GB LPDDR4X(OEC 普通版是 2GB) |
| 板载存储 | 8GB eMMC |
| 硬盘 | SATA 3.0 × 1,支持 2.5 寸硬盘 |
| 网络 | 千兆网口 × 1 |
| 其他接口 | USB 3.0 × 1、USB 2.0 Type-C × 1 |
| 电源 | 12V / 2A |
| 功耗 | 待机 1~2W,满载约 4W |
优势很明确:RK3566 带 SATA,功耗个位数,一年电费不到二十块。缺点也很明确——8GB eMMC 太小了。
这不是点几下鼠标的事,先把风险摆在前面:
1. 固件带硬件锁,别乱刷
OEC/OECT 的飞牛固件是针对这台机器的,严禁刷入其他任何设备,刷错必变砖,而且没有救砖办法。反过来也一样,别把别的机型的固件往 OECT 里怼。
2. 8GB eMMC 会很紧张
飞牛官方对 ARM 设备的建议是 eMMC 不低于 16GB,32GB 以上最优。OECT 只有 8GB,系统能装下、能跑,但应用别指望装太多,存储主力还是要靠那块 2.5 寸硬盘。
3. 硬件版本不止一个
OECT 存在多个硬件版本,不同版本进入 MASKROM 模式的短接方法不一样。网上教程的触点位置可能对不上你的板子,多找几份同型号的图片对比。
另外,刷完 PCDN 收益就没了,硬盘会被格式化,有数据先备份。
硬件
软件
Rockchip_DriverAssitant_v5.1.1RKDevTool(v2.84 或 v3.x 版本都有人用,个别版本有兼容性差异,刷不动就换个版本)rk356x_spl_loader_ddr1056_v1.10.111.bin(一般在 RKDevTool 目录的 Firmware 下,选 rk3568 那一项)rk3566-null 系列,例如 fnos_Mainland-PE_arm_1.1.19_rk3566-null_544固件去哪找
飞牛 ARM 版的官方下载页是 https://fnnas.com/download-arm。需要说明的是,官网的设备支持列表会随版本变动,OEC/OECT 的固件在 2026 年上半年的公测版本里是独立的一个包,之后列表调整过。如果你打开官网没找到 OEC/OECT,有两条路:
ophub/fnnas 项目,它的支持列表里有 WXY-OEC-turbo-4g,刷完可以走 OTA下载到的固件如果是 rar/zip/gz,一定要先解压出 .img 文件,工具不认压缩包。
原厂系统、从没刷过的机器,必须拆机短接才能进 MaskROM。
在主板上找到两个触点,位置在 SATA 接口旁边,一般标记为 GND 和 1V8,等下就要把这两个点短接在一起。
顺带说一句 Type-C 口:网心云官方说明书里写「硬盘槽旁边的 Type-C 口为生产调试使用,不具备实际功能性」,但刷机恰恰就要用这个口,别被这句话劝退。
第一步,装驱动
进 DriverAssitant 目录,运行 DriverInstall.exe,默认安装即可。
第二步,连设备
打开 RKDevTool.exe,底部会显示「没有发现设备」。
全程不需要接电源线——设备靠 USB 供电就够了。用数据线连接设备的 Type-C 口,另一头插电脑。
第三步,进 MaskROM(最容易翻车的一步)
用镊子短接主板那两个触点,同时把 USB 插到电脑上。设备灯会亮,等 3~4 秒就可以松开短接了。
软件底部显示「发现一个 MASKROM 设备」,就说明成功了。
如果一直不识别,别急,这步多试几次很正常。几个提高成功率的办法:
第四步,加载文件开刷
MiniLoaderAll.bin).img 固件0xCCCCCCCC 对应 Bootloader,0x00000000 对应固件镜像进度条走完大概要 7 分钟左右,工具提示「下载完成」就刷好了。
另一种进 Loader 模式的方法:不想拆机的话,可以试通电前用卡针顶住机身的 Reset 小孔,再插刷机线,进入 Loader 模式。这时候去掉勾选 Bootloader 那一项,直接执行刷入 Image 固件即可。不过这个办法对原厂固件版本有要求,升级过系统的机器可能失效。
先别急着装回去。
debian 的新设备——这就是刷好飞牛的机器,记下它的 IP后面就是设置账号、挂载硬盘、开 SMB 共享、装飞牛影视这些常规操作了,跟 x86 版基本一致。
把散在各处的坑集中一下,刷之前建议过一遍:
| 坑 | 说明 |
|---|---|
| 短接时机 | 短接和插 USB 要同步,失败就多试几次,这是最高频的卡点 |
| USB 口选择 | 优先 USB 2.0,3.0 口失败率明显更高 |
| 红灯常亮 | 刷完指示灯常亮红灯是正常现象,不是刷失败了,别慌 |
| 固件格式 | 必须解压成 .img,压缩包工具不认 |
| 硬件版本 | OECT 有多个硬件版本,短接点可能不同,多对比图片 |
| 固件锁 | OEC 固件有硬件锁,刷别的设备必砖,反之亦然 |
| eMMC 空间 | 只有 8GB,装应用悠着点,主力存储交给 SATA 硬盘 |
| 工具版本 | RKDevTool 各版本兼容性有差异,卡住了就换个版本试 |
还有个进阶玩法:恩山论坛有大佬做了 OEC/OECT 多系统切换工具,支持系统升级、克隆、改 LED 灯、改 MAC 地址,想折腾多系统的可以去搜一下。
如果你手上已经有一台吃灰的 OECT,那答案是很值——零成本多一台低功耗 NAS,跑跑下载、影音、文件备份绰绰有余。
但如果还没入手,就得算笔账了:这机器因为能刷 NAS 已经涨过一波价,同样的钱现在能买到不少正经的 ARM 小主机,eMMC 还更大。为了刷飞牛专门去买 OECT,性价比已经不如从前了。
刷机有风险,动手前确认自己能接受最坏结果。祝各位一次点亮。
]]>真动手才发现,这条路比想象中绕。前后踩了三个坑,记录一下,省得你重走。
最直觉的做法是命令行模拟表单提交。Typecho 的登录表单长这样:
<form action="https://example.com/index.php/action/login?_=xxxx" method="post">
<input type="text" name="name" />
<input type="password" name="password" />
<input type="hidden" name="referer" value="https://example.com/admin/" />
</form>于是:
curl -c cookie.txt -L "https://example.com/admin/" -o login.html
TOKEN=$(grep -oE 'login\?_=[a-zA-Z0-9]+' login.html | head -1 | cut -d= -f2)
curl -b cookie.txt -c cookie.txt -L \
--data-urlencode "name=你的账号" \
--data-urlencode "password=你的密码" \
--data-urlencode "referer=https://example.com/admin/" \
"https://example.com/index.php/action/login?_=$TOKEN"诡异的是,返回 302 且 Location 指向后台——看着像成功了。但一访问后台,还是登录页。
关键判断点在这里:
curl ... -D - -o /dev/null "..." | grep -i "set-cookie"如果响应头里没有 Set-Cookie,那就是没登录成功,不管 Location 跳去哪。Typecho 登录成功一定下发 __typecho_authCode。
为什么失败?看完整响应头就能发现线索:
EO-Cache-Status: MISS
EO-LOG-UUID: 17057971157060924413站点在腾讯云 EdgeOne 这类 CDN 后面,非浏览器请求在会话层就被处理掉了,压根到不了 PHP。结论:curl 这条路对这类站点不通,别浪费时间调参数。
既然要真实浏览器,那就装自动化工具。agent-browser 这类 CLI 有个 install 子命令负责拉 Chromium,约 198MB。
实际结果:
40/198 MB (20%)
Retrying download (attempt 2/3)
Retrying download (attempt 3/3)
✗ Download error: operation timed out国内网络拉 Google 的 chrome-for-testing 源,超时是常态。不要在这步死等。
绕过下载的办法:你机器上大概率已经有 Chrome 或 Edge,直接拿来用。
npm install playwright-coreplaywright-core 不含浏览器,只有驱动,几 MB,秒装。然后指向本机 Chrome:
const browser = await chromium.launch({
executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
headless: true
});结果访问后台直接 30 秒超时。改成 headless: false 立刻正常——同样的 cookie、同样的 URL。CDN 对无头浏览器同样有识别。
const { chromium } = require('playwright-core');
(async () => {
const browser = await chromium.launch({
executablePath: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
headless: false,
args: ['--disable-blink-features=AutomationControlled']
});
const ctx = await browser.newContext({
viewport: { width: 1280, height: 860 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
});
const page = await ctx.newPage();
await page.goto('https://example.com/admin/', { waitUntil: 'domcontentloaded' });
await page.fill('#name', '你的账号');
await page.fill('#password', '你的密码');
await page.check('#remember'); // 勾选记住登录,cookie 有效期更长
await page.click('button[type="submit"]');
await page.waitForTimeout(5000);
console.log(await page.title()); // 输出「网站概要」即为成功
await ctx.storageState({ path: 'state.json' }); // 保存登录态
await browser.close();
})();跑完看到标题变成「网站概要 - ...」,就算进去了。
storageState 这一步很值钱:登录态存成 state.json 后,后续所有脚本都这样复用,不用再输一次密码:
const ctx = await browser.newContext({ storageState: 'state.json' });不同主题的写作页字段差异不小(特别是加了自定义字段的主题)。先探测再填,别猜:
document.querySelectorAll('input[name], select[name], textarea[name]').forEach(el => {
console.log(el.tagName, el.name, el.type, el.id);
});Typecho 原生字段一般是这些:
title 标题、text 正文(Markdown)、slug 别名category[] 分类(checkbox,值是分类 ID)tags 标签、date 日期visibility 可见性、allowComment 允许评论带自定义字段的主题还会有 fields[excerpt](摘要)、fields[imgst](封面图)、fields[catalog](目录开关)这类,按需填。
填完点「发布文章」提交:
await page.fill('#title', '文章标题');
await page.evaluate(t => { document.querySelector('#text').value = t; }, 正文内容);
await page.check('#category-1'); // 勾选分类,注意是 ID 不是名字
await page.fill('#tags', '标签1,标签2');
await page.click('button:has-text("发布文章")');
await page.waitForTimeout(5000);摘要里那句「注意是 ID 不是名字」是血泪:分类复选框的 id 是 category-1 这种,对应的是分类 ID,得先遍历一遍把 ID 和名称对应上:
document.querySelectorAll('input[name="category[]"]').forEach(el => {
const lab = document.querySelector(`label[for="${el.id}"]`);
console.log(el.value, lab ? lab.textContent.trim() : '?');
});折腾完回看,这几条比技术细节更重要:
state.json 就够了,后续全靠它state.json 等同于账号权限,别提交到公开仓库,也别随手发给别人example.com 之类替代三个坑其实指向同一件事:现代站点前面挡着 CDN,自动化得按真实浏览器的路子走。curl 走不通,无头浏览器走不通,用本机浏览器 + 有头模式反而最省事。
真正跑通之后,体验是值得的:内容整理、排版、配图、发布一气呵成,人只做最后的判断。这条路走顺了,后面就是批量化的事了。
]]>apt update
apt upgrade openssl
]]>
bash <(curl -Ls https://raw.githubusercontent.com/vaxilu/x-ui/master/install.sh)首先从 https://github.com/vaxilu/x-ui/releases 下载最新的压缩包,一般选择 amd64架构然后将这个压缩包上传到服务器的 /root/目录下,并使用 root用户登录服务器,如果你的服务器 cpu 架构不是 amd64,自行将命令中的 amd64替换为其他架构。
cd /root/
rm x-ui/ /usr/local/x-ui/ /usr/bin/x-ui -rf
tar zxvf x-ui-linux-amd64.tar.gz
chmod +x x-ui/x-ui x-ui/bin/xray-linux-* x-ui/x-ui.sh
cp x-ui/x-ui.sh /usr/bin/x-ui
cp -f x-ui/x-ui.service /etc/systemd/system/
mv x-ui/ /usr/local/
systemctl daemon-reload
systemctl enable x-ui
systemctl restart x-uicurl -fsSL https://get.docker.com | shmkdir x-ui && cd x-ui
docker run -itd --network=host \
-v $PWD/db/:/etc/x-ui/ \
-v $PWD/cert/:/root/cert/ \
--name x-ui --restart=unless-stopped \
enwaiax/x-ui:latestdocker build -t x-ui .从国内大厂买的vps,建议自己弄上域名和SSL证书伪装一下!
]]>
点击下载
以上软件均来自网络🌍

宝塔安装教程就不细说了,官方安装地址: 点击跳转 ,开心版地址: 仅用于学习 ,宝塔装好之后直接一键安装那几个环境就行。
PHP版本我这里用的是7.2(在禁用函数中去掉putenv),数据库5.7。
然后打开宝塔创建网站,数据库也一块创建了。创建好以后申请ssl后面好开启https。
然后打开宝塔左侧有个终端,打开它,或者你自己的ssh远程工具也行,输入以下代码,下载源码到网站目录,xx.com换成你自己刚才创建的网站文件夹名字。
cd /www/wwwroot/xx.com下载官方源码
git clone https://github.com/cydrobolt/polr.git
mv polr/{.,}* ./由于官方是英文的,需要汉化一下
cd resources && rm -rf views && wget https://www.j8mao.com/usr/down/porl_views.tar.gz
tar zxvf porl_views.tar.gz
cd ..使用Composer安装
执行完以后,将.env.setup创建一个名为.env的副本
cp .env.setup .env在宝塔面板上直接点击网站-设置-网站目录,选择/public文件夹,然后在伪静态那里填入以下代码:
location / {
try_files $uri $uri/ /index.php$is_args$args;
}然后进入网站目录,找到.evn点进去改成你的数据库名称,账户,密码,其他不用动,然后保存
保存好之后,改一下网站目录权限为777/www
然后打开网站看看是不是到安装界面了
里面的数据库名,数据库账户,密码,网站域名都改成你自己的。
其他的根据需要自己设置就行了,STMP就是发件的邮箱,开启注册,不用邮箱验证(后期需要用),然后安装
现在可以正常进入网站,但是如果你开始设置的是只有登录用户可以使用短链的话,此时是无法正常使用短链的。同时,你使用设置的用户进行登录时,会提示登陆错误。原因是数据库里现在没有用户信息。此时你就只需注册一个用户,使用注册用户进行登录,就可以正常使用短链功能了。
但是现在仍然有一个缺陷,你注册的用户并不具备管理员权限,只是一个普通用户,没有办法管理其他注册用户的短链。要将自己注册的用户升级为管理员,只需要进入数据库,在users中将你刚注册的用户的role赋值为admin然后点击右下角执行即可。然后回到网站,退出后重新登录,你就会发现你的账户已经是管理员了。

如果是使用Cloudflare,不要开启CDN(小云朵),会造成重定向次数太多,无法正常访问。如果非要开启CDN,使用Cloudflare,请在vender/autoload.php的第6行加入:
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
}设置时区可在.env文件的最后加入(时区自行根据需要设置即可):
APP_TIMEZONE=Asia/Shanghai好了 教程到此结束,快去试试吧