Mod Menu API
作用
Mod Menu API 用於註冊原生模組擁有的運行期 UI:菜單模塊、配置項、浮動按鈕 和 HUD 覆蓋層繪製命令。
通常在 enable() 中註冊;如果這些 UI 只應該在啟用狀態存在,請在 disable()
中清理。
頭文件
#include <pl/ModMenu.hpp>模塊註冊
可以使用 pl::modmenu::ModuleBuilder,也可以直接填充
pl::modmenu::ModuleInfo。
#include <pl/Mod.hpp>
#include <pl/ModMenu.hpp>
namespace {
constexpr const char *ModuleId = "example.speed_meter";
void onToggle(std::string_view moduleId, bool enabled) {
(void)moduleId;
(void)enabled;
}
} // namespace
bool MyMod::enable() {
return pl::modmenu::ModuleBuilder(ModuleId, "Speed Meter")
.modId(getSelf().getId())
.description("Shows a small movement speed overlay.")
.defaultEnabled(true)
.onToggle(onToggle)
.config("refreshRate", "Refresh Rate",
pl::modmenu::ConfigType::SliderInt, "20", "1", "60")
.registerModule();
}配置項類型:
| 類型 | 用途 |
|---|---|
ConfigType::Toggle | 布爾開關。 |
ConfigType::SliderInt | 整數滑塊。 |
ConfigType::SliderFloat | 浮點數滑塊。 |
ConfigType::Radio | 多選一字符串值。 |
ConfigType::Color | 顏色值。 |
浮動按鈕
使用 pl::modmenu::ButtonBuilder 註冊屏幕浮動按鈕。按鈕可以把 click、hold、
toggle 和指針事件派發到 C++ callback。
bool registerQuickButton() {
return pl::modmenu::ButtonBuilder("example.quick_drop", "Quick Drop")
.modId(getSelf().getId())
.moduleId(ModuleId)
.label("Drop")
.androidKeyCode(0)
.behavior(pl::modmenu::ButtonBehavior::Click)
.onEvent([](std::string_view buttonId,
pl::modmenu::ButtonEvent event, float value) {
(void)buttonId;
(void)event;
(void)value;
})
.registerButton();
}按鈕圖標可以通過 ButtonBuilder::pngIcon()、webpIcon()、svgIcon() 或通用
icon() helper 傳入 PNG、WebP 或 SVG 數據。
覆蓋層繪製
使用 pl::modmenu::submitDrawCommands() 替換某個模塊當前的 HUD 覆蓋層繪製
命令。文本命令可以使用 registerFont() 註冊的字體;圖片命令使用
registerImage() 註冊的原始 RGBA 像素。
| API | 用途 |
|---|---|
registerFont(fontId, ttfData) | 為文本命令註冊 TrueType 字體。 |
registerImage(imageId, imageData, width, height) | 為圖片命令註冊原始 RGBA 圖片像素。 |
submitDrawCommands(moduleId, commands) | 替換模塊當前的覆蓋層繪製命令列表。 |
registerImage() 要求 imageData.size() 必須等於 width * height * 4。
對 DrawCommandType::Text,請把 DrawCommand::fontId 設置為已註冊的 font id。
對 DrawCommandType::Image,請把 DrawCommand::imageId 設置為已註冊的 image id。
std::vector<unsigned char> logoRgba = loadLogoPixels();
const int logoWidth = 64;
const int logoHeight = 64;
bool MyMod::enable() {
if (!pl::modmenu::registerImage("example.logo", logoRgba,
logoWidth, logoHeight)) {
return false;
}
return pl::modmenu::ModuleBuilder(ModuleId, "Speed Meter")
.modId(getSelf().getId())
.defaultEnabled(true)
.registerModule();
}
void submitOverlay() {
const std::vector<pl::modmenu::DrawCommand> commands = {
{
.type = pl::modmenu::DrawCommandType::Image,
.x = 12.0f,
.y = 12.0f,
.w = 32.0f,
.h = 32.0f,
.imageId = "example.logo",
},
};
pl::modmenu::submitDrawCommands(ModuleId, commands);
}清理
如果註冊的 UI 是臨時的,或只應該綁定到啟用狀態,請在 disable() 中調用
pl::modmenu::unregisterModule() 和 unregisterButton()。從原生模組生命週期
中註冊的模塊和按鈕也會關聯 modId 歸屬。