feat: add forms
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
#include "Forms.h"
|
||||
#include "Global.h"
|
||||
|
||||
void RegisterCommand() {
|
||||
auto& cmd = ll::command::CommandRegistrar::getInstance().getOrCreateCommand(
|
||||
"inventorycheck",
|
||||
tr("command.inventorycheck.desc"),
|
||||
CommandPermissionLevel::GameDirectors
|
||||
);
|
||||
ll::service::getCommandRegistry()->registerAlias("inventorycheck", "ic");
|
||||
cmd.overload().execute<[&](CommandOrigin const& origin, CommandOutput& output) {
|
||||
auto entity = (GMLIB_Actor*)origin.getEntity();
|
||||
if (entity && entity->isPlayer()) {
|
||||
auto pl = (Player*)entity;
|
||||
return mainForm(*pl);
|
||||
}
|
||||
return output.error(tr("command.error.console"));
|
||||
}>();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
|
||||
std::string defaultConfig = R"({
|
||||
"language": "en_US"
|
||||
})";
|
||||
+12
-41
@@ -1,13 +1,6 @@
|
||||
#include "Entry.h"
|
||||
#include "Global.h"
|
||||
#include <fmt/format.h>
|
||||
#include <functional>
|
||||
#include <ll/api/Config.h>
|
||||
#include <ll/api/io/FileUtils.h>
|
||||
#include <ll/api/plugin/NativePlugin.h>
|
||||
#include <ll/api/plugin/PluginManagerRegistry.h>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
ll::Logger logger(PLUGIN_NAME);
|
||||
|
||||
namespace InventoryCheck {
|
||||
@@ -17,47 +10,22 @@ namespace {
|
||||
std::unique_ptr<std::reference_wrapper<ll::plugin::NativePlugin>>
|
||||
selfPluginInstance; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
auto disable(ll::plugin::NativePlugin& /*self*/) -> bool {
|
||||
logger.info("disabling...");
|
||||
|
||||
// Your code here.
|
||||
|
||||
logger.info("disabled");
|
||||
|
||||
return true;
|
||||
}
|
||||
auto disable(ll::plugin::NativePlugin& /*self*/) -> bool { return true; }
|
||||
|
||||
auto enable(ll::plugin::NativePlugin& /*self*/) -> bool {
|
||||
logger.info("enabling...");
|
||||
|
||||
logger.info("enabled");
|
||||
|
||||
RegisterCommand();
|
||||
return true;
|
||||
}
|
||||
|
||||
auto load(ll::plugin::NativePlugin& self) -> bool {
|
||||
logger.info("loading...");
|
||||
|
||||
selfPluginInstance = std::make_unique<std::reference_wrapper<ll::plugin::NativePlugin>>(self);
|
||||
|
||||
// Your code here.
|
||||
|
||||
logger.info("loaded");
|
||||
|
||||
GMLIB::Server::UserCache::enableUserCache();
|
||||
initPlugin();
|
||||
return true;
|
||||
}
|
||||
|
||||
auto unload(ll::plugin::NativePlugin& self) -> bool {
|
||||
auto& logger = self.getLogger();
|
||||
|
||||
logger.info("unloading...");
|
||||
|
||||
selfPluginInstance.reset();
|
||||
|
||||
// Your code here.
|
||||
|
||||
logger.info("unloaded");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -67,7 +35,6 @@ auto getSelfPluginInstance() -> ll::plugin::NativePlugin& {
|
||||
if (!selfPluginInstance) {
|
||||
throw std::runtime_error("selfPluginInstance is null");
|
||||
}
|
||||
|
||||
return *selfPluginInstance;
|
||||
}
|
||||
|
||||
@@ -77,7 +44,11 @@ extern "C" {
|
||||
_declspec(dllexport) auto ll_plugin_disable(ll::plugin::NativePlugin& self) -> bool {
|
||||
return InventoryCheck::disable(self);
|
||||
}
|
||||
_declspec(dllexport) auto ll_plugin_enable(ll::plugin::NativePlugin& self) -> bool { return InventoryCheck::enable(self); }
|
||||
_declspec(dllexport) auto ll_plugin_load(ll::plugin::NativePlugin& self) -> bool { return InventoryCheck::load(self); }
|
||||
_declspec(dllexport) auto ll_plugin_unload(ll::plugin::NativePlugin& self) -> bool { return InventoryCheck::unload(self); }
|
||||
_declspec(dllexport) auto ll_plugin_enable(ll::plugin::NativePlugin& self) -> bool {
|
||||
return InventoryCheck::enable(self);
|
||||
}
|
||||
_declspec(dllexport) auto ll_plugin_load(ll::plugin::NativePlugin& self) -> bool { return InventoryCheck::load(self); }
|
||||
_declspec(dllexport) auto ll_plugin_unload(ll::plugin::NativePlugin& self) -> bool {
|
||||
return InventoryCheck::unload(self);
|
||||
}
|
||||
}
|
||||
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
#include "Forms.h"
|
||||
|
||||
void mainForm(Player& pl) {
|
||||
auto fm = ll::form::SimpleForm(tr("form.main.title"), tr("form.main.content"));
|
||||
fm.appendButton(tr("form.main.checkOnline"), [](Player& pl) { return checkOnlineForm(pl); });
|
||||
fm.appendButton(tr("form.main.checkAll"), [](Player& pl) { return checkAllForm(pl); });
|
||||
fm.appendButton(tr("form.main.searchPlayer"), [](Player& pl) { return searchPlayerForm(pl); });
|
||||
fm.appendButton(tr("form.main.resumeInventory"), [](Player& pl) { return; });
|
||||
fm.sendTo(pl);
|
||||
}
|
||||
|
||||
void checkOnlineForm(Player& pl) {
|
||||
auto fm = ll::form::SimpleForm(tr("form.checkList.title"), tr("form.checkList.content"));
|
||||
std::unordered_map<mce::UUID, std::string> onlineList;
|
||||
GMLIB_Level::getLevel()->forEachPlayer([&onlineList](Player& pl) -> bool {
|
||||
if (!pl.isSimulated()) {
|
||||
onlineList[pl.getUuid()] = pl.getRealName();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
for (auto& [uuid, name] : onlineList) {
|
||||
fm.appendButton(name, [uuid](Player& pl) { return checkPlayerForm(pl, uuid); });
|
||||
}
|
||||
fm.sendTo(pl, [](Player& pl, int index) {
|
||||
if (index == -1) {
|
||||
return mainForm(pl);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
std::string getNameFormUuid(mce::UUID& uuid) {
|
||||
auto player = GMLIB_Level::getLevel()->getPlayer(uuid);
|
||||
std::string name;
|
||||
if (player) {
|
||||
name = player->getRealName();
|
||||
} else {
|
||||
auto strUuid = uuid.asString();
|
||||
auto cachename = GMLIB::Server::UserCache::getNameByUuid(strUuid);
|
||||
if (cachename.has_value()) {
|
||||
name = cachename.value();
|
||||
} else {
|
||||
name = strUuid;
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
std::unordered_map<mce::UUID, std::string> generateUuidMap() {
|
||||
auto allUuids = GMLIB_Player::getAllUuids();
|
||||
std::unordered_map<mce::UUID, std::string> allList;
|
||||
for (auto& strUuid : allUuids) {
|
||||
auto uuid = mce::UUID::fromString(strUuid);
|
||||
auto name = getNameFormUuid(uuid);
|
||||
allList[uuid] = name;
|
||||
}
|
||||
return std::move(allList);
|
||||
}
|
||||
|
||||
void checkAllForm(Player& pl) {
|
||||
auto fm = ll::form::SimpleForm(tr("form.checkList.title"), tr("form.checkList.content"));
|
||||
auto allList = generateUuidMap();
|
||||
for (auto& [uuid, name] : allList) {
|
||||
fm.appendButton(name, [uuid](Player& pl) { return checkPlayerForm(pl, uuid); });
|
||||
}
|
||||
fm.sendTo(pl, [](Player& pl, int index) {
|
||||
if (index == -1) {
|
||||
return mainForm(pl);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void searchPlayerForm(Player& pl) {
|
||||
auto fm = ll::form::CustomForm(tr("form.searchPlayer.title"));
|
||||
fm.appendLabel(tr("form.searchPlayer.description"));
|
||||
fm.appendInput("name", tr("form.searchPlayer.input"), tr("form.searchPlayer.inputName"));
|
||||
fm.appendDropdown(
|
||||
"mode",
|
||||
tr("form.searchForm.searchMode"),
|
||||
{tr("form.searchPlayer.fuzzySearch"), tr("form.searchPlayer.preciseSearch")},
|
||||
0
|
||||
);
|
||||
fm.sendTo(pl, [](Player& pl, const ll::form::CustomFormResult& result) {
|
||||
if (result.empty()) {
|
||||
return mainForm(pl);
|
||||
}
|
||||
std::string inputName;
|
||||
if (std::holds_alternative<std::string>(result.at("name"))) {
|
||||
inputName = std::get<std::string>(result.at("name"));
|
||||
}
|
||||
auto searchMode = std::get<std::string>(result.at("mode"));
|
||||
if (inputName.empty()) {
|
||||
return invalidInputForm(pl);
|
||||
}
|
||||
auto allList = generateUuidMap();
|
||||
if (searchMode == tr("form.searchPlayer.preciseSearch")) {
|
||||
for (auto& [uuid, name] : allList) {
|
||||
if (name == inputName) {
|
||||
return checkPlayerForm(pl, uuid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::unordered_map<mce::UUID, std::string> resultList;
|
||||
for (auto& [uuid, name] : allList) {
|
||||
if (name.find(inputName) != std::string::npos) {
|
||||
resultList[uuid] = name;
|
||||
}
|
||||
}
|
||||
if (!resultList.empty()) {
|
||||
return searchResultForm(pl, resultList);
|
||||
}
|
||||
}
|
||||
return searchNotFoundForm(pl, inputName);
|
||||
});
|
||||
}
|
||||
|
||||
void searchResultForm(Player& pl, std::unordered_map<mce::UUID, std::string> resultList) {
|
||||
auto fm = ll::form::SimpleForm(tr("form.checkList.title"), tr("form.checkList.content"));
|
||||
for (auto& [uuid, name] : resultList) {
|
||||
fm.appendButton(name, [&uuid](Player& pl) { checkPlayerForm(pl, uuid); });
|
||||
}
|
||||
fm.sendTo(pl, [](Player& pl, int index) {
|
||||
if (index == -1) {
|
||||
return searchPlayerForm(pl);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void searchNotFoundForm(Player& pl, std::string& name) {
|
||||
auto fm = ll::form::ModalForm(
|
||||
tr("form.notFound.title"),
|
||||
tr("form.notFound.content", {name}),
|
||||
tr("form.notFound.returnSearch"),
|
||||
tr("form.returnMainForm")
|
||||
);
|
||||
fm.sendTo(pl, [](Player& pl, ll::form::ModalForm::SelectedButton result) {
|
||||
if (result == ll::form::ModalForm::SelectedButton::Upper) {
|
||||
return searchPlayerForm(pl);
|
||||
}
|
||||
return mainForm(pl);
|
||||
});
|
||||
}
|
||||
|
||||
void checkPlayerForm(Player& pl, mce::UUID uuid) {
|
||||
std::string name = getNameFormUuid(uuid);
|
||||
auto fm = ll::form::SimpleForm(tr("form.checkPlayer.title"), tr("form.checkPlayer.content", {name}));
|
||||
fm.appendButton(tr("form.checkPlayer.copyInventory"), [uuid](Player& pl) {
|
||||
auto nbt = GMLIB_Player::getPlayerNbt(uuid);
|
||||
auto self = (GMLIB_Player*)(&pl);
|
||||
self->setPlayerNbtTags(pl.getUuid(), *nbt, {"Offhand", "Inventory", "Armor", "EnderChestInventory"});
|
||||
});
|
||||
fm.appendButton(tr("form.checkPlayer.writeInventory"), [uuid](Player& pl) {
|
||||
//
|
||||
});
|
||||
fm.appendButton(tr("form.checkPlayer.deleteData"), [uuid](Player& pl) {
|
||||
//
|
||||
});
|
||||
fm.sendTo(pl, [](Player& pl, int index) {
|
||||
if (index == -1) {
|
||||
return mainForm(pl);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void invalidInputForm(Player& pl) {
|
||||
auto fm = ll::form::ModalForm(
|
||||
tr("form.invalidInput.title"),
|
||||
tr("form.invalidInput.content"),
|
||||
tr("form.invalidInput.returnSearch"),
|
||||
tr("form.returnMainForm")
|
||||
);
|
||||
fm.sendTo(pl, [](Player& pl, ll::form::ModalForm::SelectedButton result) {
|
||||
if (result == ll::form::ModalForm::SelectedButton::Upper) {
|
||||
return searchPlayerForm(pl);
|
||||
}
|
||||
return mainForm(pl);
|
||||
});
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
#include "Global.h"
|
||||
|
||||
extern void mainForm(Player& pl) ;
|
||||
extern void checkOnlineForm(Player& pl);
|
||||
extern void checkAllForm(Player& pl) ;
|
||||
extern void searchPlayerForm(Player& pl);
|
||||
extern void searchResultForm(Player& pl, std::unordered_map<mce::UUID, std::string> resultList);
|
||||
extern void searchNotFoundForm(Player& pl, std::string& name) ;
|
||||
extern void checkPlayerForm(Player& pl, mce::UUID uuid);
|
||||
extern void invalidInputForm(Player& pl);
|
||||
+6
-1
@@ -3,4 +3,9 @@
|
||||
|
||||
#define PLUGIN_NAME "InventoryCheck"
|
||||
|
||||
extern ll::Logger logger;
|
||||
extern ll::Logger logger;
|
||||
|
||||
extern std::string tr(std::string key, std::vector<std::string> data = {});
|
||||
|
||||
extern void initPlugin();
|
||||
extern void RegisterCommand();
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "Config.h"
|
||||
#include "Global.h"
|
||||
#include "Language.h"
|
||||
|
||||
GMLIB::Files::JsonConfig* Config = nullptr;
|
||||
GMLIB::Files::I18n::LangI18n* Language = nullptr;
|
||||
|
||||
void initPlugin() {
|
||||
Config = new GMLIB::Files::JsonConfig("./plugins/InventoryCheck/config/config.json", defaultConfig);
|
||||
Config->init();
|
||||
std::string langPath = "./plugins/InventoryCheck/language/";
|
||||
std::string languageCode = Config->getValue<std::string>({"language"}, "en_US");
|
||||
Language = new GMLIB::Files::I18n::LangI18n(langPath, languageCode);
|
||||
Language->updateOrCreateLanguage("en_US", defaultLanguage_en_US);
|
||||
Language->updateOrCreateLanguage("zh_CN", defaultLanguage_zh_CN);
|
||||
Language->loadAllLanguages();
|
||||
Language->chooseLanguage(languageCode);
|
||||
}
|
||||
|
||||
std::string tr(std::string key, std::vector<std::string> data) { return Language->translate(key, data); }
|
||||
@@ -0,0 +1 @@
|
||||
#include "Global.h"
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include "Global.h"
|
||||
|
||||
std::string defaultLanguage_en_US = R"(
|
||||
|
||||
)";
|
||||
|
||||
std::string defaultLanguage_zh_CN = R"(
|
||||
form.main.title=查询玩家背包
|
||||
form.main.content=请选择查询模式
|
||||
form.main.checkOnline=查询在线玩家
|
||||
form.main.checkAll=查询全部玩家
|
||||
form.main.searchPlayer=搜索玩家
|
||||
form.main.resumeInventory=恢复查包前背包
|
||||
form.checkList.title=玩家列表
|
||||
form.checkList.content=请选择你要查询的玩家
|
||||
form.searchPlayer.title=搜索玩家
|
||||
form.searchPlayer.description=请输入玩家名进行搜索
|
||||
form.searchPlayer.input=玩家名
|
||||
form.searchPlayer.inputName=请输入玩家名称信息
|
||||
form.searchForm.searchMode=搜索模式
|
||||
form.searchPlayer.fuzzySearch=模糊搜索
|
||||
form.searchPlayer.preciseSearch=精确搜索
|
||||
form.notFound.title=未找到匹配结果
|
||||
form.notFound.content=没有找到和 %s 匹配的玩家数据
|
||||
form.notFound.returnSearch=返回搜索菜单
|
||||
form.returnMainForm=返回主菜单
|
||||
form.checkPlayer.title=查询玩家背包
|
||||
form.checkPlayer.content=你正在查询玩家 %s 的背包\n请选择操作模式
|
||||
form.checkPlayer.copyInventory=将玩家背包复制到自身背包
|
||||
form.checkPlayer.writeInventory=用自身背包覆盖玩家背包
|
||||
form.checkPlayer.deleteData=删除玩家全部数据(不仅仅是背包)
|
||||
form.invalidInput.title=非法的输入
|
||||
form.invalidInput.content=输入的玩家名不能为空!
|
||||
form.invalidInput.returnSearch=重新搜索
|
||||
command.error.console=该命令只能由玩家执行
|
||||
command.inventorycheck.desc=查询玩家背包
|
||||
)";
|
||||
Reference in New Issue
Block a user