● DNF 私服一站式工具箱

DPForge Next

DNF 私服插件管理 · 模块配置 · 一键生成部署 · GM 工具集。在浏览器里勾选功能、编辑参数、生成 df_game_r.js / Lua / config,并通过 SSH 一键部署到服务器。

100+可选功能插件
在线插件市场免更新
GM角色/账号/邮件/背包
1-ClickSSH 生成部署

核心能力

🧩

插件配置

按分类勾选功能、编辑参数、查看 Hook 地址;改动即入库,重新生成即写入 df_game_r.js。

🌙

Lua 脚本

Lua 道具处理与启动开关,配合 Work_Reload.lua 部署。

生成部署

一键生成 df_game_r.js / Lua / config,SSH 上传到服务器,目标目录自动创建。

🛡️

GM 管理

角色 / 账号 / 邮件 / 背包 / 道具搜索 / 在线玩家,直接读写游戏库。

🖥️

服务器管理

SSH 部署、PVF 上传校验、Web Shell、远程文件在线编辑。

⚙️

系统设置

改口令、初始化代码、frida 配置,兼容 MySQL 5.1–5.7 老库。

为什么要有在线插件市场?

🔄

免更新拿新插件

插件定义与注入代码托管在云端,DPForge 直接拉取最新版,不必重装程序。

🤝

社区共建

任何人都能通过 Pull Request 贡献插件,评审合并后即刻对所有人可用。

📦

标准化格式

每个插件 = 一个 JSON(元信息 + Hook + 设置项 + 注入代码),可直接导入工具。

常用操作

👤 角色列表✉️ 邮件发放📦 道具搜索 🔑 账号管理🟢 在线玩家🎒 背包编辑

插件市场

从云端加载最新插件,点卡片查看设置项与注入代码,一键复制 JSON 导入 DPForge。想贡献自己的插件?看 开发文档 › 贡献流程

提交插件

在线填写并提交,进入待审核队列;站长审核通过后即刻上架,所有 DPForge 用户可拉取。无需 Git、无需私有部署。提交前请阅读 开发文档安全红线

提交即表示你确认代码可公开分享、无恶意逻辑。插件会被服务端执行,含后门/外联上传/破坏性写入的会被拒绝。

插件是什么

DPForge 的每个「插件」对应 DNF 服务端进程里的一段 Frida 注入逻辑。工具会把所有已启用插件的代码拼进 df_game_r.js,随服务端加载执行,从而实现登入播报、副本玩法、装备道具、运营管控等功能。

一个插件在云端就是一个 JSON 文件:元信息 + Hook 地址 + 设置项 schema + 注入代码。DPForge 拉取后即可在「插件配置」页勾选、改参数、生成部署。

插件 JSON 结构

把下面的对象保存成 plugins/<id>.json,并在 plugins/index.json 里登记一行即可:

{
  "schema": 1,
  "id": "extra_monster_reward",     // 唯一 id(英文/下划线)
  "cat": "dungeon",                 // 分类 id(见 index.json.categories)
  "name": "副本随机稀有怪",          // 显示名
  "ico": "👹",                       // emoji 图标
  "version": "1.0.0",               // 语义化版本
  "author": "your-name",            // 贡献者
  "initFn": "hook_extra_monster",   // 入口函数名(会被调用)
  "desc": "进房间按概率追加稀有怪并掉落道具。",
  "tags": ["副本玩法"],
  "hooks": [                        // 仅作展示/说明,实际 attach 在 code 内
    { "addr": "0x1234ABCD", "mode": "attach", "dup": false }
  ],
  "settings": [ /* 见「插件设置配置」 */ ],
  "code": "function hook_extra_monster(){ /* Frida 代码 */ }",
  "updatedAt": "2026-07-17"
}
字段说明:id 全局唯一;cat 必须是 index.json 里存在的分类;initFn 必须与 code 中的入口函数同名——DPForge 生成时会调用它。

注入处理逻辑

注入代码就是标准的 Frida JavaScript。约定:把所有逻辑包在一个与 initFn 同名的函数里,在函数内部用 Interceptor.attach 挂目标地址。

最小示例(强制某函数返回 1)

// initFn: HookDsSwordman_SkillSlot
function HookDsSwordman_SkillSlot() {
  Interceptor.attach(ptr(0x08608C98), {   // SkillSlot::checkMoveComboSkillSlot
    onEnter: function (args) { /* args[0]=this, args[1..]=参数 */ },
    onLeave: function (retval) { retval.replace(1) } // 改返回值
  });
}

读取参数 / 调用游戏内函数

