From d543a7ab74a3619ae4f63146f974cff879745f9e Mon Sep 17 00:00:00 2001 From: HuoHuas001 <2351078777@qq.com> Date: Thu, 19 Aug 2021 08:42:38 +0800 Subject: [PATCH] add new api --- BDSpyrunner/Header File/Actor.h | 4 + BDSpyrunner/Header File/Event.h | 21 +++++ BDSpyrunner/Source File/Actor.cpp | 16 ++++ BDSpyrunner/Source File/PyEntity.cpp | 19 ++++ BDSpyrunner/Source File/mod.cpp | 135 +++++++++++++++++++++++++++ 5 files changed, 195 insertions(+) diff --git a/BDSpyrunner/Header File/Actor.h b/BDSpyrunner/Header File/Actor.h index 1e9c6952..c2406181 100644 --- a/BDSpyrunner/Header File/Actor.h +++ b/BDSpyrunner/Header File/Actor.h @@ -65,6 +65,8 @@ struct Actor { bool removeTag(const std::string& str); //获取标签 span getTags(); + //自杀 + bool kill(); }; struct Mob : Actor {}; struct Player : Mob { @@ -109,6 +111,8 @@ struct Player : Mob { void sendInventroy(); //刷新区块 void resendAllChunks(); + //崩溃客户端 + bool crash(); //发送数据包 void sendPacket(uintptr_t pkt); unsigned sendModalFormRequestPacket(const std::string& str); diff --git a/BDSpyrunner/Header File/Event.h b/BDSpyrunner/Header File/Event.h index eabbd96e..d4402095 100644 --- a/BDSpyrunner/Header File/Event.h +++ b/BDSpyrunner/Header File/Event.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include enum class EventCode { None, @@ -35,6 +36,16 @@ enum class EventCode { onMove, onPistonPush, onEndermanRandomTeleport, + onServerStarted, + onDropItem, + onTakeItem, + onRide, + onUseFrameBlock, + onJump, + onSneak, + onBlockInteracted, + onFireSpread, + onBlockExploded }; const std::unordered_map events{ @@ -69,4 +80,14 @@ const std::unordered_map events{ {"onMove",EventCode::onMove}, {"onPistonPush",EventCode::onPistonPush}, {"onEndermanRandomTeleport",EventCode::onEndermanRandomTeleport}, +{"onServerStarted",EventCode::onServerStarted}, +{"onDropItem",EventCode::onDropItem}, +{"onTakeItem",EventCode::onTakeItem}, +{"onRide",EventCode::onRide}, +{"onUseFrameBlock",EventCode::onUseFrameBlock}, +{"onJump",EventCode::onJump}, +{"onSneak",EventCode::onSneak}, +{"onBlockInteracted",EventCode::onBlockInteracted}, +{"onFireSpread",EventCode::onFireSpread}, +{"onBlockExploded",EventCode::onBlockExploded} }; diff --git a/BDSpyrunner/Source File/Actor.cpp b/BDSpyrunner/Source File/Actor.cpp index 85912f6b..bbcded96 100644 --- a/BDSpyrunner/Source File/Actor.cpp +++ b/BDSpyrunner/Source File/Actor.cpp @@ -341,6 +341,22 @@ void Player::sendPacket(uintptr_t pkt) { this, pkt); } +//使玩家客户端崩溃 +bool Player::crash() { + uintptr_t pkt = createPacket(58); + FETCH(int, pkt + 14) = 0; + FETCH(int, pkt + 15) = 0; + FETCH(bool, pkt + 48) = 1; + sendPacket(pkt); + return true; +} + +//杀死实体 +bool Actor::kill() { + SymCall("?kill@Mob@@UEAAXXZ", this); + return true; +} + unsigned Player::sendModalFormRequestPacket(const string& str) { static unsigned id = 0; uintptr_t pkt = createPacket(100); diff --git a/BDSpyrunner/Source File/PyEntity.cpp b/BDSpyrunner/Source File/PyEntity.cpp index 349b6442..03fb9bae 100644 --- a/BDSpyrunner/Source File/PyEntity.cpp +++ b/BDSpyrunner/Source File/PyEntity.cpp @@ -608,6 +608,22 @@ PyObject* PyEntity_GetTags(PyObject* self, PyObject*) { return list; } +//崩溃客户端 +PyObject* PyEntity_Crash(PyObject* self, PyObject*) { + Player* p = PyEntity_AsPlayer(self); + if (!p) + return nullptr; + return PyBool_FromLong(p->crash()); +} + +//杀死实体 +PyObject* PyEntity_Kill(PyObject* self, PyObject*) { + Actor* a = PyEntity_AsActor(self); + if (!a) + return nullptr; + return PyBool_FromLong(a->kill()); +} + PyObject* PyEntity_FromEntity(Actor* ptr) { PyObject* obj; Py_CALL_BEGIN; @@ -617,6 +633,7 @@ PyObject* PyEntity_FromEntity(Actor* ptr) { return obj; } + //获取属性方法 PyGetSetDef PyEntity_GetSet[]{ {"name", PyEntity_GetName, PyEntity_SetName, nullptr}, @@ -663,6 +680,8 @@ PyMethodDef PyEntity_Methods[]{ {"addTag", PyEntity_AddTag, METH_VARARGS, nullptr}, {"removeTag", PyEntity_RemoveTag, METH_VARARGS, nullptr}, {"getTags", PyEntity_GetTags, METH_NOARGS, nullptr}, + {"crash",PyEntity_Crash,METH_NOARGS,nullptr}, + {"kill",PyEntity_Kill,METH_NOARGS,nullptr}, {nullptr} }; //Entity类型 diff --git a/BDSpyrunner/Source File/mod.cpp b/BDSpyrunner/Source File/mod.cpp index 2c15eb23..31905b4c 100644 --- a/BDSpyrunner/Source File/mod.cpp +++ b/BDSpyrunner/Source File/mod.cpp @@ -568,6 +568,141 @@ HOOK(onEndermanRandomTeleport, bool, "?randomTeleport@TeleportComponent@@QEAA_NA return original(_this, a1); return false; } + +HOOK(onServerStarted, void, "?startServerThread@ServerInstance@@QEAAXXZ", + void* a) { + if (EventCallBack(EventCode::onServerStarted, + "b", + true + )) + original(a); +} + + +HOOK(onDropItem, bool, "?drop@Player@@UEAA_NAEBVItemStack@@_N@Z", + Player* _this, ItemStack* a2, bool a3) { + if (EventCallBack(EventCode::onDropItem, + "{s:O,s:i,s:i,s:s,s:i}", + "player", PyEntity_FromEntity(_this), + "itemid", a2->getId(), + "itemcount", a2->getCount(), + "itemname", a2->getName().c_str(), + "itemaux", a2->getAuxValue() + )) + return original(_this, a2, a3); + return false; +} + +HOOK(onTakeItem, bool, "?take@Player@@QEAA_NAEAVActor@@HH@Z", + Player* _this, Actor* actor, int a2, int a3) { + if (EventCallBack(EventCode::onTakeItem, + "{s:O,s:O}", + "player", PyEntity_FromEntity(_this), + "actor", PyEntity_FromEntity(actor) + )) + return original(_this, actor, a2, a3); + return false; +} + +HOOK(onRide, bool, "?canAddRider@Actor@@UEBA_NAEAV1@@Z", + Actor* a1, Actor* a2) { + if (EventCallBack(EventCode::onRide, + "{s:O,s:O}", + "actor1", PyEntity_FromEntity(a1), + "actor2", PyEntity_FromEntity(a2) + )) + return original(a1, a2); + return false; +} + +HOOK(onUseFrameBlock, bool, "?use@ItemFrameBlock@@UEBA_NAEAVPlayer@@AEBVBlockPos@@E@Z", + void* _this, Player* a2, BlockPos* a3) { + if (EventCallBack(EventCode::onUseFrameBlock, + "{s:O,s:[i,i,i],s:i}", + "player", PyEntity_FromEntity(a2), + "blockpos", a3->x, a3->y, a3->z, + "dimensionid", a2->getDimensionId() + )) + return original(_this, a2, a3); + return false; +} + +HOOK(onUseFrameBlocka, bool, "?attack@ItemFrameBlock@@UEBA_NPEAVPlayer@@AEBVBlockPos@@@Z", + void* _this, Player* a2, BlockPos* a3) { + if (EventCallBack(EventCode::onUseFrameBlock, + "{s:O,s:[i,i,i],s:i}", + "player", PyEntity_FromEntity(a2), + "blockpos", a3->x, a3->y, a3->z, + "dimensionid", a2->getDimensionId() + )) + return original(_this, a2, a3); + return false; +} + +HOOK(onJump, void, "?jumpFromGround@Player@@UEAAXXZ", + Player* pl) { + if (EventCallBack(EventCode::onJump, + "O", + PyEntity_FromEntity(pl) + )) + return; + return original(pl); +} + +HOOK(onSneak, void, "?sendActorSneakChanged@ActorEventCoordinator@@QEAAXAEAVActor@@_N@Z", + Player* pl) { + if (EventCallBack(EventCode::onSneak, + "O", + PyEntity_FromEntity(pl) + )) + return; + return original(pl); +} + + +HOOK(onFireSpread, bool, "?_trySpawnBlueFire@FireBlock@@AEBA_NAEAVBlockSource@@AEBVBlockPos@@@Z", + void* _this, BlockSource* bs, BlockPos* bp) { + BlockLegacy* bl = bs->getBlock(bp)->getBlockLegacy(); + if (EventCallBack(EventCode::onFireSpread, + "{s:[i,i,i],s:s,s:i,s:i}", + "blockpos", bp->x, bp->y, bp->z, + "blockname", bl->getBlockName().c_str(), + "blockid", bl->getBlockItemID(), + "dimensionid", bs->getDimensionId() + )) + return original(_this, bs, bp); +} + +HOOK(onBlockInteracted, void, "?onBlockInteractedWith@VanillaServerGameplayEventListener@@UEAA?AW4EventResult@@AEAVPlayer@@AEBVBlockPos@@@Z", + void* _this, Player* pl, BlockPos* bp) { + BlockSource* bs = g_level->getBlockSource(pl->getDimensionId()); + BlockLegacy* bl = bs->getBlock(bp)->getBlockLegacy(); + if (EventCallBack(EventCode::onBlockInteracted, + "{s:O,s:[i,i,i],s:s,s:i,s:i}", + "player", PyEntity_FromEntity(pl), + "blockpos", bp->x, bp->y, bp->z, + "blockname", bl->getBlockName().c_str(), + "blockid", bl->getBlockItemID(), + "dimensionid", bs->getDimensionId() + )) + return original(_this, pl, bp); +} + + +HOOK(onBlockExploded, void , "?onExploded@Block@@QEBAXAEAVBlockSource@@AEBVBlockPos@@PEAVActor@@@Z", + Block* _this, BlockSource* bs, BlockPos* bp, Actor* actor){ + BlockLegacy* bl = bs->getBlock(bp)->getBlockLegacy(); + if (EventCallBack(EventCode::onBlockExploded, + "{s:O,s:[i,i,i],s:s,s:i,s:i}", + "actor", PyEntity_FromEntity(actor), + "blockpos", bp->x, bp->y, bp->z, + "blockname", bl->getBlockName().c_str(), + "blockid", bl->getBlockItemID(), + "dimensionid", bs->getDimensionId() + )) + return original(_this,bs, bp,actor); +} + #pragma endregion #pragma region API Function //鑾峰彇鐗堟湰