Panel
查看 MarkdownXBase 自带的通用网页面板,模组只描述界面并挂钩子,不写前端
include/XBase/Panel.h · XBase::Panel
XBase 自带一个 React 面板,模组把界面结构挂进去、绑上读写回调就能用。多个模组聚合到同一个面板的侧栏上,谁都不用写前端。
适合想给模组加设置界面、又不想维护一套前端工程的场景:描述控件、绑回调、完事。
不属于本模块的内容:
Mountlabel 直接给显示文本,词条由模组自己决定WebView 与 WebBridgewrite 回调自己判断面板状态归共享运行时 XBase{ver}.dll。Bootstrap::Attach() 对每个模组都会先加载共享库,所以 Panel:: 的调用全部转发到那里,各模组看到的是同一份注册表。共享库没就位时退回模块内的本地副本,功能还在但不再聚合。
#include <XBase/Panel.h>
XBase::Panel::ModSpec spec;
spec.modId = "MyMod"; // 与 XBasePayloadBaseName 保持一致
spec.title = "我的模组";
spec.version = "v0.1.0";
XBase::Panel::Page page;
page.id = "main";
page.label = "主页面";
XBase::Panel::Section section;
section.id = "general";
section.label = "通用";
XBase::Panel::Control godMode;
godMode.kind = XBase::Panel::ControlKind::Toggle;
godMode.id = "mymod.godMode";
godMode.label = "无敌";
section.controls.push_back(godMode);
page.sections.push_back(section);
spec.pages.push_back(page);
// 先挂载结构再绑钩子,绑定到的控件必须已经在注册表里
XBase::Panel::Mount(spec);
XBase::Panel::BindValue(
"mymod.godMode",
[] { return gGodMode ? 1.0 : 0.0; },
[](double value) { gGodMode = value != 0.0; });
XBase::Panel::SetHotkey(XBase::Input::Hotkey{XBase::Input::Key::F7, 0});顺序反了会返回假并写一条 Panel: 控件未登记就绑定 的警告。
所有读写都用 double:
| 控件 | 读 | 写 |
|---|---|---|
Toggle | 0 或 1 | 0 或 1 |
Float / Int | 数值 | 数值 |
Select | options 下标 | options 下标 |
Action | 不读不写,走 BindAction | — |
这么定是因为 C 接口上不必传任何 STL 容器。XBase 用 /MT 静态运行库,跨模块传 std::string 与 std::function 会因 CRT 堆不匹配崩溃,函数表里只放函数指针加 void*。
| 字段 | 作用 |
|---|---|
Control::id | 全局唯一,约定按 模组名.分区.项 起名 |
Control::kind | Toggle / Float / Int / Action / Select |
Control::label hint | 显示文本,多语言由模组自己决定 |
Control::bounded min max step | 有边界才渲染成拖动条,否则渲染成输入框 |
Control::format | 数值显示格式,形如 %.1f |
Control::capability | 填 FeatureCapability,不支持时控件置灰而不是消失 |
Control::games | 限定版本,sa / vc / iii,留空表示三个版本都显示 |
Control::visibleWhen | 依赖同分区另一个控件,前置 ! 取反 |
Control::options | 仅下拉使用,读写的是下标 |
Section::columns inlineLayout | 多列排布;内联分区按固定宽度换行,适合一排动作按钮 |
Section::capability | 整块置灰,与控件级门控可以叠加 |
分区与控件的版本筛选、能力门控都在下发 schema 时算好,网页端拿到的已经是 enabled 布尔与筛过的列表。
| 调用 | 作用 |
|---|---|
Mount(ModSpec) | 提交整棵树,同 modId 重复挂载会整体替换并清空绑定 |
Unmount(modId) | 摘掉整个模组的界面与绑定 |
BindValue(id, read, write) | 绑读写,回调在游戏线程触发 |
BindAction(id, run) | 绑按钮动作 |
NotifyChanged(id, value) | 模组自己在游戏里改了状态,推事件让界面跟上 |
IsAvailable() | 网页视图运行时与面板资源都在才算可用 |
Show(modId) / Hide() / Toggle() / IsVisible() | 面板开合,modId 留空表示回到上次打开的模组 |
SetHotkey(hotkey) / GetHotkey() | 开关热键,默认 F8 |
回调在游戏线程触发。存档这类不能从界面线程直触发的动作,要自己挂起到游戏线程再执行。
面板在共享运行时里注册下面这些方法,模组一般不用直接调:
| 方法 | 参数 | 返回 |
|---|---|---|
panel.schema | — | 全部挂载内容、游戏版本、上次打开的模组 |
panel.get | { id } | { ok, value } |
panel.set | { id, value } | { ok } |
panel.run | { id } | { ok } |
panel.hide | — | { ok } |
panel.setSize / panel.setPos | { width, height } / { x, y } | { ok } |
panel.rect | — | { x, y, width, height } |
原生往网页推事件 panel.changed,载荷 { id, value }。
XBase/panel/ 是面板源码,React 19 + Vite + TypeScript + Tailwind 4,不引组件库。产物由 XBase/Build.bat Release stage 到 XBase\Library\panel\。
cd panel
npm install
npm run build产物是 file 协议与虚拟主机都能加载的经典脚本:Vite 插件剥掉 type="module" 与 crossorigin,输出 iife,资源路径全部相对。
Panel::IsAvailable() 返回假 —— 检查 XBase\Library\panel\index.html 是否存在,以及机器上有无 WebView2 运行时。Mount,或模组挂在自己的静态库副本上(共享库没加载成功)。BindValue,panel.get 取不到值。capability 填的能力在本版本上是 Unsupported,换能力名或去掉门控。type="module" 没剥掉。日志在 XBase\Mods\<模组名>\debug.log,也可以用 XBase 自带的查看器打开。
评论