function hook_user_inout_game_world() {
  Interceptor.attach(ptr(0x86C4E50), {          // GameWorld::reach_game_world
    onEnter: function (args) { this.user = args[1]; },
    onLeave: function () {
      var name = api_CUserCharacInfo_getCurCharacName(this.user);
      sendWelcomeMessage(this.user, name);      // 复用框架已有的公共函数
    }
  });
}
Hook 地址(0x…)与服务端二进制版本强绑定,跨版本需重新定位。贡献插件时请注明适用的服务端版本,并尽量把地址、魔法数写成显式常量。

内存补丁(无 Hook)

// initFn: baitan14  —— 放开个人摆摊格子上限到 14
function baitan14() {
  Memory.protect(ptr(0xXXXXXXX), 4, 'rwx');
  ptr(0xXXXXXXX).writeU8(14);
}

插件设置配置

把可调参数写进 settings 数组,DPForge 会在「基本设置」里自动渲染成输入框 / 开关,并把用户填的值替换进代码中的 {{key}} 占位符。

"settings": [
  { "key": "boss_start_hour", "label": "开启时间(点)", "type": "number",
    "default": 21, "description": "每天几点整开启活动 (0-23)" },
  { "key": "phase2_dungeon_name", "label": "二阶段副本名", "type": "text",
    "default": "罗特斯宫殿", "description": "广播文案中显示的副本名称" },
  { "key": "phase1_unique_team", "label": "一阶段队伍去重", "type": "toggle",
    "default": false, "description": "同一队伍多次通关只计一次" }
]
字段说明
key参数名,同时是代码里的占位符 {{key}}
label界面显示名
typenumber / text / toggle
default默认值
description参数说明(显示在输入框旁)

在代码里使用占位符

var START_HOUR = {{boss_start_hour}};        // 数字直接替换
var DUNGEON    = "{{phase2_dungeon_name}}";  // 文本放进引号
if ({{phase1_unique_team}}) { /* toggle → true/false */ }
生成时 DPForge 用用户配置的值做字符串替换。文本类占位符记得自己加引号;开关类替换为 true/false

在 DPForge 中使用在线插件

DPForge 客户端从本站点拉取插件(约定接口,纯静态 JSON,支持跨域):

  • GET /plugins/index.json — 插件列表 + 分类
  • GET /plugins/<id>.json — 单个插件完整定义

拿到 JSON 后合并进本地 modules.json(新增/覆盖同 id 项)+ 把 code 落地到 data/codes/<id>.js.tmpl,即可在「插件配置」页看到并启用。你也可以在插件详情里直接「复制 JSON」,手动导入。

贡献插件(在线提交)

不需要 Git、不需要自己部署站点。直接在本站 提交插件 页填写并提交:

  1. 打开 提交插件,填 id / 分类 / 名称 / initFn / 说明 / 设置项 / 注入代码(可点「填入示例」参考)。
  2. 点「提交审核」,你的插件进入待审核队列。
  3. 站长在后台审核代码,通过后即刻上架到本站,所有 DPForge 用户可拉取。
  4. 想更新已上架的插件?用同一个 id 再提交一次,审核通过即覆盖为新版。
安全提示:插件是会被服务端执行的原生注入代码。请勿提交带后门、外联上传、破坏性内存写入的代码;审核会重点检查 Interceptor 目标、网络请求与内存写入,可疑代码一律拒绝。

部署到 Cloudflare(站长,免费)

本站用 Cloudflare Pages + Pages Functions + D1,投稿与审核都在你自己的站点内完成,全部免费额度即可。

  1. dpforge-site/ 推到 Git 仓库,Cloudflare → Workers & Pages → Create → Pages → 连接仓库(Framework=None,构建命令留空,输出目录 /)。
  2. 创建 D1:npx wrangler d1 create dpforge-plugins,把返回的 database_id 填进 wrangler.toml
  3. 建表并导入示例:wrangler d1 execute dpforge-plugins --file=schema.sql--file=seed.sql
  4. 在 Pages 项目 Settings → Functions → D1 bindings 绑定变量名 DB → 该数据库。
  5. Settings → Environment variables 加密变量 ADMIN_TOKEN(你的审核口令)。
  6. 审核后台:访问 https://<你的域名>/admin.html,输入 ADMIN_TOKEN 即可批准/拒绝投稿、下架插件。
对外接口:/plugins/index.json/plugins/<id>.json 由 Functions 从 D1 实时返回;_middleware.js 已配好 CORS,DPForge 客户端默认指向本站,无需用户单独配置。