From f253c4788ac2afaa7fb9622d8db3706a1d2a9b8f Mon Sep 17 00:00:00 2001 From: twoone3l <3197653242@qq.com> Date: Wed, 11 Aug 2021 10:38:11 +0800 Subject: [PATCH] =?UTF-8?q?1.6.6=E6=9B=B4=E6=96=B0=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E5=A4=8DPlayer::getEntityTypeId=E4=B8=8D=E8=BF=94=E5=9B=9E319?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E6=96=B0=E5=A2=9E=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E6=B3=A8=E5=86=8C=E5=9B=9E=E8=B0=83=EF=BC=8Cwiki?= =?UTF-8?q?=E5=B0=86=E9=87=8D=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/msbuild.yml | 2 +- BDSpyrunner/BDSpyrunner.vcxproj | 10 ++--- BDSpyrunner/BDSpyrunner.vcxproj.user | 4 +- BDSpyrunner/mod.cpp | 67 ++++++++++++++++++++-------- BDSpyrunner/pch.h | 24 +++++++--- 5 files changed, 76 insertions(+), 31 deletions(-) diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index ed1e20d9..0a854612 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -23,4 +23,4 @@ jobs: - name: Release uses: softprops/action-gh-release@v0.1.7 with: - files: ../test/bdxcore_mod/* \ No newline at end of file + files: ../BDS/bdxcore_mod/* \ No newline at end of file diff --git a/BDSpyrunner/BDSpyrunner.vcxproj b/BDSpyrunner/BDSpyrunner.vcxproj index 59a96e1d..e5c15fd2 100644 --- a/BDSpyrunner/BDSpyrunner.vcxproj +++ b/BDSpyrunner/BDSpyrunner.vcxproj @@ -47,28 +47,28 @@ DynamicLibrary true - v142 + v143 Unicode DynamicLibrary false - v142 + v143 true Unicode DynamicLibrary true - v142 + v143 Unicode DynamicLibrary false - v142 true Unicode + v142 @@ -104,7 +104,7 @@ false - ..\..\test\bdxcore_mod\ + ..\..\BDS\bdxcore_mod\ $(Configuration)\ diff --git a/BDSpyrunner/BDSpyrunner.vcxproj.user b/BDSpyrunner/BDSpyrunner.vcxproj.user index 1666a200..0294bfcd 100644 --- a/BDSpyrunner/BDSpyrunner.vcxproj.user +++ b/BDSpyrunner/BDSpyrunner.vcxproj.user @@ -9,8 +9,8 @@ ..\..\test - C:\Users\Administrator\Desktop\test\bedrock_server.exe + C:\Users\Administrator\Desktop\BDS\bedrock_server.exe WindowsLocalDebugger - ..\..\test + C:\Users\Administrator\Desktop\BDS\ \ No newline at end of file diff --git a/BDSpyrunner/mod.cpp b/BDSpyrunner/mod.cpp index 171c265d..983f3dff 100644 --- a/BDSpyrunner/mod.cpp +++ b/BDSpyrunner/mod.cpp @@ -2,12 +2,13 @@ #define PY_SSIZE_T_CLEAN #include "include/Python.h" -#define VERSION_STRING "1.6.5" -#define VERSION_NUMBER 205 +#define VERSION_STRING "1.6.6" +#define VERSION_NUMBER 206 #define PLUGIN_PATH "plugins/py" #define MODULE_NAME "mc" #define Py_RETURN_ERROR(str) return PyErr_SetString(PyExc_Exception, str), nullptr +static_assert(sizeof(Actor) == 1); #pragma region EventCode enum class EventCode { None, @@ -123,7 +124,7 @@ static Scoreboard* _scoreboard = nullptr; //Py函数表 static unordered_map> _functions; //注册命令 -static vector> _commands; +static unordered_map> _commands; //伤害 static int _damage; } @@ -183,17 +184,11 @@ static void safeCall(const function& fn) { static bool EventCallBack(EventCode e, PyObject* val) { bool result = true; safeCall([&] { - vector& List = _functions[e]; - if (!List.empty()) { - for (PyObject* fn : List) { - //if (val) { + vector& list = _functions[e]; + if (!list.empty()) { + for (PyObject* fn : list) { if (PyObject_CallFunction(fn, "O", val) == Py_False) result = false; - //} - //else { - // if (_PyObject_CallNoArg(fn) == Py_False) - // result = false; - //} PyErr_Print(); } } @@ -428,6 +423,16 @@ static PyObject* PyEntity_GetHealth(PyObject* self, void*) { return nullptr; return PyLong_FromLong(a->getHealth()); } +static int PyEntity_SetHealth(PyObject* self, PyObject* arg, void*) { + if (PyLong_Check(arg)) { + Actor* a = PyEntity_AsActor(self); + if (!a) + return -1; + a->setHealth(PyLong_AsLong(arg)); + return 0; + } + return PyErr_BadArgument(), -1; +} //获取最大生命值 static PyObject* PyEntity_GetMaxHealth(PyObject* self, void*) { Actor* a = PyEntity_AsActor(self); @@ -435,6 +440,16 @@ static PyObject* PyEntity_GetMaxHealth(PyObject* self, void*) { return nullptr; return PyLong_FromLong(a->getMaxHealth()); } +static int PyEntity_SetMaxHealth(PyObject* self, PyObject* arg, void*) { + if (PyLong_Check(arg)) { + Actor* a = PyEntity_AsActor(self); + if (!a) + return -1; + a->setMaxHealth(PyLong_AsLong(arg)); + return 0; + } + return PyErr_BadArgument(), -1; +} //获取权限 static PyObject* PyEntity_GetPermissions(PyObject* self, void*) { Player* p = PyEntity_AsPlayer(self); @@ -488,8 +503,8 @@ static PyGetSetDef PyEntity_GetSet[]{ {"typeid", PyEntity_GetTypeID, nullptr, nullptr}, {"typename", PyEntity_GetTypeName, nullptr, nullptr}, {"nbt", PyEntity_GetNBTInfo, nullptr, nullptr}, - {"health", PyEntity_GetHealth, nullptr, nullptr}, - {"maxhealth", PyEntity_GetMaxHealth, nullptr, nullptr}, + {"health", PyEntity_GetHealth, PyEntity_SetHealth, nullptr}, + {"maxhealth", PyEntity_GetMaxHealth, PyEntity_SetMaxHealth, nullptr}, {"perm", PyEntity_GetPermissions, PyEntity_SetPermissions, nullptr}, {"deviceid", PyEntity_GetDeviceId, nullptr, nullptr}, {"deviceos", PyEntity_GetDeviceOS, nullptr, nullptr}, @@ -913,6 +928,13 @@ static PyObject* PyEntity_FromEntity(Actor* ptr) { #pragma endregion #pragma region Hook List #if 0 +HOOK(Actor_load, bool, "?load@Actor@@UEAA_NAEBVCompoundTag@@AEAVDataLoadHelper@@@Z", + Actor* _this, Tag* tag, struct DataLoadHelper* data) { + //cout << CompoundTagtoJson(tag).dump(4) << endl; + //cout << data << endl; + + return original(_this, tag, data); +} HOOK(Level_tick, void, "?tick@Level@@UEAAXXZ", Level* _this) { original(_this); @@ -951,7 +973,7 @@ HOOK(ChangeSettingCommand_setup, void, "?setup@ChangeSettingCommand@@SAXAEAVComm VA _this) { for (auto& [cmd, des] : _commands) { SymCall("?registerCommand@CommandRegistry@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PEBDW4CommandPermissionLevel@@UCommandFlag@@3@Z", - _this, &cmd, des.c_str(), 0, 0, 0x80); + _this, &cmd, des.first, 0, 0, 0x80); } original(_this); } @@ -1073,7 +1095,7 @@ HOOK(onDestroyBlock, bool, "?checkBlockDestroyPermissions@BlockSource@@QEAA_NAEA ) )) return false; - } +} return original(_this, p, bp, a3, a4); } HOOK(onOpenChest, bool, "?use@ChestBlock@@UEBA_NAEAVPlayer@@AEBVBlockPos@@E@Z", @@ -1233,6 +1255,14 @@ HOOK(onInputCommand, void, "?handle@ServerNetworkHandler@@UEAAXAEBVNetworkIdenti Player* p = _this->_getServerPlayer(id, pkt); if (p) { const string& cmd = FETCH(string, pkt + 48); + auto data = _commands.find(cmd.c_str() + 1); + if (data != _commands.end()) { + safeCall([&] { + PyObject_CallFunction(data->second.second, "O", PyEntity_FromEntity(p)); + PyErr_Print(); + }); + return; + } bool res = EventCallBack(EventCode::onInputCommand, Py_BuildValue("{s:O,s:s}", "player", PyEntity_FromEntity(p), @@ -1458,8 +1488,9 @@ static PyObject* PyAPI_setListener(PyObject*, PyObject* args) { static PyObject* PyAPI_setCommandDescription(PyObject*, PyObject* args) { const char* cmd = ""; const char* des = ""; - if (PyArg_ParseTuple(args, "ss:setCommandDescription", &cmd, &des)) { - _commands.push_back({ cmd, des }); + PyObject* callback = nullptr; + if (PyArg_ParseTuple(args, "ss|O:setCommandDescription", &cmd, &des, &callback)) { + _commands.insert({ cmd, { des, callback } }); } Py_RETURN_NONE; } diff --git a/BDSpyrunner/pch.h b/BDSpyrunner/pch.h index 7b69a5f4..362be32d 100644 --- a/BDSpyrunner/pch.h +++ b/BDSpyrunner/pch.h @@ -50,6 +50,14 @@ int HookFunction(void*, void*, void*); //获取符号 extern "C" _declspec(dllimport) void* GetServerSymbol(const char*); +//调用一个虚函数 +//_this:类地址 +//off:偏移量 +//剩下的参数就不用传this了 +template +static ret VirtualCall(VA off, void* _this, Args... args) { + return (*reinterpret_cast(*reinterpret_cast(_this) + off))(_this, args...); +} //调用一个函数 template static ret SymCall(const char* sym, Args... args) { @@ -666,7 +674,8 @@ struct Actor { } //获取实体类型 unsigned getEntityTypeId() { - return SymCall("?getEntityTypeId@Actor@@UEBA?AW4ActorType@@XZ", this); + return VirtualCall(0x520, this); + //return SymCall("?getEntityTypeId@Actor@@UEBA?AW4ActorType@@XZ", this); } //获取查询用ID VA getUniqueID() { @@ -698,11 +707,16 @@ struct Actor { int getMaxHealth() { return SymCall("?getMaxHealth@Actor@@QEBAHXZ", this); } - void setHealth(int value, int max) { - VA hattr = ((*(VA(__fastcall**)(Actor*, void*))(*(VA*)this + 1552))( - this, SYM("?HEALTH@SharedAttributes@@2VAttribute@@B"))); + void setHealth(int value) { + VA hattr = (*reinterpret_cast(*(VA*)this + 1552)) + (this, SYM("?HEALTH@SharedAttributes@@2VAttribute@@B")); FETCH(int, hattr + 132) = value; - FETCH(int, hattr + 128) = max; + //SymCall("?_setDirty@AttributeInstance@@AEAAXXZ", hattr); + } + void setMaxHealth(int value) { + VA hattr = (*reinterpret_cast(*(VA*)this + 1552)) + (this, SYM("?HEALTH@SharedAttributes@@2VAttribute@@B")); + FETCH(int, hattr + 128) = value; //SymCall("?_setDirty@AttributeInstance@@AEAAXXZ", hattr); } //获取副手