diff --git a/SDK-GMLIB b/SDK-GMLIB index acfb919..710cc6e 160000 --- a/SDK-GMLIB +++ b/SDK-GMLIB @@ -1 +1 @@ -Subproject commit acfb919941799990ce2e880c47db70289bb34153 +Subproject commit 710cc6e4c3b0e85fd793fba807d8fffd6c4b607f diff --git a/manifest.json b/manifest.json index 74b7429..045d2b8 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "${pluginName}", "entry": "${pluginFile}", - "version": "0.12.0", + "version": "0.12.1", "author": "GroupMountain", "description": "Check Player's Inventory", "type": "native", diff --git a/src/Config.h b/src/Config.h index d70b8db..e931ece 100644 --- a/src/Config.h +++ b/src/Config.h @@ -1,6 +1,8 @@ #pragma once #include "Global.h" -std::string defaultConfig = R"({ - "language": "en_US" -})"; \ No newline at end of file +struct Config { + int version = 1; + + std::string language = "en_US"; +}; \ No newline at end of file diff --git a/src/Entry.cpp b/src/Entry.cpp index 8c83e93..423ecb9 100644 --- a/src/Entry.cpp +++ b/src/Entry.cpp @@ -1,29 +1,25 @@ #include "Entry.h" #include "Global.h" +#include "Language.h" ll::Logger logger(PLUGIN_NAME); namespace InventoryCheck { -namespace { - -std::unique_ptr> - selfPluginInstance; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) - -auto disable(ll::plugin::NativePlugin& /*self*/) -> bool { return true; } - -auto enable(ll::plugin::NativePlugin& /*self*/) -> bool { - RegisterCommand(); - listenEvent(); - logger.info("InventoryCheck Loaded!"); - logger.info("Author: GroupMountain"); - logger.info("Repository: https://github.com/GroupMountain/InventoryCheck"); - return true; +std::unique_ptr& Entry::getInstance() { + static std::unique_ptr instance; + return instance; } -auto load(ll::plugin::NativePlugin& self) -> bool { - selfPluginInstance = std::make_unique>(self); - initPlugin(); +bool Entry::load() { + mConfig.emplace(); + if (!ll::config::loadConfig(*mConfig, getSelf().getConfigDir() / u8"config.json")) { + ll::config::saveConfig(*mConfig, getSelf().getConfigDir() / u8"config.json"); + } + mI18n.emplace(getSelf().getLangDir(), mConfig->language); + mI18n->updateOrCreateLanguage("en_US", en_US); + mI18n->updateOrCreateLanguage("zh_CN", zh_CN); + mI18n->loadAllLanguages(); if (GMLIB::Version::getProtocolVersion() != TARGET_PROTOCOL) { logger.error(tr("error.protocolMismatch.info")); logger.error( @@ -32,35 +28,35 @@ auto load(ll::plugin::NativePlugin& self) -> bool { ); return false; } - initPlayerDataCache(); return true; } -auto unload(ll::plugin::NativePlugin& self) -> bool { - selfPluginInstance.reset(); +bool Entry::enable() { + RegisterCommand(); + logger.info("InventoryCheck Loaded!"); + logger.info("Author: GroupMountain"); + logger.info("Repository: https://github.com/GroupMountain/InventoryCheck"); return true; } -} // namespace - -auto getSelfPluginInstance() -> ll::plugin::NativePlugin& { - if (!selfPluginInstance) { - throw std::runtime_error("selfPluginInstance is null"); - } - return *selfPluginInstance; +bool Entry::disable() { + // Code for disabling the plugin goes here. + return true; } +bool Entry::unload() { + getInstance().reset(); + return true; +} + +Config& Entry::getConfig() { return mConfig.value(); } + +LangI18n& Entry::getI18n() { return mI18n.value(); } + } // namespace InventoryCheck -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); -} -} +LL_REGISTER_PLUGIN(InventoryCheck::Entry, InventoryCheck::Entry::getInstance()); + +std::string tr(std::string const& key, std::vector const& data) { + return InventoryCheck::Entry::getInstance()->getI18n().get(key, data); +} \ No newline at end of file diff --git a/src/Entry.h b/src/Entry.h index c435c55..cc54ba7 100644 --- a/src/Entry.h +++ b/src/Entry.h @@ -1,9 +1,40 @@ #pragma once - -#include +#include "Config.h" +#include "Global.h" namespace InventoryCheck { -[[nodiscard]] auto getSelfPluginInstance() -> ll::plugin::NativePlugin&; +using namespace GMLIB::Files::I18n; + +class Entry { + +public: + static std::unique_ptr& getInstance(); + + Entry(ll::plugin::NativePlugin& self) : mSelf(self) {} + + [[nodiscard]] ll::plugin::NativePlugin& getSelf() const { return mSelf; } + + /// @return True if the plugin is loaded successfully. + bool load(); + + /// @return True if the plugin is enabled successfully. + bool enable(); + + /// @return True if the plugin is disabled successfully. + bool disable(); + + /// @return True if the plugin is unloaded successfully. + bool unload(); + + Config& getConfig(); + + LangI18n& getI18n(); + +private: + ll::plugin::NativePlugin& mSelf; + std::optional mConfig; + std::optional mI18n; +}; } // namespace InventoryCheck diff --git a/src/Global.h b/src/Global.h index 5f6f3ca..cf5f131 100644 --- a/src/Global.h +++ b/src/Global.h @@ -6,24 +6,18 @@ extern ll::Logger logger; -extern std::string tr(std::string key, std::vector data = {}); +extern std::string tr(std::string const& key, std::vector const& data = {}); -extern void initPlugin(); extern void RegisterCommand(); 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 resultList); -extern void searchNotFoundForm(Player& pl, std::string& name); -extern void checkPlayerForm(Player& pl, mce::UUID uuid); +extern void searchResultForm(Player& pl, std::unordered_map const& resultList); +extern void searchNotFoundForm(Player& pl, std::string const& name); +extern void checkPlayerForm(Player& pl, mce::UUID const& uuid); extern void invalidInputForm(Player& pl); -extern void confirmWriteForm(Player& pl, mce::UUID uuid, std::string name); -extern void confirmDeleteForm(Player& pl, mce::UUID uuid, std::string name); -extern void deleteFailedForm(Player& pl, mce::UUID uuid, std::string name); - -extern void listenEvent(); -extern void initPlayerDataCache(); - -extern std::optional getNameFromUuid(std::string uuid); \ No newline at end of file +extern void confirmWriteForm(Player& pl, mce::UUID const& uuid, std::string const& name); +extern void confirmDeleteForm(Player& pl, mce::UUID const& uuid, std::string const& name); +extern void deleteFailedForm(Player& pl, mce::UUID const& uuid, std::string const& name); \ No newline at end of file diff --git a/src/Initialization.cpp b/src/Initialization.cpp deleted file mode 100644 index 7bc9349..0000000 --- a/src/Initialization.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "Config.h" -#include "Global.h" -#include "Language.h" - -GMLIB::Files::JsonConfig* Config = nullptr; -GMLIB::Files::I18n::LangI18n* Language = nullptr; -nlohmann::json mPlayerDataCache; - -std::optional readFile(std::string path) { - if (std::filesystem::exists(path)) { - return GMLIB::Files::JsonFile::readFromFile(path); - } - return {}; -} - -void initPlayerDataCache() { - mPlayerDataCache = nlohmann::json::object(); - auto data = readFile("./plugins/InventoryCheck/data/PlayerDataCache.json"); - if (data.has_value()) { - try { - mPlayerDataCache = data.value(); - } catch (...) {} - } -} - -void saveCacheData() { - std::string path = "./plugins/InventoryCheck/data/PlayerDataCache.json"; - GMLIB::Files::JsonFile::writeFile(path, mPlayerDataCache); -} - -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({"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); - if (!std::filesystem::exists("./plugins/InventoryCheck/data/")) { - std::filesystem::create_directories("./plugins/InventoryCheck/data/"); - } - if (!std::filesystem::exists("./plugins/InventoryCheck/save/")) { - std::filesystem::create_directories("./plugins/InventoryCheck/save/"); - } -} - -std::string tr(std::string key, std::vector data) { return Language->translate(key, data); } - -void listenEvent() { - auto& eventBus = ll::event::EventBus::getInstance(); - eventBus.emplaceListener([](ll::event::player::PlayerConnectEvent& ev) { - auto& pl = ev.self(); - mPlayerDataCache[pl.getUuid().asString()] = pl.getRealName(); - saveCacheData(); - }); -} - -std::optional getNameFromUuid(std::string uuid) { - if (mPlayerDataCache.contains(uuid)) { - return mPlayerDataCache[uuid].get(); - } - return {}; -} \ No newline at end of file diff --git a/src/InventoryCheck.cpp b/src/InventoryCheck.cpp index b0b0dc4..0aa55e5 100644 --- a/src/InventoryCheck.cpp +++ b/src/InventoryCheck.cpp @@ -1,18 +1,13 @@ #include "Global.h" bool saveInventory(Player& player) { - auto& pl = static_cast(player); - auto uuid = pl.getUuid(); - std::string path = "./plugins/InventoryCheck/save/" + uuid.asString() + ".dat"; - if (!std::filesystem::exists(path)) { - auto nbt = pl.getNbt()->toBinaryNbt(); - std::ofstream newFile(path, std::ios::out | std::ios::binary); - if (newFile.is_open()) { - newFile.write(nbt.c_str(), nbt.size()); - newFile.close(); - return true; - } - } + auto& pl = static_cast(player); + auto uuid = pl.getUuid(); + ll::file_utils::writeFile( + "./plugins/InventoryCheck/save/" + uuid.asString() + ".dat", + pl.getNbt()->toBinaryNbt(), + true + ); return false; } @@ -20,22 +15,11 @@ bool resumeInventory(Player& player) { auto& pl = static_cast(player); auto uuid = pl.getUuid(); std::string path = "./plugins/InventoryCheck/save/" + uuid.asString() + ".dat"; - if (std::filesystem::exists(path)) { - std::ifstream dataFile(path, std::ios::binary); - if (dataFile.is_open()) { - dataFile.seekg(0, std::ios::end); - std::streampos fileSize = dataFile.tellg(); - dataFile.seekg(0, std::ios::beg); - std::vector buffer(fileSize); - dataFile.read(buffer.data(), fileSize); - std::string_view binaryData(buffer.data(), fileSize); - dataFile.close(); - std::filesystem::remove(path); - auto nbt = CompoundTag::fromBinaryNbt(binaryData); - if (nbt) { - GMLIB_Player::setPlayerNbtTags(uuid, *nbt, {"Offhand", "Inventory", "Armor", "EnderChestInventory"}); - return true; - } + if (auto binaryData = ll::file_utils::readFile(path, true)) { + std::filesystem::remove(path); + if (auto nbt = CompoundTag::fromBinaryNbt(binaryData.value())) { + GMLIB_Player::setPlayerNbtTags(uuid, *nbt, {"Offhand", "Inventory", "Armor", "EnderChestInventory"}); + return true; } } return false; @@ -81,19 +65,14 @@ void checkOnlineForm(Player& pl) { }); } -std::string getNameFormUuid(mce::UUID& uuid) { +std::string getNameFormUuid(mce::UUID const& uuid) { auto player = GMLIB_Level::getLevel()->getPlayer(uuid); std::string name; if (player) { name = player->getRealName(); } else { - auto strUuid = uuid.asString(); - auto cachename = getNameFromUuid(strUuid); - if (cachename.has_value()) { - name = cachename.value(); - } else { - name = strUuid; - } + auto cache = GMLIB::UserCache::getNameByUuid(uuid); + name = cache ? cache.value() : uuid.asString(); } return name; } @@ -170,7 +149,7 @@ void searchPlayerForm(Player& pl) { }); } -void searchResultForm(Player& pl, std::unordered_map resultList) { +void searchResultForm(Player& pl, std::unordered_map const& 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); }); @@ -182,7 +161,7 @@ void searchResultForm(Player& pl, std::unordered_map res }); } -void searchNotFoundForm(Player& pl, std::string& name) { +void searchNotFoundForm(Player& pl, std::string const& name) { auto fm = ll::form::ModalForm( tr("form.notFound.title"), tr("form.notFound.content", {name}), @@ -197,7 +176,7 @@ void searchNotFoundForm(Player& pl, std::string& name) { }); } -void checkPlayerForm(Player& pl, mce::UUID uuid) { +void checkPlayerForm(Player& pl, mce::UUID const& 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, name](Player& pl) { @@ -238,7 +217,7 @@ void invalidInputForm(Player& pl) { }); } -void confirmWriteForm(Player& pl, mce::UUID uuid, std::string name) { +void confirmWriteForm(Player& pl, mce::UUID const& uuid, std::string const& name) { auto fm = ll::form::ModalForm( tr("form.confirmWrite.title"), tr("form.confirmWrite.content", {name}), @@ -260,7 +239,7 @@ void confirmWriteForm(Player& pl, mce::UUID uuid, std::string name) { }); } -void confirmDeleteForm(Player& pl, mce::UUID uuid, std::string name) { +void confirmDeleteForm(Player& pl, mce::UUID const& uuid, std::string const& name) { auto fm = ll::form::ModalForm( tr("form.confirmDelete.title"), tr("form.confirmDelete.content", {name}), @@ -280,7 +259,7 @@ void confirmDeleteForm(Player& pl, mce::UUID uuid, std::string name) { }); } -void deleteFailedForm(Player& pl, mce::UUID uuid, std::string name) { +void deleteFailedForm(Player& pl, mce::UUID const& uuid, std::string const& name) { auto fm = ll::form::ModalForm( tr("form.deleteFailed.title"), tr("form.deleteFailed.content", {name}), diff --git a/src/Language.h b/src/Language.h index 7cd381e..4534996 100644 --- a/src/Language.h +++ b/src/Language.h @@ -1,7 +1,7 @@ #pragma once -#include "Global.h" +#include -std::string defaultLanguage_en_US = R"( +std::string en_US = R"( form.main.title=Check Player Inventory form.main.content=Please select a query mode. form.main.checkOnline=Query online players @@ -53,7 +53,7 @@ std::string defaultLanguage_en_US = R"( error.protocolMismatch.version=Support protocol %1$s, current protocol %2$s. )"; -std::string defaultLanguage_zh_CN = R"( +std::string zh_CN = R"( form.main.title=查询玩家背包 form.main.content=请选择查询模式 form.main.checkOnline=查询在线玩家 diff --git a/tooth.json b/tooth.json index ce839db..2f5145b 100644 --- a/tooth.json +++ b/tooth.json @@ -1,7 +1,7 @@ { "format_version": 2, "tooth": "github.com/GroupMountain/InventoryCheck", - "version": "0.12.0", + "version": "0.12.1", "info": { "name": "InventoryCheck", "description": "Check Player's Inventory", @@ -14,9 +14,9 @@ "gmlib" ] }, - "asset_url": "https://github.com/GroupMountain/InventoryCheck/releases/download/v0.12.0/InventoryCheck-windows-x64.zip", + "asset_url": "https://github.com/GroupMountain/InventoryCheck/releases/download/v0.12.1/InventoryCheck-windows-x64.zip", "dependencies": { - "github.com/GroupMountain/GMLIB": ">=0.12.1" + "github.com/GroupMountain/GMLIB": ">=0.12.6" }, "files": { "place": [