well404.WebPanel
1.6.0
dotnet add package well404.WebPanel --version 1.6.0
NuGet\Install-Package well404.WebPanel -Version 1.6.0
<PackageReference Include="well404.WebPanel" Version="1.6.0" />
<PackageVersion Include="well404.WebPanel" Version="1.6.0" />
<PackageReference Include="well404.WebPanel" />
paket add well404.WebPanel --version 1.6.0
#r "nuget: well404.WebPanel, 1.6.0"
#:package well404.WebPanel@1.6.0
#addin nuget:?package=well404.WebPanel&version=1.6.0
#tool nuget:?package=well404.WebPanel&version=1.6.0
well404.WebPanel
Unturned / OpenMod 通用 Web 管理面板 —— 一个 schema 驱动的单页面板,让各功能插件挂载自己的可视化管理模块。
well404.WebPanel 是 well404 OpenMod 插件家族 的基础设施插件。它内置一个轻量
HTTP 服务(基于 BCL HttpListener,无外部依赖)与单页应用,并对外暴露 IWebPanelRegistry;
well404.Economy、
well404.Shop 等插件在加载时把自己的管理
模块注册进来,面板即可通用地渲染出表单、设置组、集合 CRUD 与搜索框,而无需了解各插件实现。
功能
- 🌐 内置 HTTP 服务 + 单页管理界面,零外部依赖
- 🧩
IWebPanelRegistry:其他插件按统一 schema 注册管理模块(Settings / Collection / Search / Form / Table) - ↕️ Collection 支持分组标签、三列预览和可选拖拽排序;行操作弹窗字段会完整提交
- 🔐 路径式 token 鉴权(
/<token>/,管理面强制有 token;留空则自动生成并写回配置) - 🌐 内置反代/隧道(可选):一键经 cloudflared / ngrok 把面板安全暴露到公网,隐藏真实 IP、自动 HTTPS;要求管理员预装 cloudflared(自动下载因供应链校验要求而关闭)
- 🛠️ 安装即用:装了哪个家族插件,面板里就出现对应模块
- 🎮 面向玩家的网页界面(
/p):玩家游戏内/menu即可在浏览器里看服务器介绍页、逛商店买卖、查钱包转账、用实用工具(传送/组队/礼包/睡觉);各插件经IPlayerMenuRegistry注册「玩家菜单」 - ⚡ 玩家按钮 schema 支持快捷值选项、操作前确认、分组 header 动作和分组标签布局
- 🌍 管理面板 + 玩家面板均中英双语可切换(默认英文);网页文案经
IWebTranslationRegistry提供翻译,新增语言只需加一张映射表 - 🈶 通用渲染器支持物品双语主副标题:中文界面显示中文 + 换行灰色英文,英文界面只显示英文
安装
openmod install well404.WebPanel
安装或升级 DLL 后完整重启服务器,启动日志会打印管理面地址 http://<地址>:<端口>/<token>/。
openmod reload 只适合未替换二进制时的配置或生命周期重载。
配置 (config.yaml)
web:
bindAddress: "127.0.0.1" # 监听地址:127.0.0.1(仅本机)| 0.0.0.0(全部)| 指定 IP
port: 27020 # 监听端口
token: "" # 管理面密钥;留空=首次启动随机生成 12 位并写回本文件
tunnel: # 可选:内置反代,把面板安全暴露到公网
enabled: false
type: "cloudflare" # cloudflare(需预装 cloudflared) | custom(自定义,适配 ngrok 等)
command: "cloudflared"
autoDownload: false # 安全默认:不下载未验证的可执行文件,请预装并配置 command
downloadMirrors: [] # 兼容旧配置,当前忽略
downloadAttempts: 2 # 兼容旧配置,当前忽略
publicBaseUrl: "" # 玩家 /menu 链接的公网地址;空=自动推导(开 tunnel 时用隧道地址)
playerSessionMinutes: 5 # 玩家链接有效期下限;实际不少于 15 分钟
refreshIntervalSeconds: 5 # 管理面/玩家面刷新间隔;编辑或页面隐藏时暂停,0=关闭
devPlayer: # 开发预览:不进游戏也能以指定账号查看玩家面(默认关)
enabled: false
steamId: "" # 要模拟的玩家 Steam ID
displayName: "Dev Player"
开发者预览:
devPlayer.enabled: true后访问/<token>/dev-player,即以steamId账号 直接进入其玩家面板(/p),无需进游戏发/menu——便于在浏览器里调试玩家菜单。藏在管理面密钥 路径之后且默认关闭;属玩家身份模拟,生产环境请保持关闭。需玩家在线的动作(买卖/传送)仍提示「需要在线」。
Cloudflare 账号与永久域名
内置 type: "cloudflare" 是随机地址的 Quick Tunnel。长期服务器应在 Cloudflare Dashboard
创建 Named Tunnel,把固定域名(例如 panel.example.com)映射到
http://127.0.0.1:27020,并将该 route 的 HTTP Host Header 设置为
127.0.0.1:27020。然后让 cloudflared 作为 systemd / Windows 服务运行,WebPanel 配置为:
web:
bindAddress: "127.0.0.1"
port: 27020
token: "请替换为至少32位的随机字符串"
tunnel:
enabled: false
publicBaseUrl: "https://panel.example.com"
不要把 Tunnel Token 写进 WebPanel 配置,也不要同时启用内置 Quick Tunnel。管理员地址为
https://panel.example.com/<web.token>/,玩家执行 /menu 后会收到固定域名下的
/p?t=... 链接。Linux 服务安装命令通常是
sudo cloudflared service install <TUNNEL_TOKEN>;Windows 请以管理员身份运行 Cloudflare
控制台给出的 cloudflared.exe service install <TUNNEL_TOKEN>。
完整的逐步操作、Linux/Windows 验证、安全说明与 400/502//menu 无公网 URL 排障见
仓库 WebPanel 文档。
安全说明
- 路径式 token:管理面始终在
http://host:port/<token>/下,token 即鉴权;路径不对一律 404(不泄露面板是否存在)。 - token 强制存在:留空则自动生成 12 位大小写字母+数字并写回 config.yaml(重启不变);不在 WebUI 中可改,只能改配置文件。
- 内置反代(
web.tunnel):开启后经 cloudflared / ngrok 把面板反代到公网,不暴露真实 IP、不开入站端口、自动 HTTPS;隧道把整个端口反代出去,管理面就靠路径 token 保护,务必保密。 - 执行
openmod reload时会清除旧 quick-tunnel 地址并等待新地址;旧实例的迟到回调不会覆盖新状态。autoRestart: true也会重试 reload 后首次未取得公网 URL 的情况。 - 玩家面(
/p)用各玩家一次性短时令牌:有效期至少 15 分钟,之后只要在线就有效,下线即失效;与管理员 token 互相独立。
命令
| 命令 | 别名 | 说明 |
|---|---|---|
/menu [tab] |
/panel |
向玩家推送其专属面板链接(可选 tab 定位标签,如 /menu shop) |
HTTP 接口
管理面全部在 /<token>/ 前缀下(下表省略前缀);玩家面在 /p、/api/p/*。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /<token>/ |
管理单页应用(API 用相对路径,自动带 token 前缀) |
| GET | /<token>/api/modules |
列出已注册模块及其字段 schema |
| GET/POST | /<token>/api/modules/{module}/{action}[/values\|/records\|/delete\|/reorder] |
预填 / 记录 / 提交 / 删除 |
| GET | /<token>/api/modules/{module}/asset/{asset} |
管理模块自建 UI 的只读图片(管理 token 鉴权) |
| GET | /<token>/dev-player |
开发预览:签发 devPlayer 会话并跳转 /p(仅 devPlayer.enabled 时;否则 404) |
| GET | /p |
玩家单页应用(令牌从 ?t= 读取) |
| GET | /api/p/view |
玩家的全部菜单(玩家令牌鉴权) |
| POST | /api/p/invoke/{menu} |
以玩家身份执行卡片按钮(玩家令牌鉴权) |
| GET | /api/p/asset/{menu}/{asset} |
玩家菜单自建 UI 的只读图片(玩家令牌鉴权) |
给插件开发者
WebPanel 保留两套扩展方式:简单插件继续使用描述符注册制;复杂插件可随自身程序集打包 HTML/CSS/JavaScript,由 WebPanel 挂入隔离的 Shadow DOM。插件负责业务布局,宿主统一负责鉴权、 导航、语言、错误隔离和受限动作 API。管理面与玩家面默认每 5 秒安全刷新一次;页面隐藏、弹窗或 输入编辑时自动暂停。玩家动作期间旧 GET 会失效,多动作只应用最后发起者的视图并在结束后权威刷新,避免慢响应回滚库存。 配置项 refreshIntervalSeconds 设为 0 可关闭。
- 管理模块:可选注入
IWebPanelRegistry(来自共享库UnturnedMods.Shared),用WebPanelModule描述若干WebPanelAction并注册;面板自动渲染。 - 玩家菜单:可选注入
IPlayerMenuRegistry,实现IPlayerMenu(RenderAsync出卡片、InvokeAsync执行按钮)并注册;玩家在/p面板里以自己的身份操作。
两者注入皆为可选——未安装本面板时注册被跳过,你的插件照常工作。
自建玩家 UI 元数据:
PlayerCard.Metadata可携带非敏感字符串元数据。WebPanel 会按键稳定排序后 原样序列化为卡片的metadata对象,但不会解释字段;插件可用它实现本地排序、筛选、样式等, 同时继续复用宿主鉴权与动作调用。自建 UI 图片:管理模块可给
WebPanelModule.AssetProvider提供IWebPanelModuleAssetProvider,玩家菜单可实现IPlayerMenuAssetProvider。自建脚本只拿到panel.assetUrl(assetId),不能传服务器路径。宿主统一要求对应管理员/玩家身份,只允许 PNG/JPEG/WebP/GIF、最大 64 MiB,并添加private缓存、ETag 与nosniff。资源 id 应是固定白名单,不得当文件路径解释。
well404 OpenMod 插件家族
| 插件 | 说明 |
|---|---|
| well404.Economy | 货币经济核心,全局 IEconomyProvider 供币 |
| well404.Shop | 分组物品商店,买卖物品,依赖 Economy |
| well404.WebPanel | 通用 Web 管理面板,供各插件挂载可视化管理模块 |
| well404.Essentials | 面向玩家的实用指令:home/tp/warp/gift/sleep/back,经济收费可选 |
完整文档、配置示例与本地调试说明见 GitHub 仓库 的 docs/。
许可
CC BY-NC-SA 4.0 © well404
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Cronos (>= 0.8.4)
- OpenMod.Extensions.Economy.Abstractions (>= 3.8.10)
- OpenMod.Unturned (>= 3.8.10)
- System.Formats.Asn1 (>= 8.0.1)
- System.Text.Json (>= 8.0.6)
- well404.UnturnedMods.Shared (>= 1.4.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.6.0 | 99 | 7/21/2026 |
| 1.5.0 | 105 | 7/15/2026 |
| 1.3.0 | 97 | 7/13/2026 |
| 1.2.7 | 98 | 7/12/2026 |
| 1.2.6 | 112 | 7/12/2026 |
| 1.2.5 | 98 | 7/12/2026 |
| 1.2.4 | 791 | 6/16/2026 |
| 1.2.3 | 110 | 6/16/2026 |
| 1.2.2 | 109 | 6/16/2026 |
| 1.2.1 | 112 | 6/16/2026 |
| 1.2.0 | 105 | 6/15/2026 |
| 1.1.0 | 109 | 6/15/2026 |
| 1.0.0 | 109 | 6/15/2026 |
| 0.1.2 | 116 | 6/11/2026 |
| 0.1.1 | 114 | 6/11/2026 |
| 0.1.0 | 102 | 6/11/2026 |