From 0749023acb607da7596210236d35825a6430aa25 Mon Sep 17 00:00:00 2001 From: wed150 Date: Sat, 13 Jun 2026 23:56:04 +0800 Subject: [PATCH] feat:adapt to levilamina 26.10 Signed-off-by: wed150 --- src/Command.cpp | 18 ++--- src/Entry.cpp | 29 +++----- src/Entry.h | 11 ++- src/InventoryCheck.cpp | 163 ++++++++++++++++++++++++++++++++++------- 4 files changed, 164 insertions(+), 57 deletions(-) diff --git a/src/Command.cpp b/src/Command.cpp index ffcefbf..979a90e 100644 --- a/src/Command.cpp +++ b/src/Command.cpp @@ -9,18 +9,18 @@ #include "gmlib/mc/world/actor/Actor.h" void RegisterCommand() { - auto& cmd = ll::command::CommandRegistrar::getInstance().getOrCreateCommand( + auto& cmd = ll::command::CommandRegistrar::getInstance(false).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")); - }>(); + cmd.overload().execute([](CommandOrigin const& origin, CommandOutput& output) { + auto entity = (gmlib::GMActor*)origin.getEntity(); + if (entity && entity->isPlayer()) { + auto pl = (Player*)entity; + return mainForm(*pl); + } + return output.error(tr("command.error.console")); +}); } \ No newline at end of file diff --git a/src/Entry.cpp b/src/Entry.cpp index 8951307..7c2564d 100644 --- a/src/Entry.cpp +++ b/src/Entry.cpp @@ -13,12 +13,10 @@ #include "ll/api/service/Bedrock.h" #include "ll/api/service/PlayerInfo.h" -ll::Logger logger(MOD_NAME); - namespace InventoryCheck { -std::unique_ptr& Entry::getInstance() { - static std::unique_ptr instance; +Entry& Entry::getInstance() { + static Entry instance; return instance; } @@ -31,21 +29,19 @@ bool Entry::load() { 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( - tr("error.protocolMismatch.version", - {std::to_string(TARGET_PROTOCOL), std::to_string(GMLIB::Version::getProtocolVersion())}) - ); + + if (ll::getNetworkProtocolVersion() != TARGET_PROTOCOL) { + getSelf().getLogger().error(tr("error.protocolMismatch.info")); + getSelf().getLogger().error(tr("error.protocolMismatch.version", {std::to_string(ll::getNetworkProtocolVersion()), std::to_string(TARGET_PROTOCOL)})); } return true; } +; bool Entry::enable() { RegisterCommand(); - logger.info("InventoryCheck Loaded!"); - logger.info("Author: GroupMountain"); - logger.info("Repository: https://github.com/GroupMountain/InventoryCheck"); + + return true; } @@ -54,10 +50,7 @@ bool Entry::disable() { return true; } -bool Entry::unload() { - getInstance().reset(); - return true; -} + Config& Entry::getConfig() { return mConfig.value(); } @@ -68,5 +61,5 @@ LangI18n& Entry::getI18n() { return mI18n.value(); } LL_REGISTER_MOD(InventoryCheck::Entry, InventoryCheck::Entry::getInstance()); std::string tr(std::string const& key, std::vector const& data) { - return InventoryCheck::Entry::getInstance()->getI18n().get(key, 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 af7486b..254c901 100644 --- a/src/Entry.h +++ b/src/Entry.h @@ -5,18 +5,19 @@ #include "Global.h" #include "gmlib/gm/i18n/LangI18n.h" +#include "gmlib/gm/data/UserCache.h" #include namespace InventoryCheck { -using namespace GMLIB::Files::I18n; +using namespace gmlib::i18n; class Entry { public: - static std::unique_ptr& getInstance(); + static Entry& getInstance(); - Entry(ll::mod::NativeMod& self) : mSelf(self) {} + Entry() : mSelf((*ll::mod::NativeMod::current())) {} [[nodiscard]] ll::mod::NativeMod& getSelf() const { return mSelf; } @@ -30,12 +31,14 @@ public: bool disable(); /// @return True if the mod is unloaded successfully. - bool unload(); Config& getConfig(); LangI18n& getI18n(); + std::vector userCache; + + private: ll::mod::NativeMod& mSelf; std::optional mConfig; diff --git a/src/InventoryCheck.cpp b/src/InventoryCheck.cpp index d77d3d2..4fecd82 100644 --- a/src/InventoryCheck.cpp +++ b/src/InventoryCheck.cpp @@ -15,44 +15,80 @@ #include "ll/api/form/SimpleForm.h" #include "ll/api/form/CustomForm.h" +#include "gmlib/gm/data/UserCache.h" #include "gmlib/mc/world/actor/OfflinePlayer.h" -#include -bool saveInventory(Player& player) { - auto& pl = static_cast(player); +void saveInventory(Player& player) { + auto& pl = static_cast(player); auto uuid = pl.getUuid(); ll::file_utils::writeFile( - "./plugins/InventoryCheck/save/" + uuid.asString() + ".dat", + "./plugins/InventoryChecker/save/" + uuid.asString() + ".dat", pl.getNbt()->toBinaryNbt(), true ); - return false; +} +bool validSetNbt(mce::UUID uuid, const std::unique_ptr& nbt) { + try { + Player* player = ll::service::getLevel()->getPlayer(uuid); + if (player && nbt) { + auto& pl=static_cast(*player); + pl.setNbt(*nbt); + pl.refreshInventory(); + return true; + } else if (nbt) {auto db = ll::service::getDBStorage(); + if (db && db->hasKey("player_" + uuid.asString(), DBHelpers::Category::Player)) { + std::unique_ptr playerTag = + db->getCompoundTag("player_" + uuid.asString(), DBHelpers::Category::Player); + if (playerTag) { + std::string serverId = playerTag->at("ServerId"); + if (!serverId.empty()) { + auto player_offline = gmlib::OfflinePlayer(uuid,serverId); + player_offline.setNbt(*nbt); + return true; + } + } + } + + } + return false; + } + catch (...) { + return false; + + } } bool resumeInventory(Player& player) { - auto& pl = static_cast(player); + auto& pl = static_cast(player); auto uuid = pl.getUuid(); - std::string path = "./plugins/InventoryCheck/save/" + uuid.asString() + ".dat"; + std::string path = "./plugins/InventoryChecker/save/" + uuid.asString() + ".dat"; 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"}); + auto playerNbt=pl.getNbt(); + + playerNbt->mTags["Armor"] =nbt->at("Armor"); + playerNbt->mTags["EnderChestInventory"] = nbt->at("EnderChestInventory"); + playerNbt->mTags["Offhand"] = nbt->at("Offhand"); + playerNbt->mTags["Inventory"] = nbt->at("Inventory"); + pl.setNbt(*playerNbt); + pl.refreshInventory(); + + return true; } } return false; } - 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) { - auto res = resumeInventory(pl); - if (res) { + if (auto res = resumeInventory(pl)) { return pl.sendMessage(tr("resumeInventory.success")); } return pl.sendMessage(tr("resumeInventory.failed")); @@ -63,12 +99,13 @@ void mainForm(Player& pl) { void checkOnlineForm(Player& pl) { auto fm = ll::form::SimpleForm(tr("form.checkList.title"), tr("form.checkList.content")); std::unordered_map onlineList; - GMLIB_Level::getLevel()->forEachPlayer([&onlineList](Player& pl) -> bool { + ll::service::getLevel()->forEachPlayer([&onlineList](Player& pl) -> bool { if (!pl.isSimulated()) { onlineList[pl.getUuid()] = pl.getRealName(); } return true; }); + for (auto& [uuid, name] : onlineList) { if (uuid != pl.getUuid()) { fm.appendButton(name, [uuid](Player& pl) { return checkPlayerForm(pl, uuid); }); @@ -83,21 +120,43 @@ void checkOnlineForm(Player& pl) { } }); } - std::string getNameFormUuid(mce::UUID const& uuid) { - auto player = GMLIB_Level::getLevel()->getPlayer(uuid); + auto player = ll::service::getLevel()->getPlayer(uuid); std::string name; if (player) { name = player->getRealName(); } else { - auto cache = GMLIB::UserCache::getNameByUuid(uuid); - name = cache ? cache.value() : uuid.asString(); + // 获取 UserCache 实例 + auto userCache = gmlib::UserCache::getInstance(); + if (!userCache) { + return uuid.asString(); // UserCache 未初始化或不可用 + } + + // 查询用户信息 + auto entry = userCache->from(uuid); + + + if (!entry) { + return uuid.asString(); // 未找到对应 UUID 的用户 + } + name = entry->mName; } return name; } std::unordered_map generateUuidMap() { - auto allUuids = GMLIB_Player::getAllUuids(); + auto userCache = gmlib::UserCache::getInstance(); + if (!userCache) { + // 处理 UserCache 未初始化的情况 + } + + std::vector allUuids; + for (const auto& entry : userCache->entries()) { + allUuids.push_back(entry.mUuid); + } + for (const auto& player : ll::service::getLevel()->getPlayerList()) { + allUuids.push_back(player.first); + } std::unordered_map allList; for (auto& uuid : allUuids) { auto name = getNameFormUuid(uuid); @@ -194,19 +253,58 @@ void searchNotFoundForm(Player& pl, std::string const& name) { return mainForm(pl); }); } +std::unique_ptr getNBTptr(mce::UUID uuid) { + if (auto player = ll::service::getLevel()->getPlayer(uuid)) { + auto& pl=static_cast(*player); + return pl.getNbt(); + } + else { + auto db = ll::service::getDBStorage(); + if (db && db->hasKey("player_" + uuid.asString(), DBHelpers::Category::Player)) { + std::unique_ptr playerTag = + db->getCompoundTag("player_" + uuid.asString(), DBHelpers::Category::Player); + if (playerTag) { + std::string serverId = playerTag->at("ServerId"); + if (!serverId.empty() && db->hasKey(serverId, DBHelpers::Category::Player)) { + auto player_offline = gmlib::OfflinePlayer(uuid,serverId); + if (auto nbtResult = player_offline.getNbt()) { + return std::make_unique(nbtResult.value()); + } + + + } + } + } + + } + return nullptr; +} 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) { saveInventory(pl); - auto nbt = GMLIB_Player::getPlayerNbt(uuid); - if (!nbt) { + auto nbt =getNBTptr(uuid); + + auto playerNbt=getNBTptr(pl.getUuid()); + if ((!nbt)||(!playerNbt)) { + return pl.sendMessage(tr("checkPlayer.copyInventory.failed", {name})); } - auto& self = static_cast(pl); - GMLIB_Player::setPlayerNbtTags(pl.getUuid(), *nbt, {"Offhand", "Inventory", "Armor", "EnderChestInventory"}); + playerNbt->mTags["Armor"] = nbt->at("Armor"); + playerNbt->mTags["EnderChestInventory"] = nbt->at("EnderChestInventory"); + playerNbt->mTags["Offhand"] = nbt->at("Offhand"); + playerNbt->mTags["Inventory"] = nbt->at("Inventory"); + + bool success= validSetNbt(pl.getUuid(), std::move(playerNbt)); + pl.refreshInventory(); + if (!success) { + return pl.sendMessage(tr("checkPlayer.copyInventory.failed", {name})); + } + return pl.sendMessage(tr("checkPlayer.copyInventory.success", {name})); + }); fm.appendButton(tr("form.checkPlayer.writeInventory"), [uuid, name](Player& pl) { return confirmWriteForm(pl, uuid, name); @@ -236,6 +334,8 @@ void invalidInputForm(Player& pl) { }); } + + void confirmWriteForm(Player& pl, mce::UUID const& uuid, std::string const& name) { auto fm = ll::form::ModalForm( tr("form.confirmWrite.title"), @@ -245,13 +345,23 @@ void confirmWriteForm(Player& pl, mce::UUID const& uuid, std::string const& name ); fm.sendTo(pl, [uuid, name](Player& pl, ll::form::ModalFormResult result, ll::form::FormCancelReason) { if (result == ll::form::ModalFormSelectedButton::Upper) { - auto& self = static_cast(pl); + auto& self = static_cast(pl); auto nbt = self.getNbt(); - auto targetNbt = GMLIB_Player::getPlayerNbt(uuid); + auto targetNbt = getNBTptr(uuid); + if (!targetNbt) { return pl.sendMessage(tr("checkPlayer.writeInventory.failed", {name})); } - GMLIB_Player::setPlayerNbtTags(uuid, *nbt, {"Offhand", "Inventory", "Armor", "EnderChestInventory"}); + targetNbt->mTags["Armor"] = nbt->at("Armor"); + targetNbt->mTags["EnderChestInventory"] = nbt->at("EnderChestInventory"); + targetNbt->mTags["Offhand"] = nbt->at("Offhand"); + targetNbt->mTags["Inventory"] = nbt->at("Inventory"); + bool success= validSetNbt(uuid, std::move(targetNbt)); + pl.refreshInventory(); + if (!success) { + return pl.sendMessage(tr("checkPlayer.writeInventory.failed", {name})); + } + return pl.sendMessage(tr("checkPlayer.writeInventory.success", {name})); } return checkPlayerForm(pl, uuid); @@ -267,10 +377,11 @@ void confirmDeleteForm(Player& pl, mce::UUID const& uuid, std::string const& nam ); fm.sendTo(pl, [uuid, name](Player& pl, ll::form::ModalFormResult result, ll::form::FormCancelReason) { if (result == ll::form::ModalFormSelectedButton::Upper) { - if (auto player = GMLIB_Level::getLevel()->getPlayer(uuid)) { + if (auto player = ll::service::getLevel()->getPlayer(uuid)) { return deleteFailedForm(pl, uuid, name); } - GMLIB_Player::deletePlayer(uuid); + gmlib::OfflinePlayer::deletePlayerNbt(uuid); + return pl.sendMessage(tr("checkPlayer.deletePlayer.success", {name})); } return checkPlayerForm(pl, uuid);