diff --git a/LiteLoader/LiteLoader.aps b/LiteLoader/LiteLoader.aps index 5ae61b4f1c..0a9f259da9 100644 Binary files a/LiteLoader/LiteLoader.aps and b/LiteLoader/LiteLoader.aps differ diff --git a/LiteLoader/LiteLoader.cpp b/LiteLoader/LiteLoader.cpp index 227b4a315e..f7e9af0805 100644 --- a/LiteLoader/LiteLoader.cpp +++ b/LiteLoader/LiteLoader.cpp @@ -64,7 +64,6 @@ static void loadPlugins() { printf(info, plugins, LiteLoaderVersion); #endif } - static void entry(bool fixcwd) { loadPlugins(); } diff --git a/LiteLoader/LiteLoader.rc b/LiteLoader/LiteLoader.rc index 5cb8c38667..acd7fba9d6 100644 --- a/LiteLoader/LiteLoader.rc +++ b/LiteLoader/LiteLoader.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,1,4,0 - PRODUCTVERSION 0,1,4,0 + FILEVERSION 0,1,5,0 + PRODUCTVERSION 0,1,5,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -69,12 +69,12 @@ BEGIN BEGIN VALUE "CompanyName", "LiteLoaderDev" VALUE "FileDescription", "A lightweight Bedorck Dedicated Server Plugin Loader " - VALUE "FileVersion", "0.1.4.0" + VALUE "FileVersion", "0.1.5.0" VALUE "InternalName", "LiteLoad.dll" VALUE "LegalCopyright", "LiteLoader Developer" VALUE "OriginalFilename", "LiteLoad.dll" VALUE "ProductName", "LiteLoader For BDS" - VALUE "ProductVersion", "0.1.4.0" + VALUE "ProductVersion", "0.1.5.0" END END BLOCK "VarFileInfo" diff --git a/LiteLoader/LiteLoader.vcxproj b/LiteLoader/LiteLoader.vcxproj index d62203b01e..c3fa6f0a4f 100644 --- a/LiteLoader/LiteLoader.vcxproj +++ b/LiteLoader/LiteLoader.vcxproj @@ -158,6 +158,7 @@ + @@ -171,6 +172,8 @@ + + diff --git a/LiteLoader/LiteLoader.vcxproj.filters b/LiteLoader/LiteLoader.vcxproj.filters index 8b6a28e3a8..570f6b3c13 100644 --- a/LiteLoader/LiteLoader.vcxproj.filters +++ b/LiteLoader/LiteLoader.vcxproj.filters @@ -34,6 +34,9 @@ {2911c288-227a-404e-ae09-17b63cb54f34} + + {c56a4f7b-2ab1-43d8-8bec-c2499ff2849a} + @@ -156,6 +159,15 @@ 头文件 + + 头文件\mc\CommandReg + + + 头文件\mc\CommandReg + + + 头文件\api + diff --git a/LiteLoader/api/Basic_Event.cpp b/LiteLoader/api/Basic_Event.cpp index 4d39481c92..384470ffa6 100644 --- a/LiteLoader/api/Basic_Event.cpp +++ b/LiteLoader/api/Basic_Event.cpp @@ -79,14 +79,15 @@ Player* MakeSP(CommandOrigin& ori) { return 0; } -vector> PlayerUseCmdCallBacks; -LIAPI void Event::addEventListener(function callback) { +vector> PlayerUseCmdCallBacks; +LIAPI void Event::addEventListener(function callback) { PlayerUseCmdCallBacks.push_back(callback); } -THook(MCRESULT,"?executeCommand@MinecraftCommands@@QEBA?AUMCRESULT@@V?$shared_ptr@VCommandContext@@@std@@_N@Z", +THook(bool,"?executeCommand@MinecraftCommands@@QEBA?AUMCRESULT@@V?$shared_ptr@VCommandContext@@@std@@_N@Z", MinecraftCommands* _this, unsigned int* a2, std::shared_ptr x, char a4) { + Player* sp = MakeSP(x->getOrigin()); - MCRESULT result = original(_this, a2, x, a4); + bool result = original(_this, a2, x, a4); if (sp) { string cmd = x->getCmd(); if (cmd.at(0) == '/') { @@ -94,11 +95,31 @@ THook(MCRESULT,"?executeCommand@MinecraftCommands@@QEBA?AUMCRESULT@@V?$shared_pt } PlayerUseCmdEV PlayerUseCmdEV = { sp,cmd,result}; for (size_t count = 0; count < PlayerUseCmdCallBacks.size(); count++) { - PlayerUseCmdCallBacks[count](PlayerUseCmdEV); + bool ret = PlayerUseCmdCallBacks[count](PlayerUseCmdEV); + if (ret) + return true; } } return result; } +class BaseCommandBlock; +class BlockSource; + +vector> CmdBlockExeEVCallBacks; +LIAPI void Event::addEventListener(function callback) { + CmdBlockExeEVCallBacks.push_back(callback); +} +THook(bool, "?_performCommand@BaseCommandBlock@@AEAA_NAEAVBlockSource@@AEBVCommandOrigin@@AEA_N@Z", + BaseCommandBlock* _this, BlockSource* a2, CommandOrigin* a3, bool* a4) { + CmdBlockExeEV ev = { offBaseCommandBlock::getCMD(_this),offBaseCommandBlock::getPos(_this) }; + for (size_t count = 0; count < CmdBlockExeEVCallBacks.size(); count++) { + bool ret = CmdBlockExeEVCallBacks[count](ev); + if (ret) + return true; + } + return original(_this, a2, a3, a4); +} + vector> PlayerDeathCallBacks; LIAPI void Event::addEventListener(function callback) { diff --git a/LiteLoader/mc/ServiceLocator.cpp b/LiteLoader/mc/ServiceLocator.cpp index 9fa9e6df48..e6108cfefe 100644 --- a/LiteLoader/mc/ServiceLocator.cpp +++ b/LiteLoader/mc/ServiceLocator.cpp @@ -35,6 +35,22 @@ THook(void, "?startServerThread@ServerInstance@@QEAAXXZ", void* a) { } } +class CommandRegistry; +vector> RegCmdEVCallBacks; +LIAPI void Event::addEventListener(function callback) { + RegCmdEVCallBacks.push_back(callback); +} +THook(void, "?setup@ChangeSettingCommand@@SAXAEAVCommandRegistry@@@Z", CommandRegistry* rg, void* a1) { + LocateS::assign(*rg); + original(rg, a1); + cout << "[LiteLoader] Registering cmds" << endl; + RegCmdEV cmdregev = {rg}; + for (size_t count = 0; count < RegCmdEVCallBacks.size(); count++) { + RegCmdEVCallBacks[count](cmdregev); + } +} + + //?initCoreEnums@MinecraftCommands@@QEAAX_NAEBVBaseGameVersion@@@Z THook(void, "?initCoreEnums@MinecraftCommands@@QEAAXAEBVIWorldRegistriesProvider@@AEBVActorFactory@@AEBVExperiments@@AEBVBaseGameVersion@@@Z", MinecraftCommands* a0, void* a1, void* a2, void*a3, void*a4) { original(a0, a1, a2, a3, a4); diff --git a/headers/api/Basic_Event.h b/headers/api/Basic_Event.h index 93c24b9974..9610b8ab5e 100644 --- a/headers/api/Basic_Event.h +++ b/headers/api/Basic_Event.h @@ -39,6 +39,12 @@ class PlayerUseCmdEV { MCRESULT mc_result; }; +class CmdBlockExeEV { +public: + string cmd; + BlockPos bpos; +}; + class ServerStartedEV { }; @@ -48,12 +54,20 @@ class PlayerDeathEV { ServerPlayer* Player; }; +class CommandRegistry; +class RegCmdEV { +public: + CommandRegistry* CMDRg; +}; + namespace Event { LIAPI void addEventListener(function callback); LIAPI void addEventListener(function callback); LIAPI void addEventListener(function callback); LIAPI void addEventListener(function callback); LIAPI void addEventListener(function callback); - LIAPI void addEventListener(function callback); + LIAPI void addEventListener(function callback); + LIAPI void addEventListener(function callback); + LIAPI void addEventListener(function callback); LIAPI void addEventListener(function callback); }; \ No newline at end of file diff --git a/headers/api/commands.h b/headers/api/commands.h new file mode 100644 index 0000000000..495a6b13d3 --- /dev/null +++ b/headers/api/commands.h @@ -0,0 +1,224 @@ +#pragma once +#include +#include +#include +CommandRegistry* CmdRegGlobal = nullptr; +namespace CMDREG { + inline void SetCommandRegistry(CommandRegistry* reg) { + CmdRegGlobal = reg; + } + template + inline typeid_t getTPID(); + inline typeid_t& GETID(const char* name) { + return *(typeid_t*)(dlsym_real(name)); + } + inline typeid_t ALLOCID() { + auto& id = *((unsigned short*)SYM("?count@?$typeid_t@VCommandRegistry@@@@2GA")); + return { id++ }; + } + template <> + inline typeid_t getTPID() { + return GETID("?id@?1???$type_id@VCommandRegistry@@VCommandMessage@@@@YA?AV?$typeid_t@VCommandRegistry@@@@XZ@4V1@A"); + } + template <> + inline typeid_t getTPID() { + return GETID("?id@?1???$type_id@VCommandRegistry@@_N@@YA?AV?$typeid_t@VCommandRegistry@@@@XZ@4V1@A"); + } + template <> + inline typeid_t getTPID() { + return GETID("?id@?1???$type_id@VCommandRegistry@@H@@YA?AV?$typeid_t@VCommandRegistry@@@@XZ@4V1@A"); + } + template <> + inline typeid_t getTPID() { + return GETID("?id@?1???$type_id@VCommandRegistry@@M@@YA?AV?$typeid_t@VCommandRegistry@@@@XZ@4V1@A"); + } + template <> + inline typeid_t getTPID() { + return GETID( + "?id@?1???$type_id@VCommandRegistry@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@YA?AV?$" + "typeid_t@VCommandRegistry@@@@XZ@4V1@A"); + } + template <> + inline typeid_t getTPID>() { + return GETID( + "?id@?1???$type_id@VCommandRegistry@@V?$CommandSelector@VActor@@@@@@YA?AV?$typeid_t@VCommandRegistry@@@@XZ@4V1@" + "A"); + } + template <> + inline typeid_t getTPID>() { + return GETID( + "?id@?1???$type_id@VCommandRegistry@@V?$CommandSelector@VPlayer@@@@@@YA?AV?$typeid_t@VCommandRegistry@@@@XZ@4V1@" + "A"); + } + template + class CEnum { + public: + static typeid_t myid; + static string name; + CEnum(string const& nam, std::initializer_list const& values) { + name = nam; + if (myid.value == 65535) { + myid = ALLOCID(); + if (CmdRegGlobal == nullptr) { + std::cout << "CmdRegGlobal Not Set" << endl; + exit(1); + } + CmdRegGlobal->addEnumValues(name, myid, values); + } + } + }; + template + typeid_t CEnum::myid(65535); + template + string CEnum::name; + + struct IMyEnum {}; + + + template + struct MyEnum : IMyEnum { + E val; + operator E() { + return val; + } + }; + + static inline void MakeCommand(string const& name, const char* desc, int lvl) { + std::cout << "RegisteringCommand > " << name << endl; + if (CmdRegGlobal == nullptr) { + std::cout << "CmdRegGlobal Not Set" << endl; + exit(1); + } + SymCall("?registerCommand@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDW4CommandPermissionLevel@@UCommandFlag@@3@Z", + void, void*, std::string const&, char const*, char, char, char) + (CmdRegGlobal, name, desc, lvl, 0, 0x40); + } + + template + typeid_t typeid_getter() { + if constexpr (std::is_base_of_v) { + return CEnum::myid; + } + else { + if constexpr (std::is_base_of_v) { + return typeid_getter(); + } + else { + return getTPID(); + } + } + } + template + struct MakeOverload { + using container = std::tuple>...>; + class sub : public Command { + public: + container data; + static uintptr_t cb; + template + inline bool invoke_impl(CommandOrigin const& a, CommandOutput& b, std::index_sequence) { + return ((bool (*)(CommandOrigin const&, CommandOutput&, TP...))cb)(a, b, std::get(data)...); + } + void execute(CommandOrigin const& a, CommandOutput& b) { + constexpr auto size = std::tuple_size::value; + try { + if (invoke_impl(a, b, std::make_index_sequence{})) { + //b.success(string("Success")); + } + + } + catch (std::exception e) { + //b.error(I18N::CMD_EXCEPTION+e.what()); + } + catch (string e) { + //b.error(I18N::CMD_EXCEPTION+e); + } + catch (...) { + //b.error(I18N::CMD_EXCEPTION); + } + } + sub() {} + }; + static void(*new_cb)(container&); + template + inline void reg_impl_sub(uintptr_t off, string const& desc, std::vector& vc) { + off += offsetof(sub, data); + if constexpr (std::is_base_of_v) { + using TXX = typename TX::Tval; + if constexpr (std::is_base_of_v) { + vc.emplace_back(typeid_getter(), &CommandRegistry::parseEnumInt, desc, CommandParameterDataType::ENUM, CEnum::name.c_str(), int(off + offsetof(TX, filler) + offsetof(TXX, val)), true, int(off + offsetof(TX, set))); + } + else { + vc.emplace_back(typeid_getter(), CommandRegistry::getParseFn(), desc, CommandParameterDataType::NORMAL, nullptr, int(off + offsetof(TX, filler)), true, int(off + offsetof(TX, set))); + } + } + else { + if constexpr (std::is_base_of_v) { + vc.emplace_back(typeid_getter(), &CommandRegistry::parseEnumInt, desc, CommandParameterDataType::ENUM, CEnum::name.c_str(), int(off + offsetof(TX, val)), false, -1); + } + else { + vc.emplace_back(typeid_getter(), CommandRegistry::getParseFn(), desc, CommandParameterDataType::NORMAL, nullptr, int(off), false, -1); + } + } + } + template + inline void reg_helper(std::vector& vc, + std::vector& argn, std::index_sequence) { + container& cter = *(container*)0; + (reg_impl_sub(cter))>>>((uintptr_t)std::addressof(std::get(cter)) - (uintptr_t)std::addressof(cter), argn[Index], vc), ...); + } + inline void regMe(string const& cname, std::vector&& vc) { + if (CmdRegGlobal == nullptr) { + std::cout << "CmdRegGlobal Not Set" << endl; + exit(1); + } + CmdRegGlobal->registerOverload(cname, &factory, std::forward< std::vector>(vc)); + } + template + MakeOverload(Dummy*, void(*_new_cb)(container&), string const& cname, bool (*__cb)(CommandOrigin const&, CommandOutput&, TP...), TP2... argns) { + static_assert(sizeof...(TP2) == sizeof...(TP), "every command arg should have a description"); + new_cb = _new_cb; + sub::cb = (decltype(sub::cb))__cb; + std::vector vc; + std::vector argn; + (argn.emplace_back(argns), ...); + constexpr auto size = std::tuple_size::value; + reg_helper(vc, argn, std::make_index_sequence{}); + regMe(cname, std::move(vc)); + } + template + inline MakeOverload(Dummy*, string const& cname, bool (*__cb)(CommandOrigin const&, CommandOutput&, TP...), TP2... argns) { + static_assert(sizeof...(TP2) == sizeof...(TP), "every command arg should have a description"); + sub::cb = (decltype(sub::cb))__cb; + std::vector vc; + std::vector argn; + (argn.emplace_back(argns), ...); + constexpr auto size = std::tuple_size::value; + reg_helper(vc, argn, std::make_index_sequence{}); + regMe(cname, std::move(vc)); + } + static std::unique_ptr factory() { + auto rv = std::make_unique(); + if (new_cb) + new_cb(rv->data); + return rv; + } + }; + template + uintptr_t MakeOverload::sub::cb; + template < typename Dummy, typename... TP> + void(*MakeOverload::new_cb)(std::tuple>...>&) = nullptr; +}; +using CMDREG::CEnum, CMDREG::MakeCommand, CMDREG::MakeOverload, CMDREG::MyEnum; +static_assert(sizeof(MakeOverload) == 1); +#define CmdOverload( name2, cb, ...) \ + { MakeOverload __ov1((struct name2*)0, string(#name2), cb, __VA_ARGS__); } +#define CmdOverload2(name2, cb, cb2, ...) \ + { MakeOverload __ov2((struct name2*)0, cb2, #name2, cb, __VA_ARGS__); } +#include +inline static ServerPlayer* MakeSP(CommandOrigin const& ori) { + if (ori.getOriginType() == OriginType::Player) { + return { (ServerPlayer*)ori.getEntity() }; + } + return nullptr; +} \ No newline at end of file diff --git a/headers/liteloader.h b/headers/liteloader.h index dfdc722990..72308e0aee 100644 --- a/headers/liteloader.h +++ b/headers/liteloader.h @@ -1,4 +1,4 @@ #pragma once #define LIAPI __declspec(dllexport) typedef unsigned char uchar; -#define LiteLoaderVersion "0.1.4" \ No newline at end of file +#define LiteLoaderVersion "0.1.5" \ No newline at end of file diff --git a/headers/mc/Command/Command.h b/headers/mc/Command/Command.h index 9210f59ab0..2fe92c1098 100644 --- a/headers/mc/Command/Command.h +++ b/headers/mc/Command/Command.h @@ -1,13 +1,26 @@ #pragma once -#include +#include +#include +#include +#include +#include +#include +#include +#include //MC_COMMAND_EXTRA class CommandRegistry; class CommandOrigin; class CommandOutput; class Actor; class Player; -enum CommandPermissionLevel : char; - +//enum CommandPermissionLevel : char; +enum CommandPermissionLevel :char { + Normal = 0, + Privileged = 1, + AutomationPlayer = 2, + OperatorOnly = 3, + ConsoleOnly = 4 +}; template class CommandSelectorResults; @@ -39,7 +52,7 @@ class CommandOutputParameter { __declspec(dllimport) CommandOutputParameter(std::vector const&); __declspec(dllimport) CommandOutputParameter(std::vector const&); */ - inline CommandOutputParameter(std::string str, int type) : str(str), type(type) {} + MCINLINE CommandOutputParameter(std::string str, int type) : str(str), type(type) {} }; class CommandOutput { public: @@ -57,7 +70,7 @@ class CommandOutput { void addMessage( std::string const& str) { - SymCall("?addMessage@CommandOutput@@AEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV?$vector@VCommandOutputParameter@@V?$allocator@VCommandOutputParameter@@@std@@@3@W4CommandOutputMessageType@@@Z", void, void*, string const&, std::vector const&, int)(this, str, {}, 0); + SymCall("?addMessage@CommandOutput@@AEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV?$vector@VCommandOutputParameter@@V?$allocator@VCommandOutputParameter@@@std@@@3@W4CommandOutputMessageType@@@Z", void, void*, std::string const&, std::vector const&, int)(this, str, {}, 0); } }; @@ -129,7 +142,7 @@ class HashedString { *((void**)&rv) = dlsym("??9HashedString@@QEBA_NAEBV0@@Z"); return (this->*rv)(a0); } - inline HashedString(const char* ch) { + MCINLINE HashedString(const char* ch) { str = ch; hash = computeHash(ch); } @@ -143,16 +156,16 @@ struct ActorDefinitionIdentifier { HashedString canonicalHash; // 128 - inline HashedString const& getCanonicalHash() const { return canonicalHash; } - inline std::string const& getCanonicalName() const { return canonicalHash.getString(); } - inline std::string const& getFullName() const { return fullname; } - inline std::string const& getIdentifier() const { return identifier; } - inline std::string const& getInitEvent() const { return event; } - inline std::string const& getNamespace() const { return ns; } - inline bool isEmpty() const { return ns.empty() && identifier.empty(); } - inline bool isVanilla() const { return ns == "minecraft"; } - inline void setIdentifier(std::string const& id) { identifier = id; } - inline void setInitEvent(std::string const& e) { event = e; } + MCINLINE HashedString const& getCanonicalHash() const { return canonicalHash; } + MCINLINE std::string const& getCanonicalName() const { return canonicalHash.getString(); } + MCINLINE std::string const& getFullName() const { return fullname; } + MCINLINE std::string const& getIdentifier() const { return identifier; } + MCINLINE std::string const& getInitEvent() const { return event; } + MCINLINE std::string const& getNamespace() const { return ns; } + MCINLINE bool isEmpty() const { return ns.empty() && identifier.empty(); } + MCINLINE bool isVanilla() const { return ns == "minecraft"; } + MCINLINE void setIdentifier(std::string const& id) { identifier = id; } + MCINLINE void setInitEvent(std::string const& e) { event = e; } MCINLINE void initialize(class std::basic_string, class std::allocator> const& a0, class std::basic_string, class std::allocator> const& a1, class std::basic_string, class std::allocator> const& a2) { void (ActorDefinitionIdentifier::*rv)(class std::basic_string, class std::allocator> const&, class std::basic_string, class std::allocator> const&, class std::basic_string, class std::allocator> const&); @@ -176,33 +189,15 @@ struct InvertableFilter { }; class CommandSelectorBase { public: - uint32_t version; // 0 - uint32_t type; // 4 - uint32_t order; // 8 - std::vector> namefilters; // 16 - std::vector> typefilter2; // 40 - std::vector> tagfilters; // 64 - std::vector> customfilters; // 88 - char position[16]; // 112 - BlockPos box; // 128 - float radiusMin; // 140 - float radiusMax; // 144 = 0x7f7fffff (float max) - uint64_t resultCount; // 152 = 0xFFFFFFFF - bool includeDeadPlayers; // 160 - bool flag161; // 161 - bool flag162; // 162 - bool flag163; // 163 - bool playerOnly; // 164 - bool explicitIdSelector; // 165 - + void* filler[192 / 8]; #ifdef MC_COMMAND_EXTRA - inline bool isExplicitIdSelector() const { return explicitIdSelector; } - inline void addNameFilter(InvertableFilter const& filter) { namefilters.emplace_back(filter); } - inline void addTagFilter(InvertableFilter const& filter) { + MCINLINE bool isExplicitIdSelector() const { return explicitIdSelector; } + MCINLINE void addNameFilter(InvertableFilter const& filter) { namefilters.emplace_back(filter); } + MCINLINE void addTagFilter(InvertableFilter const& filter) { if (isExplicitIdSelector()) explicitIdSelector = false; tagfilters.emplace_back(filter); - inline void setResultCount(uint64_t value) { resultCount = value; } + MCINLINE void setResultCount(uint64_t value) { resultCount = value; } MCINLINE void addTypeFilter(struct InvertableFilter, class std::allocator>> const& a0) { void (CommandSelectorBase::*rv)(struct InvertableFilter, class std::allocator>> const&); *((void**)&rv) = dlsym("?addTypeFilter@CommandSelectorBase@@QEAAXAEBU?$InvertableFilter@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@@Z"); @@ -245,19 +240,20 @@ class CommandSelectorBase { } } #endif - inline void setIncludeDeadPlayers(bool value) { includeDeadPlayers = value; } - + MCINLINE ~CommandSelectorBase() { + SymCall("??1CommandSelectorBase@@QEAA@XZ", void, void*)(this); + } //CommandSelectorBase() {} protected: CommandSelectorBase(bool isPlayer) { SymCall("??0CommandSelectorBase@@IEAA@_N@Z", void, void*, bool)(this, isPlayer); } }; -static_assert(offsetof(CommandSelectorBase, explicitIdSelector) == 165); +//static_assert(offsetof(CommandSelectorBase, explicitIdSelector) == 165); template class CommandSelector : public CommandSelectorBase { public: - inline CommandSelector() : CommandSelectorBase(std::is_same_v) {} + MCINLINE CommandSelector() : CommandSelectorBase(std::is_same_v) {} CommandSelectorResults results(CommandOrigin const& a0) { CommandSelectorResults (CommandSelector::*rv)(CommandOrigin const& a0); if constexpr (std::is_same_v) { diff --git a/headers/mc/Command/CommandReg.h b/headers/mc/Command/CommandReg.h index 2ae3384e6e..7123ba54a7 100644 --- a/headers/mc/Command/CommandReg.h +++ b/headers/mc/Command/CommandReg.h @@ -1,11 +1,12 @@ #pragma once #include "Command.h" -#include +#include +#include class CommandMessage { char filler[32]; public: string get(CommandOrigin const& x) { - string (CommandMessage::*rv)(CommandOrigin const&); + string(CommandMessage:: * rv)(CommandOrigin const&); *(void**)&rv = SYM("?getMessage@CommandMessage@@QEBA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBVCommandOrigin@@@Z"); return (this->*rv)(x); } @@ -13,7 +14,7 @@ class CommandMessage { static std::unordered_map parse_ptr = { { typeid(CommandMessage).name(), dlsym_real("??$parse@VCommandMessage@@@CommandRegistry@@AEBA_NPEAXAEBUParseToken@0@AEBVCommandOrigin@@HAEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEAV?$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@@4@@Z") } - , + , { typeid(std::string).name(),dlsym_real("??$parse@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@CommandRegistry@@AEBA_NPEAXAEBUParseToken@0@AEBVCommandOrigin@@HAEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEAV?$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@@4@@Z")}, { typeid(bool).name(), dlsym_real("??$parse@_N@CommandRegistry@@AEBA_NPEAXAEBUParseToken@0@AEBVCommandOrigin@@HAEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEAV?$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@@4@@Z") }, { typeid(float).name(), dlsym_real("??$parse@M@CommandRegistry@@AEBA_NPEAXAEBUParseToken@0@AEBVCommandOrigin@@HAEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEAV?$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@@4@@Z") }, @@ -29,17 +30,11 @@ class typeid_t { typeid_t(typeid_t const& id) : value(id.value) {} typeid_t(unsigned short value) : value(value) {} }; -enum CommandPermissionLevel:char { - Normal = 0, - Privileged = 1, - AutomationPlayer = 2, - OperatorOnly = 3, - ConsoleOnly = 4 -}; + class CommandVersion { public: - int Min=1, Max=0x7FFFFFFF; + int Min = 1, Max = 0x7FFFFFFF; //inline CommandVersion() : min(1), max(0x7FFFFFFF) {} //inline CommandVersion(int min, int max) : min(min), max(max) {} }; @@ -63,7 +58,7 @@ class Command { virtual void execute(CommandOrigin const&, CommandOutput&) = 0; template static bool checkHasTargets(CommandSelectorResults const& a, CommandOutput& b) { - bool (*sym)(CommandSelectorResults const& a, CommandOutput& b); + bool (*sym)(CommandSelectorResults const& a, CommandOutput & b); if constexpr (std::is_same()) { sym = (decltype(sym))dlsym("??$checkHasTargets@VActor@@@Command@@KA_NAEBV?$CommandSelectorResults@VActor@@@@AEAVCommandOutput@@@Z"); } @@ -73,9 +68,11 @@ class Command { return sym(a, b); } }; -enum class CommandParameterDataType { NORMAL, +enum class CommandParameterDataType { + NORMAL, ENUM, - SOFT_ENUM }; + SOFT_ENUM +}; class CommandRegistry; struct CommandParameterData; class CommandRegistry { @@ -87,7 +84,7 @@ class CommandRegistry { unsigned val; }; struct Overload { - using FactoryFn = std::unique_ptr (*)(void); + using FactoryFn = std::unique_ptr(*)(void); CommandVersion version; // 0 FactoryFn factory; // 8 std::vector params; // 16 @@ -119,27 +116,30 @@ class CommandRegistry { std::vector list; // 32 }; #pragma endregion struct definition - + /* MCINLINE void registerCommand( std::string const& a, char const* b, CommandPermissionLevel c, CommandFlag d, CommandFlag e) { - SymCall("?registerCommand@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDW4CommandPermissionLevel@@UCommandFlag@@3@Z", void, void*, std::string const&, char const*, CommandPermissionLevel, CommandFlag, CommandFlag)(this, a, b, c, d, e); - } + SymCall("?registerCommand@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDW4CommandPermissionLevel@@UCommandFlag@@3@Z", + void, void*, std::string const&, char const*, char, char, char) + (this, string("test"), "testcmd", 0, 0, 0x40); + //SymCall("?registerCommand@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDW4CommandPermissionLevel@@UCommandFlag@@3@Z", void, void*, std::string const&, char const*, char, char, char)(this, a, b, 0, 0, 0); + }*/ MCINLINE void registerAlias(std::string const& a, std::string const& b) { SymCall("?registerAlias@CommandRegistry@@QEAAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z", void, void*, std::string const&, std::string const&)(this, a, b); } MCINLINE Signature* findCommand(class std::basic_string, class std::allocator> const& a0) { - Signature* (CommandRegistry::*rv)(class std::basic_string, class std::allocator> const&); + Signature* (CommandRegistry:: * rv)(class std::basic_string, class std::allocator> const&); *((void**)&rv) = dlsym_real("?findCommand@CommandRegistry@@AEAAPEAUSignature@1@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z"); return (this->*rv)(a0); } MCINLINE void registerOverloadInternal(struct CommandRegistry::Signature& a0, struct CommandRegistry::Overload& a1) { - void (CommandRegistry::*rv)(struct CommandRegistry::Signature&, struct CommandRegistry::Overload&); + void (CommandRegistry:: * rv)(struct CommandRegistry::Signature&, struct CommandRegistry::Overload&); *((void**)&rv) = dlsym_real("?registerOverloadInternal@CommandRegistry@@AEAAXAEAUSignature@1@AEAUOverload@1@@Z"); return (this->*rv)(a0, a1); } Symbol addEnumValuesInternal( std::string const& a0, std::vector> const& a1, typeid_t a2, - bool (CommandRegistry::*a3)( + bool (CommandRegistry::* a3)( void*, CommandRegistry::ParseToken const&, CommandOrigin const&, int, std::string&, std::vector&) const) { decltype(&CommandRegistry::addEnumValuesInternal) rv; @@ -147,7 +147,7 @@ class CommandRegistry { return (this->*rv)(a0, a1, a2, a3); } MCINLINE unsigned __int64 getEnumData(struct CommandRegistry::ParseToken const& a0) const { - unsigned __int64 (CommandRegistry::*rv)(struct CommandRegistry::ParseToken const&) const; + unsigned __int64 (CommandRegistry:: * rv)(struct CommandRegistry::ParseToken const&) const; *((void**)&rv) = dlsym("?getEnumData@CommandRegistry@@AEBA_KAEBUParseToken@1@@Z"); return (this->*rv)(a0); } @@ -168,7 +168,7 @@ class CommandRegistry { template bool - fakeparse(void*, ParseToken const&, CommandOrigin const&, int, std::string&, std::vector&) const { + fakeparse(void*, ParseToken const&, CommandOrigin const&, int, std::string&, std::vector&) const { return false; } bool parseEnumInt( @@ -191,8 +191,8 @@ class CommandRegistry { std::string const& name, Overload::FactoryFn factory, std::vector&& args) { Signature* signature = const_cast(findCommand(name)); if (!signature) { - printf("no command found %s", name.c_str()); - exit(0); + printf("no command found %s", name.c_str()); + exit(0); } auto& overload = signature->overloads.emplace_back(CommandVersion{}, factory, std::forward>(args)); registerOverloadInternal(*signature, overload); @@ -218,7 +218,7 @@ struct CommandParameterData { typeid_t tid, ParseFn parser, std::string_view desc_, CommandParameterDataType type, char const* enumname, int offset, bool optional, int flag_offset) : tid(tid), parser(parser), name(desc_), desc(enumname), unk56(-1), type(type), offset(offset), - flag_offset(flag_offset), mand(optional), pad73(false) {} + flag_offset(flag_offset), mand(optional), pad73(false) {} }; static_assert(offsetof(CommandParameterData, pad73) == 73); static_assert(offsetof(CommandParameterData, name) == 16); diff --git a/headers/mc/OffsetHelper.h b/headers/mc/OffsetHelper.h index 79d49d7230..aa5c07c53f 100644 --- a/headers/mc/OffsetHelper.h +++ b/headers/mc/OffsetHelper.h @@ -4,6 +4,7 @@ class Player; class Level; class Certificate; +class BaseCommandBlock; typedef unsigned long long xuid_t; namespace offPlayer { inline Certificate* getCert(Player* pl) { @@ -22,3 +23,11 @@ namespace offPlayer { return SymCall("?getIdentityName@ExtendedCertificate@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBVCertificate@@@Z", string, void*)(offPlayer::getCert((Player*)pl)); } }; +namespace offBaseCommandBlock { + inline string getCMD(BaseCommandBlock* bcmdblock) { + return dAccess(bcmdblock); + } + inline BlockPos getPos(BaseCommandBlock* bcmdblock) { + return dAccess(bcmdblock); + } +}; \ No newline at end of file