From ac806242648d985e437ba992af465331bbaf4d7c Mon Sep 17 00:00:00 2001 From: twoone3l <3197653242@qq.com> Date: Sat, 2 Oct 2021 08:01:15 +0800 Subject: [PATCH] 1.8.2 released. This is a stable version. I add some macro to simplefy code. For PyEntity, I abandon some GetSet which is not easy to understand. Player::getPlayerPermissions fixed. --- mc/Actor.cpp | 70 +++++------ mc/Actor.h | 33 ++++-- mc/ItemStack.cpp | 5 +- mod/CPython.h | 4 + mod/Entity.cpp | 160 ++++++++++++++++--------- mod/Module.cpp | 302 ++++++++++++++++++++++------------------------- mod/Module.h | 4 +- mod/Version.h | 4 +- 8 files changed, 313 insertions(+), 269 deletions(-) diff --git a/mc/Actor.cpp b/mc/Actor.cpp index da087840..992dc4ce 100644 --- a/mc/Actor.cpp +++ b/mc/Actor.cpp @@ -239,7 +239,8 @@ Container* Player::getInventory() { //获取装备容器 Container* Player::getArmorContainer() { - return FETCH(Container*, this + 1648);//IDA Actor::_setArmorContainer 11 + return SymCall("?getArmorContainer@Actor@@QEBAAEBVSimpleContainer@@XZ", + this); } //获取末影箱 @@ -251,38 +252,43 @@ Container* Player::getEnderChestContainer() { //设置一个装备 uintptr_t Player::setArmor(int i, ItemStack* item) { - return SymCall("?setArmor@ServerPlayer@@UEAAXW4ArmorSlot@@AEBVItemStack@@@Z", this, i, item); + return SymCall("?setArmor@ServerPlayer@@UEAAXW4ArmorSlot@@AEBVItemStack@@@Z", + this, i, item); } //设置副手 uintptr_t Player::setOffhandSlot(ItemStack* item) { - return SymCall("?setOffhandSlot@Player@@UEAAXAEBVItemStack@@@Z", this, item); + return SymCall("?setOffhandSlot@Player@@UEAAXAEBVItemStack@@@Z", + this, item); } //添加一个物品 void Player::addItem(ItemStack* item) { - SymCall("?addItem@@YAXAEAVPlayer@@AEAVItemStack@@@Z", this, item); + SymCall("?addItem@@YAXAEAVPlayer@@AEAVItemStack@@@Z", + this, item); } //增加等级 void Player::addLevel(int level) { - SymCall("?addLevels@Player@@UEAAXH@Z", this, level); + SymCall("?addLevels@Player@@UEAAXH@Z", + this, level); } //获取当前选中的框位置 int Player::getSelectedItemSlot() { - return SymCall("?getSelectedItemSlot@Player@@QEBAHXZ", this); - //return FETCH(unsigned, FETCH(uintptr_t, this + 3208) + 16);//IDA Player::getSelectedItemSlot + return SymCall("?getSelectedItemSlot@Player@@QEBAHXZ", + this); } //获取当前物品 ItemStack* Player::getSelectedItem() { - return SymCall("?getSelectedItem@Player@@QEBAAEBVItemStack@@XZ", this); + return SymCall("?getSelectedItem@Player@@QEBAAEBVItemStack@@XZ", + this); } //获取背包物品 @@ -291,42 +297,36 @@ ItemStack* Player::getInventoryItem(int slot) { return getInventory()->getSlots()[slot]; } -//获取游戏时命令权限 - -char Player::getPermissions() { - return *FETCH(char*, this + 2376);//IDA ServerPlayer::setPermissions 22 +//获取游戏时游玩权限 +PlayerPermissionLevel Player::getPlayerPermissionLevel() { + return SymCall("?getPlayerPermissionLevel@Player@@QEBA?AW4PlayerPermissionLevel@@XZ", + this); } //设置游戏时命令权限 -void Player::setPermissions(char m) { +void Player::setPermissions(PlayerPermissionLevel m) { SymCall("?setPermissions@ServerPlayer@@UEAAXW4CommandPermissionLevel@@@Z", this, m); } -//获取游戏时游玩权限 - -char Player::getPermissionLevel() {//IDA Abilities::setPlayerPermissions ? - return FETCH(char, FETCH(char*, this + 2376) + 1); -} - -//设置游戏时游玩权限 - -void Player::setPermissionLevel(char m) { - SymCall("?setPlayerPermissions@Abilities@@QEAAXW4PlayerPermissionLevel@@@Z", - this + 2376, m); -} - //获取设备id - -string Player::getDeviceId() { - return FETCH(string, this + 8352); //IDA Player::Player v13 + 8352 +string Player::getPlatformOnlineId() { + string id; + SymCall("?getPlatformOnlineId@Player@@QEBAAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ", + this, &id); + return id; + //return FETCH(string, this + 8352); + //IDA Player::Player v13 + 8352 } //获取设备系统类型 -int Player::getDeviceOS() { - return FETCH(int, this + 2368); //IDA ServerNetworkHandler::createNewPlayer ConnectionRequest::getDeviceOS +unsigned Player::getPlatform() { + return SymCall("?getPlatform@Player@@QEBA?AW4BuildPlatform@@XZ", + this); + //return FETCH(int, this + 2336); + //IDA ServerNetworkHandler::createNewPlayer ConnectionRequest::getDeviceOS } //发送背包 @@ -415,7 +415,9 @@ void Player::sendSetScorePacket(char type, const vector& slot) } bool IsPlayer(Actor* ptr) { - if (ptr && ptr->getEntityTypeId() == 319) - return true; - return false; + if (ptr == nullptr) + return false; + if (ptr->getEntityTypeId() != 319) + return false; + return true; } diff --git a/mc/Actor.h b/mc/Actor.h index f08bac28..73a6e014 100644 --- a/mc/Actor.h +++ b/mc/Actor.h @@ -10,6 +10,21 @@ struct Tag; struct NetworkIdentifier; struct Container; struct ScorePacketInfo; +struct Abilities; +enum class PlayerPermissionLevel : uint8_t { + Visitor, + Member, + Operator, + Custom +}; +enum class CommandPermissionLevel : uint8_t { + Any, + GameMasters, + Admin, + Host, + Owner, + Internal +}; struct Actor { //ȡϢ std::string getNameTag(); @@ -71,7 +86,7 @@ struct Mob : Actor {}; struct Player : Mob { //ȡuuid std::string getUuid(); - //ݵͼϢȡxuid + //ȡxuid std::string& getXuid(); //ȡʶ NetworkIdentifier* getClientId(); @@ -95,18 +110,16 @@ struct Player : Mob { ItemStack* getSelectedItem(); //ȡƷ ItemStack* getInventoryItem(int slot); - //ȡϷʱȨ - char getPermissions(); - //ϷʱȨ - void setPermissions(char m); - //ȡϷʱȨ - char getPermissionLevel(); + //ȡȨ + PlayerPermissionLevel getPlayerPermissionLevel(); //ϷʱȨ - void setPermissionLevel(char m); + void setPermissions(PlayerPermissionLevel m); + //ȡ + Abilities* getAbilities(); //ȡ豸id - std::string getDeviceId(); + std::string getPlatformOnlineId(); //ȡ豸ϵͳ - int getDeviceOS(); + unsigned getPlatform(); //ͱ void sendInventroy(); //ˢ diff --git a/mc/ItemStack.cpp b/mc/ItemStack.cpp index 2b95b772..4aa21693 100644 --- a/mc/ItemStack.cpp +++ b/mc/ItemStack.cpp @@ -100,8 +100,9 @@ void ItemStack::fromJson(const Json& value) { vector Container::getSlots() { vector s; - SymCall("?getSlots@Container@@UEBA?BV?$vector@PEBVItemStack@@V?$allocator@PEBVItemStack@@@std@@@std@@XZ", - this, &s); + VirtualCall(0x98, this, &s); + //SymCall("?getSlots@Container@@UEBA?BV?$vector@PEBVItemStack@@V?$allocator@PEBVItemStack@@@std@@@std@@XZ", + // this, &s); return s; } diff --git a/mod/CPython.h b/mod/CPython.h index 91060c99..ddaf66ca 100644 --- a/mod/CPython.h +++ b/mod/CPython.h @@ -3,6 +3,10 @@ #define PY_SSIZE_T_CLEAN #include "../include/Python.h" +#define Py_PARSE(format,...) if (!PyArg_ParseTuple(args, format ":" __FUNCTION__, __VA_ARGS__))return nullptr +#define Py_KERWORDS_LIST(...) static const char* kwlist[]{ __VA_ARGS__,nullptr } +#define Py_PARSE_WITH_KERWORDS(format,...) if (!PyArg_ParseTupleAndKeywords(args, kwds, format ":" __FUNCTION__, const_cast(kwlist), __VA_ARGS__))return nullptr + //ַתUnicode inline PyObject* StringToPyUnicode(std::string_view str) { return PyUnicode_FromStringAndSize(str.data(), str.length()); diff --git a/mod/Entity.cpp b/mod/Entity.cpp index 5a5fb686..88962227 100644 --- a/mod/Entity.cpp +++ b/mod/Entity.cpp @@ -45,55 +45,54 @@ struct PyEntity { return nullptr; return StringToPyUnicode(a->getNameTag()); } -}; + static PyObject* rich_compare(PyObject* self, PyObject* other, int op) { + switch (op) { + //< + case Py_LT:break; + //<= + case Py_LE:break; + //== + case Py_EQ: + if (PyEntity::asActor(self) == PyEntity::asActor(other)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + break; + //!= + case Py_NE: + if (PyEntity::asActor(self) != PyEntity::asActor(other)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + break; + //> + case Py_GT:break; + //>= + case Py_GE:break; + } + Py_RETURN_NOTIMPLEMENTED; + } -//Ƚ -PyObject* PyEntity_RichCompare(PyObject* self, PyObject* other, int op) { - switch (op) { - //< - case Py_LT:break; - //<= - case Py_LE:break; - //== - case Py_EQ: - if (PyEntity::asActor(self) == PyEntity::asActor(other)) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; - break; - //!= - case Py_NE: - if (PyEntity::asActor(self) != PyEntity::asActor(other)) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; - break; - //> - case Py_GT:break; - //>= - case Py_GE:break; + //ȡ + static PyObject* getName(PyObject* self, void*) { + Actor* a = PyEntity::asActor(self); + if (!a) + return nullptr; + return StringToPyUnicode(a->getNameTag()); + } + static int setName(PyObject* self, PyObject* arg, void*) { + if (PyUnicode_Check(arg)) { + Player* p = PyEntity::asPlayer(self); + if (!p) + return -1; + p->setNameTag(PyUnicode_AsUTF8(arg)); + return 0; + } + return PyErr_BadArgument(), -1; } - Py_RETURN_NOTIMPLEMENTED; -} -//ȡ -PyObject* PyEntity_GetName(PyObject* self, void*) { - Actor* a = PyEntity::asActor(self); - if (!a) - return nullptr; - return StringToPyUnicode(a->getNameTag()); -} +}; -int PyEntity_SetName(PyObject* self, PyObject* arg, void*) { - if (PyUnicode_Check(arg)) { - Player* p = PyEntity::asPlayer(self); - if (!p) - return -1; - p->setNameTag(PyUnicode_AsUTF8(arg)); - return 0; - } - return PyErr_BadArgument(), -1; -} //ȡUUID PyObject* PyEntity_GetUuid(PyObject* self, void*) { @@ -210,7 +209,7 @@ PyObject* PyEntity_GetPermissions(PyObject* self, void*) { Player* p = PyEntity::asPlayer(self); if (!p) return nullptr; - return PyLong_FromLong(p->getPermissions()); + return PyLong_FromLong(static_cast(p->getPlayerPermissionLevel())); } int PyEntity_SetPermissions(PyObject* self, PyObject* arg, void*) { @@ -218,26 +217,26 @@ int PyEntity_SetPermissions(PyObject* self, PyObject* arg, void*) { Player* p = PyEntity::asPlayer(self); if (!p) return -1; - p->setPermissions((char)PyLong_AsLong(arg)); + p->setPermissions(static_cast(PyLong_AsLong(arg))); return 0; } return PyErr_BadArgument(), -1; } //ȡ豸id -PyObject* PyEntity_GetDeviceId(PyObject* self, void*) { +PyObject* PyEntity_GetPlatformOnlineId(PyObject* self, void*) { Player* p = PyEntity::asPlayer(self); if (!p) return nullptr; - return StringToPyUnicode(p->getDeviceId()); + return StringToPyUnicode(p->getPlatformOnlineId()); } //ȡ豸 -PyObject* PyEntity_GetDeviceOS(PyObject* self, void*) { +PyObject* PyEntity_GetPlatform(PyObject* self, void*) { Player* p = PyEntity::asPlayer(self); if (!p) return nullptr; - return PyLong_FromLong(p->getDeviceOS()); + return PyLong_FromLong(p->getPlatform()); } //ȡIP @@ -276,6 +275,42 @@ PyObject* PyEntity_GetAllItem(PyObject* self, PyObject*) { return StringToPyUnicode(value.dump(4)); } +//ȡ/Ʒ +//PyObject* PyEntity_GetItem(PyObject* self, PyObject* args, PyObject* kwds) { +// bool get_inventory, get_enderchest, get_armor, get_offhand, get_hand; +// Py_KERWORDS_LIST( +// "Inventory", "EndChest", "Armor", "OffHand", "Hand" +// ); +// Py_PARSE_WITH_KERWORDS( +// "|ppppp", +// &get_inventory, &get_enderchest, &get_armor, &get_offhand, &get_hand +// ); +// Player* p = PyEntity::asPlayer(self); +// if (!p) +// return nullptr; +// Json value; +// +// Json& inventory = value["Inventory"]; +// for (auto& i : p->getInventory()->getSlots()) { +// inventory.push_back(CompoundTagtoJson(i->save())); +// } +// +// Json& endchest = value["EndChest"]; +// for (auto& i : p->getEnderChestContainer()->getSlots()) { +// endchest.push_back(CompoundTagtoJson(i->save())); +// } +// +// Json& armor = value["Armor"]; +// for (auto& i : p->getArmorContainer()->getSlots()) { +// armor.push_back(CompoundTagtoJson(i->save())); +// } +// +// value["OffHand"] = CompoundTagtoJson(p->getOffHand()->save()); +// value["Hand"] = CompoundTagtoJson(p->getSelectedItem()->save()); +// +// return StringToPyUnicode(value.dump(4)); +//} + PyObject* PyEntity_SetAllItem(PyObject* self, PyObject* args) { const char* x = ""; if (PyArg_ParseTuple(args, "s:setAllItem", &x)) { @@ -608,26 +643,33 @@ PyObject* PyEntity_Kill(PyObject* self, PyObject*) { //ȡԷ PyGetSetDef PyEntity_GetSet[]{ - {"name", PyEntity_GetName, PyEntity_SetName, nullptr}, + {"name", PyEntity::getName, PyEntity::setName, nullptr}, {"uuid", PyEntity_GetUuid, nullptr, nullptr}, {"xuid", PyEntity_GetXuid, nullptr, nullptr}, {"pos", PyEntity_GetPos, nullptr, nullptr}, {"did", PyEntity_GetDimensionId, nullptr, nullptr}, - {"isstand", PyEntity_GetIsStand, nullptr, nullptr}, - {"issneak", PyEntity_GetIsSneaking, nullptr, nullptr}, + {"is_standing", PyEntity_GetIsStand, nullptr, nullptr}, + /**/{"isstand", PyEntity_GetIsStand, nullptr, nullptr}, + {"is_sneaking", PyEntity_GetIsSneaking, nullptr, nullptr}, + /**/{"issneak", PyEntity_GetIsSneaking, nullptr, nullptr}, {"typeid", PyEntity_GetTypeID, nullptr, nullptr}, {"typename", PyEntity_GetTypeName, nullptr, nullptr}, - {"nbt", PyEntity_GetNBTInfo, nullptr, nullptr}, + {"NBT", PyEntity_GetNBTInfo, nullptr, nullptr}, + /**/{"nbt", PyEntity_GetNBTInfo, 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}, - {"ip", PyEntity_GetIP, nullptr, nullptr}, + {"platform_online_id", PyEntity_GetPlatformOnlineId, nullptr, nullptr}, + /**/{"deviceid", PyEntity_GetPlatformOnlineId, nullptr, nullptr}, + {"platform", PyEntity_GetPlatform, nullptr, nullptr}, + /**/{"deviceos", PyEntity_GetPlatform, nullptr, nullptr}, + {"IP", PyEntity_GetIP, nullptr, nullptr}, + /**/{"ip", PyEntity_GetIP, nullptr, nullptr}, {nullptr} }; //Entity PyMethodDef PyEntity_Methods[]{ + //{"getItem", (PyCFunction)PyEntity_GetItem, METH_VARARGS | METH_KEYWORDS, nullptr}, {"getAllItem", PyEntity_GetAllItem, METH_VARARGS, nullptr}, {"setAllItem", PyEntity_SetAllItem, METH_VARARGS, nullptr}, {"setHand", PyEntity_SetHand, METH_VARARGS, nullptr}, @@ -680,7 +722,7 @@ PyTypeObject PyEntity_Type{ "Entities in Minecraft",/* tp_doc */ nullptr, /* tp_traverse */ nullptr, /* tp_clear */ - PyEntity_RichCompare, /* tp_richcompare */ + PyEntity::rich_compare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ nullptr, /* tp_iter */ nullptr, /* tp_iternext */ diff --git a/mod/Module.cpp b/mod/Module.cpp index 9094b047..ddc6062d 100644 --- a/mod/Module.cpp +++ b/mod/Module.cpp @@ -28,54 +28,49 @@ constexpr int IsSlimeChunk(unsigned x, unsigned z) { } //С汾Ҫ static PyObject* minVersionRequire(PyObject*, PyObject* args) { - int v1, v2, v3; - if (PyArg_ParseTuple(args, "iii:" __FUNCTION__, &v1, &v2, &v3)) { - if (v1 > PYR_MAJOR_VERSION) - Py_RETURN_ERROR("The plugin version does not meet the minimum requirements"); - if (v2 > PYR_MINOR_VERSION) - Py_RETURN_ERROR("The plugin version does not meet the minimum requirements"); - if (v3 > PYR_MICRO_VERSION) - Py_RETURN_ERROR("The plugin version does not meet the minimum requirements"); - } + int major, minor, micro; + Py_PARSE("iii", &major, &minor, µ); + if (major > PYR_MAJOR_VERSION) + Py_RETURN_ERROR("The plugin version does not meet the minimum requirements"); + if (minor > PYR_MINOR_VERSION) + Py_RETURN_ERROR("The plugin version does not meet the minimum requirements"); + if (micro > PYR_MICRO_VERSION) + Py_RETURN_ERROR("The plugin version does not meet the minimum requirements"); Py_RETURN_NONE; } //ȡBDS汾 -static PyObject* getBDSVersion(PyObject*, PyObject*) { +static PyObject* getBDSVersion(PyObject*, PyObject* args) { + Py_PARSE(""); return StringToPyUnicode(GetBDSVersion()); } //ָ static PyObject* logout(PyObject*, PyObject* args) { const char* msg = ""; - if (PyArg_ParseTuple(args, "s:" __FUNCTION__, &msg)) { - SymCall("??$_Insert_string@DU?$char_traits@D@std@@_K@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@QEBD_K@Z", - &cout, msg, strlen(msg)); - } + Py_PARSE("s", &msg); + SymCall("??$_Insert_string@DU?$char_traits@D@std@@_K@std@@YAAEAV?$basic_ostream@DU?$char_traits@D@std@@@0@AEAV10@QEBD_K@Z", + &cout, msg, strlen(msg)); Py_RETURN_NONE; } //ִָ static PyObject* runCommand(PyObject*, PyObject* args) { const char* cmd = ""; - if (PyArg_ParseTuple(args, "s:" __FUNCTION__, &cmd)) { - if (!Global::data) - Py_RETURN_ERROR("Command queue is not initialized"); - SymCall("??$inner_enqueue@$0A@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@?$SPSCQueue@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@$0CAA@@@AEAA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", - Global::data, cmd); - } + Py_PARSE("s", &cmd); + if (!Global::data) + Py_RETURN_ERROR("Command queue is not initialized"); + SymCall("??$inner_enqueue@$0A@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@?$SPSCQueue@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@$0CAA@@@AEAA_NAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", + Global::data, cmd); Py_RETURN_NONE; } //ü static PyObject* setListener(PyObject*, PyObject* args) { const char* name = ""; PyObject* func; - if (PyArg_ParseTuple(args, "sO:" __FUNCTION__, &name, &func)) { - auto it = events.find(name); - if (!PyFunction_Check(func)) { - Py_RETURN_ERROR("Parameter 2 is not callable"); - } - if (it == events.end()) { - Py_RETURN_ERROR("Invalid Listener key words"); - } - g_callback_functions[it->second].push_back(func); - } + Py_PARSE("sO", &name, &func); + auto it = events.find(name); + if (!PyFunction_Check(func)) + Py_RETURN_ERROR("Parameter 2 is not callable"); + if (it == events.end()) + Py_RETURN_ERROR("Invalid Listener key words"); + g_callback_functions[it->second].push_back(func); Py_RETURN_NONE; } //ָ˵ @@ -83,23 +78,22 @@ static PyObject* setCommandDescription(PyObject*, PyObject* args) { const char* cmd = ""; const char* des = ""; PyObject* callback = nullptr; - if (PyArg_ParseTuple(args, "ss|O:" __FUNCTION__, &cmd, &des, &callback)) { - g_commands[cmd] = { des, callback }; - } + Py_PARSE("ss|O", &cmd, &des, &callback); + g_commands[cmd] = { des, callback }; Py_RETURN_NONE; } //ȡ static PyObject* getPlayerByXuid(PyObject*, PyObject* args) { const char* xuid = ""; - if (PyArg_ParseTuple(args, "s:" __FUNCTION__, &xuid)) { - Player* p = Global::data->getPlayerByXuid(xuid); - if (!p) - Py_RETURN_ERROR("Failed to find player"); - return ToEntity(p); - } - Py_RETURN_NONE; + Py_PARSE("s", &xuid); + Player* p = Global::data->getPlayerByXuid(xuid); + if (!p) + Py_RETURN_ERROR("Failed to find player"); + return ToEntity(p); } -static PyObject* getPlayerList(PyObject*, PyObject*) { +//ȡб +static PyObject* getPlayerList(PyObject*, PyObject* args) { + Py_PARSE(""); PyObject* list = PyList_New(0); if (!Global::data) Py_RETURN_ERROR("Level is not set"); @@ -113,110 +107,103 @@ static PyObject* getPlayerList(PyObject*, PyObject*) { } //޸˵˺ֵ static PyObject* setDamage(PyObject*, PyObject* args) { - PyArg_ParseTuple(args, "i:" __FUNCTION__, &g_damage); + Py_PARSE("i", &g_damage); Py_RETURN_NONE; } static PyObject* setServerMotd(PyObject*, PyObject* args) { const char* name = ""; - if (PyArg_ParseTuple(args, "s:" __FUNCTION__, &name)) { - if (!Global::data) - Py_RETURN_ERROR("Server did not finish loading"); - SymCall("?allowIncomingConnections@ServerNetworkHandler@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z", - Global::data, name, true); - } + Py_PARSE("s", &name); + if (!Global::data) + Py_RETURN_ERROR("Server did not finish loading"); + SymCall("?allowIncomingConnections@ServerNetworkHandler@@QEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@_N@Z", + Global::data, name, true); Py_RETURN_NONE; } //÷ static PyObject* getBlock(PyObject*, PyObject* args) { BlockPos bp; int did; - if (PyArg_ParseTuple(args, "iiii:" __FUNCTION__, &bp.x, &bp.y, &bp.z, &did)) { - if (!Global::data) - Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Global::data->getBlockSource(did); - if (!bs) - Py_RETURN_ERROR("Unknown dimension ID"); - BlockLegacy* bl = bs->getBlock(&bp)->getBlockLegacy(); - return Py_BuildValue("{s:s:s:i}", - "blockname", bl->getBlockName().c_str(), - "blockid", bl->getBlockItemID() - ); - } - Py_RETURN_NONE; + Py_PARSE("iiii", &bp.x, &bp.y, &bp.z, &did); + if (!Global::data) + Py_RETURN_ERROR("Level is not set"); + BlockSource* bs = Global::data->getBlockSource(did); + if (!bs) + Py_RETURN_ERROR("Unknown dimension ID"); + BlockLegacy* bl = bs->getBlock(&bp)->getBlockLegacy(); + return Py_BuildValue("{s:s:s:i}", + "blockname", bl->getBlockName().c_str(), + "blockid", bl->getBlockItemID() + ); } static PyObject* setBlock(PyObject*, PyObject* args) { const char* name = ""; BlockPos bp; int did; - if (PyArg_ParseTuple(args, "siiii:" __FUNCTION__, &name, &bp.x, &bp.y, &bp.z, &did)) { - if (!Global::data) - Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Global::data->getBlockSource(did); - if (!bs) - Py_RETURN_ERROR("Unknown dimension ID"); - Block* b = *reinterpret_cast(SYM((string("?m") + name + "@VanillaBlocks@@3PEBVBlock@@EB").c_str())); - if (!b) - Py_RETURN_ERROR("Unknown Block"); - bs->setBlock(&bp, b); - } + Py_PARSE("siiii", &name, &bp.x, &bp.y, &bp.z, &did); + if (!Global::data) + Py_RETURN_ERROR("Level is not set"); + BlockSource* bs = Global::data->getBlockSource(did); + if (!bs) + Py_RETURN_ERROR("Unknown dimension ID"); + Block* b = *reinterpret_cast(SYM((string("?m") + name + "@VanillaBlocks@@3PEBVBlock@@EB").c_str())); + if (!b) + Py_RETURN_ERROR("Unknown Block"); + bs->setBlock(&bp, b); Py_RETURN_NONE; } //ȡһṹ static PyObject* getStructure(PyObject*, PyObject* args) { BlockPos pos1, pos2; int did; - if (PyArg_ParseTuple(args, "iiiiiii:" __FUNCTION__, + Py_PARSE("iiiiiii", &pos1.x, &pos1.y, &pos1.z, - &pos2.x, &pos2.y, &pos2.z, &did)) { - if (!Global::data) - Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Global::data->getBlockSource(did); - if (!bs) - Py_RETURN_ERROR("Unknown dimension ID"); - BlockPos start{ - min(pos1.x,pos2.x), - min(pos1.y,pos2.y), - min(pos1.z,pos2.z) - }; - BlockPos size{ - max(pos1.x,pos2.x) - start.x, - max(pos1.y,pos2.y) - start.y, - max(pos1.z,pos2.z) - start.z - }; - StructureSettings ss(&size, false, false); - StructureTemplate st("tmp"); - st.fillFromWorld(bs, &start, &ss); + &pos2.x, &pos2.y, &pos2.z, &did + ); + if (!Global::data) + Py_RETURN_ERROR("Level is not set"); + BlockSource* bs = Global::data->getBlockSource(did); + if (!bs) + Py_RETURN_ERROR("Unknown dimension ID"); + BlockPos start{ + min(pos1.x,pos2.x), + min(pos1.y,pos2.y), + min(pos1.z,pos2.z) + }; + BlockPos size{ + max(pos1.x,pos2.x) - start.x, + max(pos1.y,pos2.y) - start.y, + max(pos1.z,pos2.z) - start.z + }; + StructureSettings ss(&size, false, false); + StructureTemplate st("tmp"); + st.fillFromWorld(bs, &start, &ss); - return StringToPyUnicode(CompoundTagtoJson(st.save()).dump(4)); - } - Py_RETURN_NONE; + return StringToPyUnicode(CompoundTagtoJson(st.save()).dump(4)); } static PyObject* setStructure(PyObject*, PyObject* args) { const char* data = ""; BlockPos pos; int did; - if (PyArg_ParseTuple(args, "siiii:" __FUNCTION__, - &data, &pos.x, &pos.y, &pos.z, &did)) { - if (!Global::data) - Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Global::data->getBlockSource(did); - if (!bs) - Py_RETURN_ERROR("Unknown dimension ID"); - Json value = StringToJson(data); - Json& arr = value["size9"]; - if (!arr.is_array()) - Py_RETURN_ERROR("Invalid json string"); - BlockPos size{ - arr[0].get(), - arr[1].get(), - arr[2].get() - }; - StructureSettings ss(&size, true, false); - StructureTemplate st("tmp"); - st.fromJson(value); - st.placeInWorld(bs, Global::data->getBlockPalette(), &pos, &ss); - for (int x = 0; x != size.x; ++x) { - for (int y = 0; y != size.y; ++y) { - for (int z = 0; z != size.z; ++z) { - BlockPos bp{ x,y,z }; - bs->neighborChanged(&bp); - } + Py_PARSE("siiii", &data, &pos.x, &pos.y, &pos.z, &did); + if (!Global::data) + Py_RETURN_ERROR("Level is not set"); + BlockSource* bs = Global::data->getBlockSource(did); + if (!bs) + Py_RETURN_ERROR("Unknown dimension ID"); + Json value = StringToJson(data); + Json& arr = value["size9"]; + if (!arr.is_array()) + Py_RETURN_ERROR("Invalid json string"); + BlockPos size{ + arr[0].get(), + arr[1].get(), + arr[2].get() + }; + StructureSettings ss(&size, true, false); + StructureTemplate st("tmp"); + st.fromJson(value); + st.placeInWorld(bs, Global::data->getBlockPalette(), &pos, &ss); + for (int x = 0; x != size.x; ++x) { + for (int y = 0; y != size.y; ++y) { + for (int z = 0; z != size.z; ++z) { + BlockPos bp{ x,y,z }; + bs->neighborChanged(&bp); } } } @@ -227,60 +214,55 @@ static PyObject* explode(PyObject*, PyObject* args) { Vec3 pos; int did; float power; bool destroy; float range; bool fire; - if (PyArg_ParseTuple(args, "fffifbfb:" __FUNCTION__, - &pos.x, &pos.y, &pos.z, &did, &power, &destroy, &range, &fire)) { - if (!Global::data) - Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Global::data->getBlockSource(did); - if (!bs) - Py_RETURN_ERROR("Unknown dimension ID"); - SymCall("?explode@Level@@UEAAXAEAVBlockSource@@PEAVActor@@AEBVVec3@@M_N3M3@Z", - Global::data, bs, nullptr, pos, power, fire, destroy, range, true); - } + Py_PARSE("fffifbfb", + &pos.x, &pos.y, &pos.z, &did, &power, &destroy, &range, &fire + ); + if (!Global::data) + Py_RETURN_ERROR("Level is not set"); + BlockSource* bs = Global::data->getBlockSource(did); + if (!bs) + Py_RETURN_ERROR("Unknown dimension ID"); + SymCall("?explode@Level@@UEAAXAEAVBlockSource@@PEAVActor@@AEBVVec3@@M_N3M3@Z", + Global::data, bs, nullptr, pos, power, fire, destroy, range, true); Py_RETURN_NONE; } //Ʒ static PyObject* spawnItem(PyObject*, PyObject* args) { const char* data = ""; Vec3 pos; int did; - if (PyArg_ParseTuple(args, "sfffi:" __FUNCTION__, &data, &pos.x, &pos.y, &pos.z, &did)) { - if (!Global::data) - Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Global::data->getBlockSource(did); - if (!bs) - Py_RETURN_ERROR("Unknown dimension ID"); - ItemStack item(StringToJson(data)); - Global::data->getSpawner()->spawnItem(bs, &item, &pos); - cout << pos.toString() << endl; - } + Py_PARSE("sfffi", &data, &pos.x, &pos.y, &pos.z, &did); + if (!Global::data) + Py_RETURN_ERROR("Level is not set"); + BlockSource* bs = Global::data->getBlockSource(did); + if (!bs) + Py_RETURN_ERROR("Unknown dimension ID"); + ItemStack item(StringToJson(data)); + Global::data->getSpawner()->spawnItem(bs, &item, &pos); Py_RETURN_NONE; } //ǷΪʷķ static PyObject* isSlimeChunk(PyObject*, PyObject* args) { unsigned x, z; - if (PyArg_ParseTuple(args, "II:" __FUNCTION__, &x, &z)) { - if (IsSlimeChunk(x, z)) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; - } - Py_RETURN_NONE; + Py_PARSE("II", &x, &z); + if (IsSlimeChunk(x, z)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; } // static PyObject* setSignBlockMessage(PyObject*, PyObject* args) { const char* name = ""; BlockPos bp; int did; - if (PyArg_ParseTuple(args, "siiii:" __FUNCTION__, &name, &bp.x, &bp.y, &bp.z, &did)) { - if (!Global::data) - Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Global::data->getBlockSource(did); - if (!bs) - Py_RETURN_ERROR("Unknown dimension ID"); - BlockActor* sign = bs->getBlockEntity(&bp); - SymCall("?setMessage@SignBlockActor@@QEAAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z", - sign, name, name); - sign->setChanged(); - } + Py_PARSE("siiii", &name, &bp.x, &bp.y, &bp.z, &did); + if (!Global::data) + Py_RETURN_ERROR("Level is not set"); + BlockSource* bs = Global::data->getBlockSource(did); + if (!bs) + Py_RETURN_ERROR("Unknown dimension ID"); + BlockActor* sign = bs->getBlockEntity(&bp); + SymCall("?setMessage@SignBlockActor@@QEAAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z", + sign, name, name); + sign->setChanged(); Py_RETURN_NONE; } //ģ鷽б @@ -318,7 +300,7 @@ static PyModuleDef Module{ nullptr }; //ģʼ -PyObject* mc_init() { +extern "C" PyObject * mc_init() { PyObject* module = PyModule_Create(&Module); PyModule_AddObject(module, "Entity", reinterpret_cast(&PyEntity_Type)); return module; diff --git a/mod/Module.h b/mod/Module.h index 2c6df24d..839494df 100644 --- a/mod/Module.h +++ b/mod/Module.h @@ -9,6 +9,6 @@ inline std::unordered_map> g_callback_function //ע inline std::unordered_map> g_commands; //˺ -inline int g_damage = 0; +inline static int g_damage = 0; -PyObject* mc_init(); \ No newline at end of file +extern "C" PyObject * mc_init(); \ No newline at end of file diff --git a/mod/Version.h b/mod/Version.h index 25af3fec..0b42b231 100644 --- a/mod/Version.h +++ b/mod/Version.h @@ -1,5 +1,5 @@ #pragma once constexpr unsigned PYR_MAJOR_VERSION = 1; constexpr unsigned PYR_MINOR_VERSION = 8; -constexpr unsigned PYR_MICRO_VERSION = 1; -constexpr const char* PYR_VERSION = "v1.8.1"; \ No newline at end of file +constexpr unsigned PYR_MICRO_VERSION = 2; +constexpr const char* PYR_VERSION = "v1.8.2"; \ No newline at end of file