diff --git a/src/ll/api/command/UnlockCommand.cpp b/src/ll/api/command/UnlockCommand.cpp new file mode 100644 index 0000000000..36037976b9 --- /dev/null +++ b/src/ll/api/command/UnlockCommand.cpp @@ -0,0 +1,59 @@ +#include "ll/api/base/Global.h" +#include "ll/api/memory/Hook.h" +#include "ll/core/Config.h" + +#include "magic_enum.hpp" + +#include "mc/server/commands/CommandRegistry.h" +#include "mc/server/commands/CommandSelectorBase.h" + + +using namespace ll::memory; + +LL_AUTO_TYPED_INSTANCE_HOOK( + UnlockCmdHookRegisterCommand, + HookPriority::Normal, + CommandRegistry, + &CommandRegistry::registerCommand, + void, + std::string const& name, + char const* description, + ::CommandPermissionLevel permlevel, + CommandFlag flag1, + CommandFlag flag2 // useless, idiot +) { + if (ll::globalConfig.enableUnlockCmd) { flag1 |= CommandFlagValue::NotCheat; } + + return origin(name, description, permlevel, flag1, flag2); +} + +LL_AUTO_TYPED_INSTANCE_HOOK( + UnlockCmdHookIsExpansionAllowed, + HookPriority::Normal, + CommandSelectorBase, + &CommandSelectorBase::isExpansionAllowed, + bool, + CommandOrigin const& commandOrigin +) { + if (ll::globalConfig.enableUnlockCmd) { return true; } + return origin(commandOrigin); +} + +LL_AUTO_TYPED_INSTANCE_HOOK( + UnlockCmdHookAddEnumValueConstraints, + HookPriority::Normal, + CommandRegistry, + &CommandRegistry::addEnumValueConstraints, + void, + std::string const& enumName, + std::vector const& enumValues, + SemanticConstraint constraint +) { + using namespace magic_enum::bitwise_operators; + if (ll::globalConfig.enableUnlockCmd + && magic_enum::enum_integer(constraint & SemanticConstraint::RequiresCheatsEnabled)) { + constraint = constraint & (~SemanticConstraint::RequiresCheatsEnabled); + constraint = constraint | SemanticConstraint::RequiresElevatedPermissions; + } + return origin(enumName, enumValues, constraint); +} diff --git a/src/ll/api/service/GlobalService.cpp b/src/ll/api/service/GlobalService.cpp index bf9e01736f..df04a0fa25 100644 --- a/src/ll/api/service/GlobalService.cpp +++ b/src/ll/api/service/GlobalService.cpp @@ -60,6 +60,7 @@ LL_AUTO_TYPED_INSTANCE_HOOK( (RakNet::RakPeer*)((RakNetConnector&)(*ll::Global->getNetworkSystem().getRemoteConnector())) .getPeer() ); + ll::Global.init(ll::Global->getStructureManager().get()); ll::Global.init(ll::Global->getLevel()); ll::Global.init((ServerLevel*)ll::Global); origin(ins); @@ -75,11 +76,8 @@ LL_AUTO_TYPED_INSTANCE_HOOK( std::string const& a1, bool a2 ) { - static bool initd = false; - if (!initd) { - initd = true; - ll::Global.init(this); - } + ll::Global.init(this); + unhook(); origin(a1, a2); } @@ -106,6 +104,7 @@ LL_AUTO_TYPED_INSTANCE_HOOK( bool const ) { ll::Global.init(this); + unhook(); return origin(); } @@ -122,6 +121,3 @@ LL_AUTO_TYPED_INSTANCE_HOOK( } } // namespace - -// fixme: remove or implement -template class ll::GlobalService; diff --git a/src/ll/core/LeviLamina.cpp b/src/ll/core/LeviLamina.cpp index af0eea7423..1f5144148a 100644 --- a/src/ll/core/LeviLamina.cpp +++ b/src/ll/core/LeviLamina.cpp @@ -216,7 +216,6 @@ void checkProtocolVersion() { if (TARGET_BDS_PROTOCOL_VERSION != currentProtocol) { logger.warn(tr("ll.main.warning.protocolVersionNotMatch.1"), TARGET_BDS_PROTOCOL_VERSION, currentProtocol); logger.warn(tr("ll.main.warning.protocolVersionNotMatch.2")); - std::this_thread::sleep_for(std::chrono::seconds(1)); } } diff --git a/src/ll/core/ModifyInfomation.cpp b/src/ll/core/ModifyInfomation.cpp index 321be1a81b..5388769467 100644 --- a/src/ll/core/ModifyInfomation.cpp +++ b/src/ll/core/ModifyInfomation.cpp @@ -1,5 +1,6 @@ #include "ll/api/LoggerAPI.h" #include "ll/api/memory/Hook.h" +#include "mc/common/Common.h" #include "mc/deps/core/common/debug/LogDetails.h" @@ -16,7 +17,7 @@ std::unordered_map loggerMap = { LL_AUTO_TYPED_INSTANCE_HOOK( AppendLogEntryMetadataHook, - ll::memory::HookPriority::Normal, + HookPriority::Normal, ::BedrockLog::LogDetails, &::BedrockLog::LogDetails::_appendLogEntryMetadata, void, @@ -33,7 +34,7 @@ MCAPI void BedrockLogOut(unsigned int priority, const char* pszFormat, ...); LL_AUTO_STATIC_HOOK( BedrockLogOutHook, - ll::memory::HookPriority::Normal, + HookPriority::Normal, BedrockLogOut, void, unsigned int priority, diff --git a/src/ll/core/Version.h.in b/src/ll/core/Version.h.in index cddb17eb30..8c1681b67b 100644 --- a/src/ll/core/Version.h.in +++ b/src/ll/core/Version.h.in @@ -14,7 +14,7 @@ #define LL_VERSION_COMMIT_SHA ${GIT_COMMIT} -#define TARGET_BDS_PROTOCOL_VERSION 568 +#define TARGET_BDS_PROTOCOL_VERSION 618 #define LL_VERSION_TO_STRING_INNER(ver) #ver #define LL_VERSION_TO_STRING(ver) LL_VERSION_TO_STRING_INNER(ver) diff --git a/src/mc/common/wrapper/optional_ref.h b/src/mc/common/wrapper/optional_ref.h index a2d71f0d89..ba33b3d9c2 100644 --- a/src/mc/common/wrapper/optional_ref.h +++ b/src/mc/common/wrapper/optional_ref.h @@ -20,12 +20,6 @@ class optional_ref { constexpr optional_ref(std::nullptr_t) noexcept {} - // template - // requires(IsCompatibleV) - // constexpr optional_ref(std::optional const& o) - // requires(std::is_const_v) - // : ptr_(o ? &*o : nullptr) {} - template requires(IsCompatibleV) constexpr optional_ref(std::optional& o) : ptr_(o ? &*o : nullptr) {} @@ -34,10 +28,6 @@ class optional_ref { requires(IsCompatibleV) constexpr optional_ref(U* p) : ptr_(p) {} - // template - // requires(IsCompatibleV) - // constexpr optional_ref(U const& r) : ptr_(std::addressof(r)) {} - template requires(IsCompatibleV) constexpr optional_ref(U& r) : ptr_(std::addressof(r)) {} @@ -57,11 +47,11 @@ class optional_ref { [[nodiscard]] constexpr T* as_ptr() const noexcept { return ptr_; } constexpr T* operator->() const { - if (!has_value()) { throw std::bad_optional_access{}; } + if (!has_value()) { throw std::runtime_error{"bas optional_ref access"}; } return ptr_; } [[nodiscard]] constexpr T& get() const { - if (!has_value()) { throw std::bad_optional_access{}; } + if (!has_value()) { throw std::runtime_error{"bas optional_ref access"}; } return *ptr_; } @@ -78,7 +68,7 @@ class optional_ref { } [[nodiscard]] constexpr operator T&() const { - if (!has_value()) { throw std::bad_optional_access{}; } + if (!has_value()) { throw std::runtime_error{"bas optional_ref access"}; } return *ptr_; } diff --git a/src/mc/server/commands/CommandFlag.h b/src/mc/server/commands/CommandFlag.h index b5a5beac3e..7b8283c767 100644 --- a/src/mc/server/commands/CommandFlag.h +++ b/src/mc/server/commands/CommandFlag.h @@ -52,4 +52,8 @@ struct CommandFlag { value = rhs.value | value; return *this; } + CommandFlag& operator|=(CommandFlagValue const& rhs) { + value = rhs | value; + return *this; + } }; diff --git a/src/mc/world/item/enchanting/Enchant.h b/src/mc/world/item/enchanting/Enchant.h index 6db821f741..9a6a512c7b 100644 --- a/src/mc/world/item/enchanting/Enchant.h +++ b/src/mc/world/item/enchanting/Enchant.h @@ -81,8 +81,8 @@ class Enchant { CrossbowQuickCharge = 0x23, SoulSpeed = 0x24, SwiftSneak = 0x25, - NumEnchantments = 0x26, - InvalidEnchantment = 0x27, + Count = 0x26, + Invalid = 0x27, }; enum class Activation : int { diff --git a/src/mc/world/level/levelgen/structure/StructureTemplate.cpp b/src/mc/world/level/levelgen/structure/StructureTemplate.cpp index 6d14af2279..1d67cd715f 100644 --- a/src/mc/world/level/levelgen/structure/StructureTemplate.cpp +++ b/src/mc/world/level/levelgen/structure/StructureTemplate.cpp @@ -24,7 +24,7 @@ void StructureTemplate::placeInWorld( } -std::unique_ptr StructureTemplate::create(std::string name, CompoundTag const& tag) { +std::unique_ptr StructureTemplate::create(const std::string& name, CompoundTag const& tag) { auto& unknownBlockRegistry = Global->mUnknownBlockRegistry; auto res = std::make_unique(name, unknownBlockRegistry); bool success{res->load(tag)}; @@ -33,7 +33,7 @@ std::unique_ptr StructureTemplate::create(std::string name, C } std::unique_ptr StructureTemplate::create( - std::string name, + const std::string& name, BlockSource& blockSource, BoundingBox const& boundingBox, bool ignoreBlocks, diff --git a/src/mc/world/level/levelgen/structure/StructureTemplate.h b/src/mc/world/level/levelgen/structure/StructureTemplate.h index d4b5a16443..a54b4b50dc 100644 --- a/src/mc/world/level/levelgen/structure/StructureTemplate.h +++ b/src/mc/world/level/levelgen/structure/StructureTemplate.h @@ -34,11 +34,11 @@ class StructureTemplate { ) const; // nullptr if invalid nbt - LLNDAPI static std::unique_ptr create(std::string name, CompoundTag const& tag); + LLNDAPI static std::unique_ptr create(const std::string& name, CompoundTag const& tag); // always success LLNDAPI static std::unique_ptr create( - std::string name, + const std::string& name, BlockSource& blockSource, BoundingBox const& boundingBox, bool ignoreBlocks = false, diff --git a/temp/FormPacketHelper.cpp b/temp/FormPacketHelper.cpp deleted file mode 100644 index fc43438baf..0000000000 --- a/temp/FormPacketHelper.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include "ll/api/FormUI.h" - -#include "ll/api/Impl/FormPacketHelper.h" -#include "ll/api/utils/fifo_json.h" - -//////////////////////////////// Data //////////////////////////////// - -enum class FormType { - SimpleFormBuilder, - ModalFormBuilder, - CustomFormBuilder, - SimpleFormPacket, - ModalFormPacket, - CustomFormPacket -}; - -unordered_map formTypes; - -unordered_map> simpleFormPacketCallbacks; -unordered_map> modalFormPacketCallbacks; -unordered_map> customFormPacketCallbacks; - -unordered_map> simpleFormBuilders; -unordered_map> modalFormBuilders; -unordered_map> customFormBuilders; - - -//////////////////////////////// Functions //////////////////////////////// - -#define RAND_FORM_ID() (uint)((rand() << 16) + rand()) - -uint NewFormId() { - uint formId; - do { - formId = RAND_FORM_ID(); - } while (formTypes.find(formId) != formTypes.end()); - return formId; -} - -void SetSimpleFormPacketCallback(uint formId, std::function callback) { - formTypes[formId] = FormType::SimpleFormPacket; - simpleFormPacketCallbacks[formId] = callback; -} - -void SetModalFormPacketCallback(uint formId, std::function callback) { - formTypes[formId] = FormType::ModalFormPacket; - modalFormPacketCallbacks[formId] = callback; -} - -void SetCustomFormPacketCallback(uint formId, std::function callback) { - formTypes[formId] = FormType::CustomFormPacket; - customFormPacketCallbacks[formId] = callback; -} - -void SetSimpleFormBuilderData(uint formId, std::shared_ptr data) { - formTypes[formId] = FormType::SimpleFormBuilder; - simpleFormBuilders[formId] = data; -} - -void SetModalFormBuilderData(uint formId, std::shared_ptr data) { - formTypes[formId] = FormType::ModalFormBuilder; - modalFormBuilders[formId] = data; -} - -void SetCustomFormBuilderData(uint formId, std::shared_ptr data) { - formTypes[formId] = FormType::CustomFormBuilder; - customFormBuilders[formId] = data; -} - -void HandleFormPacket(Player* player, uint formId, string const& data) { - if (formTypes.find(formId) == formTypes.end()) - return; - - if (formTypes[formId] == FormType::SimpleFormBuilder) { - int chosen = data != "null" ? stoi(data) : -1; - - // Simple Form Builder - auto form = simpleFormBuilders[formId]; - if (form->callback) - form->callback(player, chosen); - // Button Callback - if (chosen >= 0) { - auto button = dynamic_pointer_cast(form->elements[chosen]); - if (button->callback) - button->callback(player); - } - simpleFormBuilders.erase(formId); - } else if (formTypes[formId] == FormType::ModalFormBuilder) { - int chosen = data == "true" ? 1 : 0; - - // Modal Form Builder - auto form = modalFormBuilders[formId]; - if (form->callback) - form->callback(player, chosen); - modalFormBuilders.erase(formId); - } else if (formTypes[formId] == FormType::CustomFormBuilder) { - // Custom Form Builder - auto form = customFormBuilders[formId]; - - if (data == "null") { - customFormBuilders.erase(formId); - if (form->callback) - form->callback(player, {}); - return; - } - - fifo_json res = fifo_json::parse(data); - int nowIndex = 0; - for (fifo_json& j : res) { - switch (form->getType(nowIndex)) { - case Form::CustomFormElement::Type::Label: // label's data is null - break; - case Form::CustomFormElement::Type::Input: - form->setValue(nowIndex, j.get()); - break; - case Form::CustomFormElement::Type::Toggle: - form->setValue(nowIndex, j.get()); - break; - case Form::CustomFormElement::Type::Slider: - form->setValue(nowIndex, j.get()); - break; - case Form::CustomFormElement::Type::Dropdown: { - auto& options = dynamic_pointer_cast(form->elements[nowIndex].second)->options; - form->setValue(nowIndex, options[j.get()]); - break; - } - case Form::CustomFormElement::Type::StepSlider: { - auto& options = dynamic_pointer_cast(form->elements[nowIndex].second)->options; - form->setValue(nowIndex, options[j.get()]); - break; - } - default: - break; - } - ++nowIndex; - } - - if (form->callback) { - std::map> callbackData; - for (auto& [k, v] : form->elements) - callbackData[k] = v; - - form->callback(player, callbackData); - } - - customFormBuilders.erase(formId); - } else if (formTypes[formId] == FormType::SimpleFormPacket) { - int chosen = data != "null" ? stoi(data) : -1; - simpleFormPacketCallbacks[formId](player, chosen); - simpleFormPacketCallbacks.erase(formId); - } else if (formTypes[formId] == FormType::CustomFormPacket) { - customFormPacketCallbacks[formId](player, data); - customFormPacketCallbacks.erase(formId); - } else if (formTypes[formId] == FormType::ModalFormPacket) { - int chosen = data == "true" ? 1 : 0; - modalFormPacketCallbacks[formId](player, chosen); - modalFormPacketCallbacks.erase(formId); - } - formTypes.erase(formId); -} diff --git a/temp/GlobalService.cpp b/temp/GlobalService.cpp deleted file mode 100644 index d52adc0dbf..0000000000 --- a/temp/GlobalService.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "ll/api/base/Global.h" - -#include "mc/AllowListFile.hpp" -#include "mc/CommandSoftEnumRegistry.hpp" -#include "mc/DBStorage.hpp" -#include "mc/Level.hpp" -#include "mc/Minecraft.hpp" -#include "mc/MinecraftCommands.hpp" -#include "mc/RakNet.hpp" -#include "mc/RakNetServerLocator.hpp" -#include "mc/Scoreboard.hpp" -#include "mc/ServerNetworkHandler.hpp" - -#include "ll/api/service/GlobalService.h" - -#include "ll/api/memory/Hook.h" -#include "ll/api/utils/Hash.h" - -using namespace ll::memory; - -// Minecraft -LL_AUTO_TYPED_INSTANCE_HOOK( - MinecraftService, - Minecraft, - HookPriority::Normal, - "?initAsDedicatedServer@Minecraft@@QEAAXXZ", - void -) { - Global = this; - origin(); -} - -// ServerNetworkHandler -LL_AUTO_TYPED_INSTANCE_HOOK( - ServerNetworkHandlerService, - ServerNetworkHandler, - HookPriority::Normal, - "?allowIncomingConnections@ServerNetworkHandler@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" - "std@@_N@Z", - void, - std::string const& a1, - bool a2 -) { - static bool initd = false; - if (!initd) { - initd = true; - // auto v3 = (ServerNetworkHandler*)((char*)this + 16); - // +16 cause fetchConnectionRequest returns nullptr - Global = this; - } - origin(a1, a2); -} - -// TInstanceHook(ServerNetworkHandler*, -// "??0ServerNetworkHandler@@QEAA@AEAVGameCallbacks@@AEBV?$NonOwnerPointer@VILevel@@@Bedrock@@AEAVNetworkHandler@@AEAVPrivateKeyManager@@AEAVServerLocator@@AEAVPacketSender@@AEAVAllowList@@PEAVPermissionsFile@@AEBVUUID@mce@@H_NAEBV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HAEAVMinecraftCommands@@AEAVIMinecraftApp@@AEBV?$unordered_map@UPackIdVersion@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@U?$hash@UPackIdVersion@@@3@U?$equal_to@UPackIdVersion@@@3@V?$allocator@U?$pair@$$CBUPackIdVersion@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@std@@@3@@std@@AEAVScheduler@@V?$NonOwnerPointer@VTextFilteringProcessor@@@3@@Z", -// ServerNetworkHandler, class GameCallbacks& a1, class Bedrock::NonOwnerPointer const& a2, -// class NetworkHandler& a3, class PrivateKeyManager& a4, class ServerLocator& a5, class PacketSender& a6, -// class AllowList& a7, class PermissionsFile* a8, class mce::UUID const& a9, int a10, bool a11, -// std::vector const& a12, std::string a13, int a14, class MinecraftCommands& a15, class -// IMinecraftApp& a16, class std::unordered_map const& a17, class -// Scheduler& a18, class Bedrock::NonOwnerPointer a19) -//{ -// auto rtn = origin( a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); -// Global = this; -// //Global = &a3; -// Global = &a15; -// return rtn; -// } - -// MinecraftCommands -LL_AUTO_TYPED_INSTANCE_HOOK( - MinecraftCommandsService, - MinecraftCommands, - HookPriority::Normal, - "?initCoreEnums@MinecraftCommands@@QEAAXVItemRegistryRef@@AEBVIWorldRegistriesProvider@@AEBVActorFactory@" - "@AEBVExperiments@@AEBVBaseGameVersion@@@Z", - void, - void* a2, - int64 a3, - int64 a4, - void* a5, - void* a6 -) { - origin(a2, a3, a4, a5, a6); - Global = this; -} - -// LevelStorage & DBStorage -LL_AUTO_TYPED_INSTANCE_HOOK( - LevelStorageService, - DBStorage, - HookPriority::Normal, - "??0DBStorage@@QEAA@UDBStorageConfig@@V?$not_null@V?$NonOwnerPointer@VLevelDbEnv@@@Bedrock@@@gsl@@@Z", - DBStorage*, - struct DBStorageConfig* config, - void* a3 -) { - auto ret = origin(config, a3); - Global = (LevelStorage*)this; - Global = this; - return ret; -} - -// RakNetServerLocator -// ?activate@RakNetServerLocator@@AEAAXXZ -LL_AUTO_TYPED_INSTANCE_HOOK(RakNetServerLocatorService, RakNetServerLocator, HookPriority::Normal, "?_activate@RakNetServerLocator@@AEAAXXZ", void*) { - constexpr auto h = do_hash("?_activate@RakNetServerLocator@@AEAAXXZ"); - static bool set = false; - if (!set) { - set = true; - Global = this; - } - return origin(); -} - -using RakNet::RakPeer; -LL_AUTO_TYPED_INSTANCE_HOOK(RakPeerService, RakPeer, HookPriority::Normal, "??0RakPeer@RakNet@@QEAA@XZ", void*) { - static bool set = false; - if (!set) { - set = true; - Global = this; - } - return origin(); -} - -// Scoreboard -LL_AUTO_TYPED_INSTANCE_HOOK( - ScoreboardService, - Scoreboard, - HookPriority::Normal, - "??0ServerScoreboard@@QEAA@VCommandSoftEnumRegistry@@PEAVLevelStorage@@@Z", - Scoreboard*, - void** a2, - class LevelStorage* a3 -) { - Scoreboard* sc = origin(a2, a3); - Global = sc; - return sc; -} - -// AllowListFile -LL_AUTO_TYPED_INSTANCE_HOOK( - AllowListFileService, - AllowListFile, - HookPriority::Normal, - "?reload@AllowListFile@@QEAA?AW4FileReadResult@@XZ", - int -) { - static bool set = false; - if (!set) { - Global = this; - set = true; - } - return origin(); -} -// PropertiesSettings -// -> BuiltinBugFix.cpp diff --git a/temp/LoggerAPI.cpp b/temp/LoggerAPI.cpp deleted file mode 100644 index a8ca0a83a9..0000000000 --- a/temp/LoggerAPI.cpp +++ /dev/null @@ -1,253 +0,0 @@ -// -// Created by RimuruChan on 2021/12/11. -// - -#pragma once - -#include -#include - -#include "ll/api/LoggerAPI.h" -#include "ll/api/utils/Hash.h" -#include "mc/Player.hpp" - -#include "ll/core/Config.h" - -#define LOGGER_CURRENT_TITLE "ll_plugin_logger_title" -#define LOGGER_CURRENT_FILE "ll_plugin_logger_file" - -std::unordered_map lockerList; - -bool Logger::setDefaultFileImpl(HMODULE hPlugin, std::string const& logFile, bool appendMode = true) { - if (logFile.empty()) { - PluginOwnData::removeImpl(hPlugin, LOGGER_CURRENT_FILE); - return true; - } else { - std::error_code ec; - std::filesystem::create_directories(std::filesystem::path(str2wstr(logFile)).remove_filename(), ec); - - auto& res = PluginOwnData::setImpl( - hPlugin, LOGGER_CURRENT_FILE, logFile, appendMode ? std::ios::app : std::ios::out - ); - return res.is_open(); - } -} - -bool Logger::setDefaultFileImpl(HMODULE hPlugin, nullptr_t) { - PluginOwnData::removeImpl(hPlugin, LOGGER_CURRENT_FILE); - return true; -} - -bool Logger::setFile(std::string const& logFile, bool appendMode) { - if (ofs.is_open()) - ofs.close(); - - if (logFile.empty()) { - return true; - } else { - std::error_code ec; - std::filesystem::create_directories(std::filesystem::path(str2wstr(logFile)).remove_filename(), ec); - ofs.open(logFile, appendMode ? std::ios::app : std::ios::out); - return ofs.is_open(); - } -} - -bool Logger::setFile(nullptr_t) { - if (ofs.is_open()) - ofs.close(); - return true; -} - -bool Logger::tryLock() { return lockerList[title].tryLock(); } - -bool Logger::lock() { return lockerList[title].lock(); } - -bool Logger::unlock() { return lockerList[title].unlock(); } - -CsLock& Logger::getLocker() { return lockerList[title]; } - -Logger::OutputStream::OutputStream() = default; - -Logger::OutputStream::OutputStream( - Logger* logger, - int level, - std::string&& consoleFormat, - std::string&& fileFormat, - std::string&& playerFormat, - fmt::text_style&& style, - std::string&& levelPrefix -) { - this->logger = logger; - this->level = level; - this->consoleFormat = consoleFormat; - this->fileFormat = fileFormat; - this->playerFormat = playerFormat; - this->style = style; - this->levelPrefix = levelPrefix; -} - -bool checkLogLevel(int level, int outLevel) { - if (level >= outLevel) - return true; - if (level == -1 && ll::globalConfig.logLevel >= outLevel) - return true; - return false; -} -#define H do_hash -fmt::text_style getModeColor(string const& a1) { - if (!ll::globalConfig.colorLog) - return {}; - switch (H(a1.c_str())) { - case H("INFO"): - return fmt::fg(fmt::color::light_sea_green); - case H("WARN"): - return fmt::fg(fmt::color::yellow); - case H("DEBUG"): - return fmt::fg(fmt::color::white); - case H("ERROR"): - return fmt::fg(fmt::terminal_color::bright_red); - case H("FATAL"): - return fmt::fg(fmt::color::red); - } - return fmt::fg(fmt::color::white); -} - -template > -std::string applyTextStyle(const fmt::v9::text_style& ts, S const& format_str) { - fmt::v9::basic_memory_buffer buf; - auto fmt = fmt::detail::to_string_view(format_str); - bool has_style = false; - if (ts.has_emphasis()) { - has_style = true; - auto emphasis = fmt::v9::detail::make_emphasis(ts.get_emphasis()); - buf.append(emphasis.begin(), emphasis.end()); - } - if (ts.has_foreground()) { - has_style = true; - auto foreground = fmt::v9::detail::make_foreground_color(ts.get_foreground()); - buf.append(foreground.begin(), foreground.end()); - } - if (ts.has_background()) { - has_style = true; - auto background = fmt::v9::detail::make_background_color(ts.get_background()); - buf.append(background.begin(), background.end()); - } - buf.append(fmt.begin(), fmt.end()); - if (has_style) - fmt::v9::detail::reset_color(buf); - return fmt::to_string(buf); -} - -void Logger::endlImpl(HMODULE hPlugin, OutputStream& o) { - try { - CsLockHolder lock(o.logger->getLocker()); - - std::string title = o.logger->title; - if (!title.empty()) - title = "[" + title + "]"; - - auto text = o.os.str(); - bool filterBanned = false; - // Output Filter - if (ll::globalConfig.enableOutputFilter) - for (auto& regexStr : ll::globalConfig.outputFilterRegex) { - try { - std::regex re(regexStr); - if (std::regex_search(text, re) || std::regex_search(title, re)) { - filterBanned = true; - break; - } - } catch (...) { - } - } - - if (checkLogLevel(o.logger->consoleLevel, o.level) && !filterBanned) { - fmt::print( - fmt::runtime(o.consoleFormat), - applyTextStyle( - ll::globalConfig.colorLog ? fg(fmt::color::light_blue) : fmt::text_style(), - fmt::format("{:%H:%M:%S}", fmt::localtime(_time64(nullptr))) - ), - applyTextStyle(getModeColor(o.levelPrefix), o.levelPrefix), - applyTextStyle(ll::globalConfig.colorLog ? o.style : fmt::text_style(), title), - applyTextStyle(ll::globalConfig.colorLog ? o.style : fmt::text_style(), text) - ); - } - - if (checkLogLevel(o.logger->fileLevel, o.level) && - (ll::globalConfig.onlyFilterConsoleOutput || !filterBanned)) { - if (o.logger->ofs.is_open() || PluginOwnData::hasImpl(hPlugin, LOGGER_CURRENT_FILE)) { - auto fileContent = fmt::format( - fmt::runtime(o.fileFormat), fmt::localtime(_time64(nullptr)), o.levelPrefix, title, text - ); - if (o.logger->ofs.is_open()) - o.logger->ofs << fileContent << std::flush; - else - PluginOwnData::getImpl(hPlugin, LOGGER_CURRENT_FILE) << fileContent << std::flush; - } - } - - if (checkLogLevel(o.logger->playerLevel, o.level) && o.logger->player && Player::isValid(o.logger->player) && - (ll::globalConfig.onlyFilterConsoleOutput || !filterBanned)) { - o.logger->player->sendTextPacket( - fmt::format(fmt::runtime(o.playerFormat), fmt::localtime(_time64(nullptr)), o.levelPrefix, title, text) - ); - } - - o.os.str(""); - o.os.clear(); - } catch (...) { - std::cerr << "Error in Logger::endlImpl" << std::endl; - o.os.str(""); - o.os.clear(); - } -} - -Logger::Logger(std::string const& title) { - this->title = title; - debug = OutputStream{ - this, - 5, - "{} {} {} {}\n", - "[{:%Y-%m-%d %H:%M:%S} {}]{} {}\n", - "§o[{}{}]{} {}\n", - fmt::fg(fmt::terminal_color::white) | fmt::emphasis::italic, - "DEBUG"}; - info = OutputStream{ - this, - 4, - "{} {} {} {}\n", - "[{:%Y-%m-%d %H:%M:%S} {}]{} {}\n", - "[{}{}]{} {}\n", - fmt::fg(fmt::terminal_color::white), - "INFO"}; - warn = OutputStream{ - this, - 3, - "{} {} {} {}\n", - "[{:%Y-%m-%d %H:%M:%S} {}]{} {}\n", - "§e[{}{}]{} {}\n", - fmt::fg(fmt::terminal_color::yellow) | fmt::emphasis::bold, - "WARN"}; - error = OutputStream{ - this, - 2, - "{} {} {} {}\n", - "[{:%Y-%m-%d %H:%M:%S} {}]{} {}\n", - "§c[{}{}]{} {}\n", - fmt::fg(fmt::color::red) | fmt::emphasis::bold, - "ERROR"}; - fatal = OutputStream{ - this, - 1, - "{} {} {} {}\n", - "[{:%Y-%m-%d %H:%M:%S} {}]{} {}\n", - "§4[{}{}]{} {}\n", - fmt::fg(fmt::color::red) | fmt::emphasis::bold, - "FATAL"}; -} - -// For compatibility -void Logger::initLockImpl(HMODULE hPlugin) { ; } -void Logger::lockImpl(HMODULE hPlugin) { ; } -void Logger::unlockImpl(HMODULE hPlugin) { ; } diff --git a/temp/RegCommandAPI.h b/temp/RegCommandAPI.h deleted file mode 100644 index fa7045b609..0000000000 --- a/temp/RegCommandAPI.h +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once -#include "ll/api/base/Global.h" -#include "mc/Actor.hpp" -#include "mc/Command.hpp" -#include "mc/CommandMessage.hpp" -#include "mc/CommandOutput.hpp" -#include "mc/CommandParameterData.hpp" -#include "mc/CommandPosition.hpp" -#include "mc/CommandRegistry.hpp" -#include "mc/CommandSelector.hpp" -#include "mc/Player.hpp" -#include - -namespace RegisterCommandHelper { -template -static int getOffset(Type Command::*src) { - union { - Type Command::*src; - int value; - } u; - u.src = src; - return u.value; -} - -using ParseFn = - bool (CommandRegistry::*)(void*, CommandRegistry::ParseToken const&, CommandOrigin const&, int, std::string&, std::vector&) - const; - -template -static CommandParameterData makeMandatory(Type Command::*field, std::string name, bool Command::*isSet = nullptr) { - - return { - type_id(), - CommandRegistry::getParseFn(), - name, - CommandParameterDataType::NORMAL, - nullptr, - getOffset(field), - false, - isSet ? getOffset(isSet) : -1, - }; -} -template -static CommandParameterData -makeMandatory(Type Command::*field, std::string name, char const* desc = nullptr, bool Command::*isSet = nullptr) { - return { - type_id(), - CommandRegistry::getParseFn(), - name, - DataType, - desc, - getOffset(field), - false, - isSet ? getOffset(isSet) : -1, - }; -} -template -static CommandParameterData makeOptional(Type Command::*field, std::string name, bool Command::*isSet = nullptr) { - typeid_t tpid{0}; - - return { - type_id(), - CommandRegistry::getParseFn(), - name, - CommandParameterDataType::NORMAL, - nullptr, - getOffset(field), - true, - isSet ? getOffset(isSet) : -1, - }; -} -template -static CommandParameterData -makeOptional(Type Command::*field, std::string name, char const* desc = nullptr, bool Command::*isSet = nullptr) { - - return { - type_id(), - CommandRegistry::getParseFn(), - name, - DataType, - desc, - getOffset(field), - true, - isSet ? getOffset(isSet) : -1, - }; -} -} // namespace RegisterCommandHelper diff --git a/temp/SendPacketAPI.h b/temp/SendPacketAPI.h deleted file mode 100644 index 4edebe53c6..0000000000 --- a/temp/SendPacketAPI.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include "mc/BinaryStream.hpp" -#include "mc/Packet.hpp" - -template -class NetworkPacket : public Packet { -public: - std::string_view view; - NetworkPacket() { incompressible = compress; } - NetworkPacket(std::string_view sv) : view(sv) { incompressible = compress; } - inline virtual ~NetworkPacket() {} - - virtual enum MinecraftPacketIds getId() const { return (enum MinecraftPacketIds)pid; } - virtual std::string getName() const { return "MyPkt"; } - virtual void write(BinaryStream& bs) const { bs.getRaw().append(view); } - virtual enum StreamReadResult _read(class ReadOnlyBinaryStream&) override { - throw("TODO in MyPkt::_read()"); - return (enum StreamReadResult)0; - } - virtual void dummyread() { throw("TODO in MyPkt::dummyread()"); } - virtual bool disallowBatching() const { return !batching; } -}; \ No newline at end of file diff --git a/temp/core/BuiltinUnlockCmd.cpp b/temp/core/BuiltinUnlockCmd.cpp deleted file mode 100644 index 0ce04e1ced..0000000000 --- a/temp/core/BuiltinUnlockCmd.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "ll/api/base/Global.h" -#include "ll/api/memory/Hook.h" -#include "mc/CommandParameterData.hpp" - -#include "ll/core/Config.h" -#include "magic_enum.hpp" - -using namespace ll::memory; - -/////////////////// Built in UnlockCmd /////////////////// - -// ==> LeviLamina/Main/SimpleServerLogger.cpp -void LogCommandRegistration( - std::string const& name, - char const* description, - enum CommandPermissionLevel perm, - short flag1, - short flag2 -); - -LL_AUTO_TYPED_INSTANCE_HOOK( - UnlockCmdHook0, - CommandRegistry, - HookPriority::Normal, - "?registerCommand@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@" - "PEBDW4CommandPermissionLevel@@UCommandFlag@@3@Z", - void, - std::string const& name, - char const* description, - enum CommandPermissionLevel perm, - short flag1, - short flag2 -) { - // For #643 - if (name.find(' ') == std::string::npos) { // If no space inside - // Check whether command is already exists before registering - if (this->findCommand(name)) { - // throw to prevent setup function, then this exception can be caught by event handler - throw std::runtime_error("There is already a command named " + name); - } - } - if (ll::globalConfig.enableUnlockCmd) { - flag1 |= 0x80; - } - if (ll::globalConfig.debugMode) { - LogCommandRegistration(name, description, perm, flag1, flag2); - } - return origin(name, description, perm, flag1, flag2); -} - -class CommandSelectorBase; -class CommandOrigin; -LL_AUTO_INSTANCE_HOOK( - UnlockCmdHook1, - HookPriority::Normal, - "?isExpansionAllowed@CommandSelectorBase@@AEBA_NAEBVCommandOrigin@@@Z", - bool, - CommandOrigin* a2 -) { - if (ll::globalConfig.enableUnlockCmd) { - origin(a2); - return true; - } - return origin(a2); -} - -// #include -// #include -// #include -// #include -// inline void tryChangeStringToRawText(CommandParameterData& data) -//{ -// if (false /* config.xxxx*/ && data.tid.value == type_id().value) -// { -// data.tid = type_id(); -// data.parser = CommandRegistry::getParseFn(); -// } -// } -//// allowlist -// TInstanceHook(CommandRegistry::Overload*, -// "??$_registerOverload@VAllowListCommand@@VCommandParameterData@@V2@@CommandRegistry@@AEAAPEAUOverload@0@PEBDVCommandVersion@@AEBVCommandParameterData@@2@Z", -// CommandRegistry, char const* unk, class CommandVersion version, class CommandParameterData const& -// operationParam, class CommandParameterData& nameParam) -//{ -// tryChangeStringToRawText(nameParam); -// return origin( unk, version, operationParam, nameParam); -// } -//// op -// TInstanceHook(CommandRegistry::Overload*, -// "??$_registerOverload@VOpCommand@@VCommandParameterData@@@CommandRegistry@@AEAAPEAUOverload@0@PEBDVCommandVersion@@AEBVCommandParameterData@@@Z", -// CommandRegistry, char const* unk, class CommandVersion version, class CommandParameterData& nameParam) -//{ -// tryChangeStringToRawText(nameParam); -// return origin( unk, version, nameParam); -// } -//// deop -// TInstanceHook(CommandRegistry::Overload*, -// "??$_registerOverload@VDeOpCommand@@VCommandParameterData@@@CommandRegistry@@AEAAPEAUOverload@0@PEBDVCommandVersion@@AEBVCommandParameterData@@@Z", -// CommandRegistry, char const* unk, class CommandVersion version, class CommandParameterData& nameParam) -//{ -// tryChangeStringToRawText(nameParam); -// return origin( unk, version, nameParam); -// } -// bool unlockNewExecute = true; -// TClasslessInstanceHook(bool, "?isEnabled@FeatureToggles@@QEBA_NW4FeatureOptionID@@@Z", -// int feature) -// { -// if (feature == 54 && unlockNewExecute) -// return true; -// return origin( feature); -// } -// TClasslessInstanceHook(void, "?addSemanticConstraint@CommandRegistry@@AEAAXW4SemanticConstraint@@@Z", -// enum SemanticConstraint) -//{ -// return; -// } -LL_AUTO_INSTANCE_HOOK( - UnlockCmdHook2, - HookPriority::Normal, - "?addEnumValueConstraints@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@" - "AEBV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_" - "traits@D@std@@V?$allocator@D@2@@std@@@2@@3@W4SemanticConstraint@@@Z", - void, - std::string const& enumName, - std::vector const& enumValues, - SemanticConstraint constraint -) { - using namespace magic_enum::bitwise_operators; - if (ll::globalConfig.enableUnlockCmd && - magic_enum::enum_integer(constraint & SemanticConstraint::RequiresCheatsEnabled)) { - constraint = (SemanticConstraint)(constraint & (~SemanticConstraint::RequiresCheatsEnabled)); - constraint = (SemanticConstraint)(constraint | SemanticConstraint::RequiresElevatedPermissions); - } - // if (constraint & SemanticConstraint::RequiresHostPermissions) - //{ - // constraint = (SemanticConstraint)(constraint & (~SemanticConstraint::RequiresHostPermissions)); - // constraint = (SemanticConstraint)(constraint | SemanticConstraint::RequiresElevatedPermissions); - // } - return origin(enumName, enumValues, constraint); -} diff --git a/temp/core/ModifyInfomation.cpp b/temp/core/ModifyInfomation.cpp deleted file mode 100644 index f7aa8590ba..0000000000 --- a/temp/core/ModifyInfomation.cpp +++ /dev/null @@ -1,227 +0,0 @@ -#include "ll/api/LLAPI.h" -#include "ll/api/LoggerAPI.h" -#include "ll/api/ServerAPI.h" -#include "ll/api/memory/Hook.h" - -#include "ll/core/Config.h" -#include "ll/core/Version.h" -#include -#include - -using namespace std; -using namespace ll::memory; - -#define MI_HOOK_NAME(id) MiHook##id - -Logger serverLogger("Server"); -extern void checkBetaVersion(); -LL_AUTO_STATIC_HOOK( - MI_HOOK_NAME(1), - HookPriority::Normal, - "?getServerVersionString@Common@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ", - std::string, -) { - checkBetaVersion(); - return origin() + "(ProtocolVersion " + to_string(ll::getServerProtocolVersion()) + ") with " + - fmt::format( - ll::globalConfig.colorLog ? fg(fmt::color::light_sky_blue) | fmt::emphasis::bold | fmt::emphasis::italic - : fmt::text_style(), - "LeviLamina " LL_FILE_VERSION_STRING - ); -} - -string& replace_all_distinct(string& str, string const& old_value, string const& new_value) { - for (string::size_type pos(0); pos != string::npos; pos += new_value.length()) { - if ((pos = str.find(old_value, pos)) != string::npos) - str.replace(pos, old_value.length(), new_value); - else - break; - } - return str; -} - -LL_AUTO_STATIC_HOOK(MI_HOOK_NAME(2), HookPriority::Normal, "?BedrockLogOut@@YAXIPEBDZZ", void, int a1, char* a2, ...) { - char Buffer[4096]; - va_list va; - va_start(va, a2); - auto v1 = vsprintf(Buffer, a2, va); - va_end(va); - if (v1 < 0) - v1 = -1; - if (v1 < 0) - return origin(a1, a2, va); - string input = Buffer; - - - input.erase(std::remove(input.begin(), input.end(), '\n'), input.end()); - switch (a1) { - case 1u: - serverLogger.debug << input << Logger::endl; - return; - case 2u: - serverLogger.info << input << Logger::endl; - return; - case 4u: - serverLogger.warn << input << Logger::endl; - return; - case 8u: - serverLogger.error << input << Logger::endl; - return; - default: - serverLogger.info << input << Logger::endl; - return; - } - - return origin(a1, a2, va); -} - -// Standardize BDS's output -LL_AUTO_STATIC_HOOK( - MI_HOOK_NAME(3), - HookPriority::Normal, - "?PlatformBedrockLogOut@@YAXIPEBD@Z", - void, - int a1, - const char* ts -) { - string input = ts; - input.erase(std::remove(input.begin(), input.end(), '\n'), input.end()); - switch (a1) { - case 1u: - serverLogger.debug << input << Logger::endl; - break; - case 2u: - serverLogger.info << input << Logger::endl; - break; - case 4u: - serverLogger.warn << input << Logger::endl; - break; - case 8u: - serverLogger.error << input << Logger::endl; - break; - default: - serverLogger.info << input << Logger::endl; - break; - } -} - -// Block BDS from adding LOG metadata -LL_AUTO_STATIC_HOOK( - MI_HOOK_NAME(4), - HookPriority::Normal, - "?_appendLogEntryMetadata@LogDetails@BedrockLog@@AEAAXAEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@" - "std@@V34@W4LogAreaID@@I1HH@Z", - void, - void* a1, - void* a2, - void** a3, - int a4, - uint a5, - int64 a6, - uint a7, - uint a8 -) {} - -#include "ll/core/LeviLamina.h" -#include "mc/BedrockLog.hpp" -namespace ModifyInfomation { -int telemetryText = 0; -} -LL_AUTO_STATIC_HOOK( - MI_HOOK_NAME(5), - HookPriority::Normal, - "?log@BedrockLog@@YAXW4LogCategory@1@V?$bitset@$02@std@@W4LogRule@1@W4LogAreaID@@IPEBDH4ZZ", - void, - enum BedrockLog::LogCategory a1, - class std::bitset<3> a2, - enum BedrockLog::LogRule a3, - enum LogAreaID a4, - uint a5, - char const* a6, - int a7, - char const* a8, - ... -) { - va_list va; - auto text = (char*)a8; - va_start(va, a8); - if (string(text).find("= TELEMETRY MESSAGE =") != string(text).npos) { - ModifyInfomation::telemetryText = 6; - return BedrockLog::log_va( - a1, - a2, - a3, - a4, - a5, - a6, - a7, - "To enable Server Telemetry, add the line 'emit-server-telemetry=true' to the server.properties file in " - "the bds directory", - va - ); - } - if (ModifyInfomation::telemetryText > 0) { - ModifyInfomation::telemetryText--; - return; - } - - if (string(text).find("setting up server logging...") != string(text).npos || - string(text).find("Server started") != string(text).npos) { - return; - } - return BedrockLog::log_va(a1, a2, a3, a4, a5, a6, a7, a8, va); -} - -#include "mc/ColorFormat.hpp" -#include "mc/CommandOrigin.hpp" -#include "mc/CommandOutput.hpp" -extern std::unordered_map resultOfOrigin; -LL_AUTO_INSTANCE_HOOK( - MI_HOOK_NAME(6), - HookPriority::Normal, - "?send@CommandOutputSender@@UEAAXAEBVCommandOrigin@@AEBVCommandOutput@@@Z", - void*, - class CommandOrigin const& origin, - class CommandOutput const& output -) { - std::stringbuf tmpBuf; - auto oldBuf = std::cout.rdbuf(); - std::cout.rdbuf(&tmpBuf); - auto rv = this->origin(origin, output); - std::cout.rdbuf(oldBuf); - if (ll::isDebugMode() && ll::globalRuntimeConfig.tickThreadId != std::this_thread::get_id()) { - ll::logger.warn("The thread executing the CommandOutputSender::send is not the \"MC_SERVER\" thread"); - ll::logger.warn("Output: {}", tmpBuf.str()); - } - - auto it = resultOfOrigin.find(&origin); - if (it != resultOfOrigin.end()) { - try { - // May crash for incomprehensible reasons - it->second->assign(tmpBuf.str()); - while (it->second->size() && (it->second->back() == '\n' || it->second->back() == '\r')) - it->second->pop_back(); - it->second = nullptr; - resultOfOrigin.erase(it); - return rv; - } catch (...) { - if (ll::isDebugMode()) { - ll::logger.warn("Output: {}", tmpBuf.str()); - ll::logger.warn("size of resultOfOrigin: {}", resultOfOrigin.size()); - } -#ifdef DEBUG - __debugbreak(); -#endif // DEBUG - } - } - auto& log = output.getSuccessCount() > 0 ? serverLogger.info : serverLogger.error; - std::istringstream iss(tmpBuf.str()); - string line; - while (getline(iss, line)) { - if (ll::globalConfig.colorLog) - log << ColorFormat::convertToConsole(line, false) << Logger::endl; - else - log << ColorFormat::removeColorCode(line) << Logger::endl; - } - return rv; -} diff --git a/temp/scoreboard/ObjectiveAPI.cpp b/temp/scoreboard/ObjectiveAPI.cpp deleted file mode 100644 index 3274dc6b0c..0000000000 --- a/temp/scoreboard/ObjectiveAPI.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "ll/api/service/GlobalService.h" -#include "mc/Objective.hpp" -#include "mc/ServerScoreboard.hpp" - -#include "ll/api/utils/Hash.h" - -// helper -#define H do_hash -LLAPI bool checkSlotName(std::string const& slot) { - switch (H(slot.c_str())) { - case H("list"): - break; - case H("sidebar"): - break; - case H("belowname"): - break; - default: - return false; - } - return true; -} - -bool Objective::setDisplay(std::string const& slotName, ObjectiveSortOrder sort) { - if (checkSlotName(slotName)) { - ((ServerScoreboard*)Global)->setDisplayObjective(slotName, *this, sort); - return true; - } - return false; -} diff --git a/temp/scoreboard/ScoreboardAPI.cpp b/temp/scoreboard/ScoreboardAPI.cpp deleted file mode 100644 index 6f554536e6..0000000000 --- a/temp/scoreboard/ScoreboardAPI.cpp +++ /dev/null @@ -1,391 +0,0 @@ -#include "ll/api/PlayerInfoAPI.h" -#include "mc/CompoundTag.hpp" -#include "mc/DisplayObjective.hpp" -#include "mc/Level.hpp" -#include "mc/Objective.hpp" -#include "mc/ObjectiveCriteria.hpp" -#include "mc/Player.hpp" -#include "mc/PlayerScoreboardId.hpp" -#include "mc/Scoreboard.hpp" -#include "mc/ScoreboardId.hpp" -#include "mc/ScoreboardIdentityRef.hpp" -#include "mc/ServerScoreboard.hpp" -#include "mc/setScorePacket.hpp" - -#include "ll/api/memory/MemoryUtils.h" - -using ll::memory::dAccess; - -LLAPI ScoreboardId const& Scoreboard::nextScoreboardId() { return ++*(ScoreboardId*)((char*)this + 1072); } - -bool Scoreboard::createScoreboardId(PlayerScoreboardId const& pid) { - ScoreboardId newsid = nextScoreboardId(); - ScoreboardId* (Scoreboard::*rv)(ScoreboardId, PlayerScoreboardId const&) = nullptr; - *((void**)&rv) = - LL_RESOLVE_SYMBOL("??$_createScoreboardId@UPlayerScoreboardId@@@Scoreboard@@IEAAAEBUScoreboardId@@U1@" - "AEBUPlayerScoreboardId@@@Z"); - return (this->*rv)(newsid, pid)->isValid(); -} - -LLAPI bool Scoreboard::createScoreboardId(mce::UUID const& uuid) { - - auto cTag = Player::getPlayerNbt(uuid); - if (cTag != nullptr && !cTag->isEmpty() && cTag->contains("UniqueID")) { - ActorUniqueID aId(cTag->getInt64("UniqueID")); - PlayerScoreboardId myPid(aId); - // check - auto& maySid = this->getScoreboardId(myPid); - if (!maySid.isValid()) { - return this->createScoreboardId(myPid); - } - return true; - } - return false; -} - -LLAPI ScoreboardId Scoreboard::getScoreboardId(mce::UUID const& uuid) const { - auto cTag = Player::getPlayerNbt(uuid); - if (cTag != nullptr && !cTag->isEmpty() && cTag->contains("UniqueID")) { - ActorUniqueID aId(cTag->getInt64("UniqueID")); - PlayerScoreboardId myPid(aId); - return this->getScoreboardId(myPid); - } - return ScoreboardId::INVALID; -} - -LLAPI ScoreboardId Scoreboard::getOrCreateScoreboardId(mce::UUID const& uuid) { - ScoreboardId sId = Global->getScoreboardId(uuid); - if (!sId.isValid()) { - Global->createScoreboardId(uuid); - sId = Global->getScoreboardId(uuid); - } - return sId; -} - -LLAPI bool Scoreboard::forceModifyPlayerScore( - mce::UUID const& uuid, - std::string const& objname, - int val, - PlayerScoreSetFunction pf -) { - auto sId = Global->getOrCreateScoreboardId(uuid); - if (sId.isValid()) { - Objective* obj = Global->getObjective(objname); - if (!obj) - obj = Scoreboard::newObjective(objname, objname); - if (obj) { - bool ret; - Global->modifyPlayerScore(ret, sId, *obj, val, pf); - return ret; - } - } - return false; -} - -LLAPI bool -Scoreboard::forceModifyPlayerScore(xuid_t const& xuid, std::string const& objname, int val, PlayerScoreSetFunction pf) { - auto uuid = PlayerInfo::getUUIDByXuid(xuid); - if (!uuid.empty()) { - return Global->forceModifyPlayerScore(mce::UUID::fromString(uuid), objname, val, pf); - } - return false; -} - -LLAPI std::optional Scoreboard::queryPlayerScore(mce::UUID const& uuid, std::string const& objname) { - auto obj = Global->getObjective(objname); - auto sId = Global->getScoreboardId(uuid); - if (!obj || !sId.isValid() || !obj->hasScore(sId)) - return std::nullopt; - return obj->getPlayerScore(sId).getCount(); -} - -LLAPI std::optional Scoreboard::queryPlayerScore(xuid_t const& xuid, std::string const& objname) { - auto obj = Global->getObjective(objname); - auto uuid = PlayerInfo::getUUIDByXuid(xuid); - if (uuid.empty()) - return std::nullopt; - auto const& sId = Global->getScoreboardId(uuid); - if (!obj || !sId.isValid() || !obj->hasScore(sId)) - return std::nullopt; - return obj->getPlayerScore(sId).getCount(); -} - -LLAPI bool Scoreboard::forceRemovePlayerScoreFromObjective(mce::UUID const& uuid, std::string const& objname) { - - return removeFromObjective(objname, Global->getScoreboardId(uuid)); -} - -LLAPI bool Scoreboard::forceRemovePlayerScoreFromObjective(xuid_t const& xuid, std::string const& objname) { - auto uuid = PlayerInfo::getUUIDByXuid(xuid); - if (uuid.empty()) - return false; - return removeFromObjective(objname, Global->getScoreboardId(uuid)); -} - -LLAPI Objective* Scoreboard::newObjective(std::string const& objname, std::string const& displayName) { - std::string criteria = "dummy"; - return Global->addObjective(objname, displayName, *Global->getCriteria(criteria)); -} - -/* -LLAPI bool Scoreboard::setDisplayObjective(std::string const& objname, std::string const& slot, int sort) { - if (checkSlotName(slot)) { - auto obj = Global->getObjective(objname); - if (!obj) - return false; - ((ServerScoreboard*)Global)->setDisplayObjective(slot,*obj,(ObjectiveSortOrder)sort); - return true; - } - return false; -} - -LLAPI Objective* Scoreboard::clearDisplayObjective(std::string const& slot) { - if (checkSlotName(slot)) - return Global->clearDisplayObjective(slot); - return nullptr; -} - -LLAPI Objective* Scoreboard::getDisplayObjective(std::string const& slot) { - if (checkSlotName(slot)) { - auto disp = Global->getDisplayObjective(slot); - if (disp) - return const_cast(&disp->getObjective()); - } - return nullptr; -}*/ -LLAPI struct ScoreboardId& Scoreboard::getOrCreateScoreboardId(std::string const& id) { - auto& identity = const_cast(Global->getScoreboardId(id)); - if (!identity.isValid()) { - ((ServerScoreboard*)Global)->createScoreboardId(id); - } - return identity; -} - -LLAPI std::optional Scoreboard::addScore(std::string const& objname, std::string const& id, int score) { - auto obj = Global->getObjective(objname); - if (!obj) - return std::nullopt; - - auto& identity = getOrCreateScoreboardId(id); - - bool temp = true; - return Global->modifyPlayerScore(temp, identity, *obj, score, PlayerScoreSetFunction::Add); -} - -LLAPI std::optional Scoreboard::setScore(std::string const& objname, std::string const& id, int score) { - auto obj = Global->getObjective(objname); - if (!obj) - return std::nullopt; - - auto& identity = getOrCreateScoreboardId(id); - bool temp = true; - return Global->modifyPlayerScore(temp, identity, *obj, score, PlayerScoreSetFunction::Set); -} - -LLAPI std::optional Scoreboard::reduceScore(std::string const& objname, std::string const& id, int score) { - auto obj = Global->getObjective(objname); - if (!obj) - return std::nullopt; - - auto& identity = getOrCreateScoreboardId(id); - - bool temp = true; - return Global->modifyPlayerScore(temp, identity, *obj, score, PlayerScoreSetFunction::Remove); -} - -LLAPI bool Scoreboard::removeFromObjective(std::string const& objname, std::string const& id) { - auto& identity = const_cast(Global->getScoreboardId(id)); - if (!identity.isValid()) { - return true; - } - auto obj = Global->getObjective(objname); - if (!obj) { - return true; - } - return Global->getScoreboardIdentityRef(identity)->removeFromObjective(*Global, *obj); -} - -LLAPI bool Scoreboard::removeFromObjective(std::string const& objname, Player* player) { - auto& identity = const_cast(Global->getScoreboardId(*player)); - if (!identity.isValid()) - return true; - Objective* obj = Global->getObjective(objname); - if (!obj) - return true; - vector info; - ScorePacketInfo i( - (ScoreboardId*)&identity, - objname, - Global->getScoreboardIdentityRef(identity)->getIdentityType(), - obj->getPlayerScore(identity).getCount(), - obj->getName() - ); - info.emplace_back(i); - for (auto sp : Level::getAllPlayers()) { - sp->sendSetScorePacket(1, info); - } - auto out = Global->getScoreboardIdentityRef(identity)->removeFromObjective(*Global, *obj); - return out; -} - -LLAPI bool Scoreboard::removeFromObjective(std::string const& objname, ScoreboardId const& identity) { - if (!identity.isValid()) - return true; - Objective* obj = Global->getObjective(objname); - if (!obj) - return true; - vector info; - ScorePacketInfo i( - (ScoreboardId*)&identity, - objname, - Global->getScoreboardIdentityRef(identity)->getIdentityType(), - obj->getPlayerScore(identity).getCount(), - obj->getName() - ); - info.emplace_back(i); - for (auto sp : Level::getAllPlayers()) { - sp->sendSetScorePacket(1, info); - } - auto out = Global->getScoreboardIdentityRef(identity)->removeFromObjective(*Global, *obj); - return out; -} - -LLAPI int Scoreboard::getScore(std::string const& objname, std::string const& id) { - auto& identity = - const_cast(Global->getOrCreateScoreboardId(id) // If not exists, create a new one - ); - if (!identity.isValid()) { - throw std::runtime_error("Bad ScoreboardId"); - } - - auto obj = Global->getObjective(objname); - if (!obj) { - throw std::invalid_argument("Objective " + objname + " not found"); - } - - auto scores = Global->getIdScores(identity); -#ifdef DEBUG - struct voids { - void** filler[100]; - }; - - auto& vs = *(voids*&)scores; // -> sizeof(ScoreInfo) == 16 -#endif // DEBUG - for (auto& it : scores) { - if (it.getObjective() == obj) { - return it.getCount(); - } - } - throw std::runtime_error("Cannot get score"); -} - -LLAPI bool Scoreboard::getScore(std::string const& objname, std::string const& id, int& score) { - try { - score = getScore(objname, id); - return true; - } catch (...) { - } - return false; -} - -// For compatibility -LLAPI int Scoreboard::getScore(Player* player, std::string const& objname) { return getScore(objname, player); } - -LLAPI int Scoreboard::getScore(std::string const& objname, Player* player) { - Objective* obj = Global->getObjective(objname); - if (!obj) { - throw std::invalid_argument("Objective " + objname + " not found"); - } - - auto& identity = const_cast(Global->getScoreboardId(*player)); - if (!identity.isValid()) { - ((ServerScoreboard*)Global)->createScoreboardId(*player); - } - - auto score = obj->getPlayerScore(identity); - return score.getCount(); -} - -LLAPI bool Scoreboard::getScore(std::string const& objname, Player* player, int& score) { - try { - score = getScore(objname, player); - return true; - } catch (...) { - } - return false; -} - -// For compatibility -LLAPI bool Scoreboard::setScore(Player* player, std::string const& objname, int value) { - return setScore(objname, player, value); -} - -LLAPI bool Scoreboard::setScore(std::string const& objname, Player* player, int value) { - Objective* obj = Global->getObjective(objname); - if (!obj) { - return false; - } - - auto& identity = const_cast(Global->getScoreboardId(*player)); - if (!identity.isValid()) { - ((ServerScoreboard*)Global)->createScoreboardId(*player); - } - bool temp = true; - int result = Global->modifyPlayerScore(temp, identity, *obj, value, PlayerScoreSetFunction::Set); - if (result != value) { - return false; - } - return true; -} - -// For compatibility -LLAPI bool Scoreboard::addScore(Player* player, std::string const& objname, int value) { - return addScore(objname, player, value); -} - -LLAPI bool Scoreboard::addScore(std::string const& objname, Player* player, int value) { - Objective* obj = Global->getObjective(objname); - if (!obj) { - return false; - } - - auto& identity = const_cast(Global->getScoreboardId(*player)); - if (!identity.isValid()) { - ((ServerScoreboard*)Global)->createScoreboardId(*player); - return false; - } - bool temp = true; - Global->modifyPlayerScore(temp, identity, *obj, value, PlayerScoreSetFunction::Add); - return true; -} - -// For compatibility -LLAPI bool Scoreboard::reduceScore(Player* player, std::string const& objname, int value) { - return reduceScore(objname, player, value); -} - -LLAPI bool Scoreboard::reduceScore(std::string const& objname, Player* player, int value) { - Objective* obj = Global->getObjective(objname); - if (!obj) { - return false; - } - - bool a1 = true; - bool& pa = a1; - auto& identity = const_cast(Global->getScoreboardId(*player)); - if (!identity.isValid()) { - ((ServerScoreboard*)Global)->createScoreboardId(*player); - } - bool temp = true; - Global->modifyPlayerScore(temp, identity, *obj, value, PlayerScoreSetFunction::Remove); // Reduce - return true; -} - -// For compatibility -LLAPI bool Scoreboard::deleteScore(Player* player, std::string const& objname) { return deleteScore(objname, player); } - -LLAPI bool Scoreboard::deleteScore(std::string const& objname, Player* player) { - return removeFromObjective(objname, player); -} - -LLAPI bool Scoreboard::scoreboardIdIsValid(ScoreboardId* id) { return id->isValid(); }