From 74d24fd658ba6d5cbb79a3fe0241914bb4664b12 Mon Sep 17 00:00:00 2001 From: twoone3l <3197653242@qq.com> Date: Sun, 2 Jan 2022 15:30:58 +0800 Subject: [PATCH] =?UTF-8?q?1.9.0=5Fpreview=5F2=EF=BC=8C=E4=BD=BF=E6=9B=B4?= =?UTF-8?q?=E5=A4=9A=E5=87=BD=E6=95=B0=E5=AF=B9=E6=8E=A5LL=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dnbt=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mod.cpp | 4 +- mod/CPython.h | 14 ++-- mod/DataIO.cpp | 8 +-- mod/DataIO.h | 4 +- mod/Entity.cpp | 110 +++++++++++++++------------- mod/Module.cpp | 190 ++++++++++++++++++------------------------------- mod/NBT.h | 74 ++++++++++--------- mod/Tool.h | 3 +- mod/Version.h | 2 +- 9 files changed, 186 insertions(+), 223 deletions(-) diff --git a/mod.cpp b/mod.cpp index 13a42cd5..7d54eca5 100644 --- a/mod.cpp +++ b/mod.cpp @@ -105,7 +105,7 @@ static Json AccessUrlForJson(const wchar_t* url) { } while (size); InternetCloseHandle(handle2); InternetCloseHandle(hSession); - return StringToJson(data); + return ToJson(data); } //访问url static void AccessUrlForFile(const wchar_t* url, string_view filename) { @@ -251,7 +251,7 @@ THook(int, "main", int argc, char* argv[], char* envp[]) { #if 0 while (true) { - CompoundTag* t = ToCompoundTag(StringToJson(R"( + CompoundTag* t = ToCompoundTag(ToJson(R"( { "Block10": { "name8": "minecraft:crafting_table", diff --git a/mod/CPython.h b/mod/CPython.h index 9309acc9..be445774 100644 --- a/mod/CPython.h +++ b/mod/CPython.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #define PY_SSIZE_T_CLEAN #include "../include/Python.h" #include @@ -10,7 +10,7 @@ #define Py_PARSE_WITH_KERWORDS(format,...) if (!PyArg_ParseTupleAndKeywords(args, kwds, format ":" __FUNCTION__, const_cast(kwlist), __VA_ARGS__))return nullptr #define Py_RETURN_ERROR(str) return PyErr_SetString(PyExc_Exception, str), nullptr -#define Py_PRINT_REFCOUNT(obj) cout << "ü" << obj->ob_refcnt << endl +#define Py_PRINT_REFCOUNT(obj) cout << "引用计数:" << obj->ob_refcnt << endl //#define Py_BEGIN_CALL\ // int _has_gil = PyGILState_Check();\ // PyGILState_STATE _gil_state = PyGILState_LOCKED;\ @@ -22,7 +22,7 @@ // Py_END_ALLOW_THREADS;\ // if (!_has_gil)PyGILState_Release(_gil_state) -//ַתUnicode +//字符串转Unicode inline PyObject* ToPyStr(std::string_view str) { return PyUnicode_InternFromString(str.data()); //return PyUnicode_FromStringAndSize(str.data(), str.length()); @@ -36,7 +36,7 @@ inline std::vector ToStrArray(PyObject* list) { } return arr; } -//Vec3תlist +//Vec3转list inline PyObject* ToList(Vec3 vec) { PyObject* list = PyList_New(3); PyList_SetItem(list, 0, PyFloat_FromDouble(vec.x)); @@ -44,7 +44,7 @@ inline PyObject* ToList(Vec3 vec) { PyList_SetItem(list, 2, PyFloat_FromDouble(vec.z)); return list; } -//Vec3תlist +//Vec3转list inline PyObject* ToList(Vec3* vec) { PyObject* list = PyList_New(3); PyList_SetItem(list, 0, PyFloat_FromDouble(vec->x)); @@ -52,7 +52,7 @@ inline PyObject* ToList(Vec3* vec) { PyList_SetItem(list, 2, PyFloat_FromDouble(vec->z)); return list; } -//תlist +//方块坐标转list inline PyObject* ToList(BlockPos* bp) { PyObject* list = PyList_New(3); PyList_SetItem(list, 0, PyLong_FromLong(bp->x)); @@ -60,7 +60,7 @@ inline PyObject* ToList(BlockPos* bp) { PyList_SetItem(list, 2, PyLong_FromLong(bp->z)); return list; } -//ӡϢ +//打印错误信息 inline void PrintPythonError() { if (PyErr_Occurred()) { PyErr_Print(); diff --git a/mod/DataIO.cpp b/mod/DataIO.cpp index 419049e2..27fd8a46 100644 --- a/mod/DataIO.cpp +++ b/mod/DataIO.cpp @@ -1,13 +1,13 @@ -#include "DataIO.h" +#include "DataIO.h" #include "Tool.h" #include "NBT.h" -void serialize::write(CompoundTag* item, BinaryStream* stream) { +void serialize::write(const std::unique_ptr& item, BinaryStream* stream) { return SymCall("?write@?$serialize@VCompoundTag@@@@SAXAEBVCompoundTag@@AEAVBinaryStream@@@Z", - item, stream); + item.get(), stream); } -std::unique_ptr serialize::read(BinaryStream* stream) { +std::unique_ptr serialize::read(ReadOnlyBinaryStream* stream) { auto tag = CompoundTag::create(); SymCall("?read@?$serialize@VCompoundTag@@@@SA?AVCompoundTag@@AEAVReadOnlyBinaryStream@@@Z", tag.get(), stream); diff --git a/mod/DataIO.h b/mod/DataIO.h index bdcb427d..61604b0a 100644 --- a/mod/DataIO.h +++ b/mod/DataIO.h @@ -42,7 +42,7 @@ class BinaryStream : public ReadOnlyBinaryStream { template class serialize { public: - static void write(T* val, BinaryStream* stream); - static std::unique_ptr read(BinaryStream* stream); + static void write(const std::unique_ptr& val, BinaryStream* stream); + static std::unique_ptr read(ReadOnlyBinaryStream* stream); }; diff --git a/mod/Entity.cpp b/mod/Entity.cpp index c1f3197b..279e9626 100644 --- a/mod/Entity.cpp +++ b/mod/Entity.cpp @@ -135,7 +135,7 @@ struct PyEntity { Py_GET_ACTOR; unique_ptr t = CompoundTag::create(); a->save(*t); - return ToPyStr(ToJson(move(t))); + return ToPyStr(ToJson(*t).dump(4)); } //获取生命值 static PyObject* getHealth(PyObject* self, void*) { @@ -204,81 +204,71 @@ struct PyEntity { //获取玩家所有物品 static PyObject* getAllItem(PyObject* self, PyObject*) { Py_GET_PLAYER; - fifo_json value; - - fifo_json& inventory = value["Inventory"]; + fifo_json items_json = fifo_json::object(); + fifo_json& inventory = items_json["Inventory"]; for (auto& i : p->getInventory().getSlots()) { - inventory.push_back(ToJson(i->save())); + inventory.push_back(ToJson(*i->save())); } - - fifo_json& endchest = value["EndChest"]; + fifo_json& endchest = items_json["EndChest"]; for (auto& i : p->getEnderChestContainer()->getSlots()) { - endchest.push_back(ToJson(i->save())); + endchest.push_back(ToJson(*i->save())); } - - fifo_json& armor = value["Armor"]; + fifo_json& armor = items_json["Armor"]; for (auto& i : p->getArmorContainer().getSlots()) { - armor.push_back(ToJson(i->save())); + armor.push_back(ToJson(*i->save())); } - - value["OffHand"] = ToJson(p->getOffhandSlot().save()); - value["Hand"] = ToJson(p->getSelectedItem().save()); - - return ToPyStr(value.dump(4)); + items_json["OffHand"] = ToJson(*p->getOffhandSlot().save()); + items_json["Hand"] = ToJson(*p->getSelectedItem().save()); + return ToPyStr(items_json.dump(4)); } //设置玩家所有物品 static PyObject* setAllItem(PyObject* self, PyObject* args) { - const char* x = ""; - Py_PARSE("s", &x); + const char* items_data = ""; + Py_PARSE("s", &items_data); Py_GET_PLAYER; - fifo_json value(StringToJson(x)); - - if (value.contains("Inventory")) { + fifo_json items_json(ToJson(items_data)); + if (items_json.contains("Inventory")) { auto& items = p->getInventory(); - fifo_json& inventory = value["Inventory"]; + fifo_json& inventory = items_json["Inventory"]; for (unsigned i = 0; i < inventory.size(); i++) { *items.getSlot(i) = LoadItemFromJson(inventory[i]); } } - - if (value.contains("EndChest")) { + if (items_json.contains("EndChest")) { auto items = p->getEnderChestContainer(); - fifo_json& endchest = value["EndChest"]; + fifo_json& endchest = items_json["EndChest"]; for (unsigned i = 0; i < endchest.size(); i++) { *items->getSlot(i) = LoadItemFromJson(endchest[i]); } } - - if (value.contains("Armor")) { + if (items_json.contains("Armor")) { auto& items = p->getArmorContainer(); - fifo_json& armor = value["Armor"]; + fifo_json& armor = items_json["Armor"]; for (unsigned i = 0; i < armor.size(); i++) { *items.getSlot(i) = LoadItemFromJson(armor[i]); } } - - if (value.contains("OffHand")) { - p->setOffhandSlot(LoadItemFromJson(value["OffHand"])); + if (items_json.contains("OffHand")) { + p->setOffhandSlot(LoadItemFromJson(items_json["OffHand"])); } p->sendInventory(true); - Py_RETURN_NONE; } //设置玩家手上物品 static PyObject* setHand(PyObject* self, PyObject* args) { - const char* x = ""; - Py_PARSE("s", &x); + const char* item_data = ""; + Py_PARSE("s", &item_data); Py_GET_PLAYER; - const_cast(p->getSelectedItem()) = LoadItemFromString(x); + const_cast(p->getSelectedItem()) = LoadItemFromString(item_data); p->sendInventory(true); Py_RETURN_NONE; } //增加玩家背包物品 static PyObject* addItem(PyObject* self, PyObject* args) { - const char* x = ""; - Py_PARSE("s", &x); + const char* item_data = ""; + Py_PARSE("s", &item_data); Py_GET_PLAYER; - auto item = LoadItemFromString(x); + auto item = LoadItemFromString(item_data); p->giveItem(&item); p->sendInventory(true); Py_RETURN_NONE; @@ -294,7 +284,8 @@ struct PyEntity { } //传送 static PyObject* teleport(PyObject* self, PyObject* args) { - Vec3 pos; int did; + Vec3 pos; + int did; Py_PARSE("fffi", &pos.x, &pos.y, &pos.z, &did); Py_GET_PLAYER; p->teleport(pos, did); @@ -330,19 +321,38 @@ struct PyEntity { p->kick(msg); Py_RETURN_NONE; } - //计分板操作 + //获取玩家分数 static PyObject* getScore(PyObject* self, PyObject* args) { const char* objname = ""; Py_PARSE("s", &objname); Py_GET_PLAYER; return PyLong_FromLong(p->getScore(objname)); } - //todo add reduce set - static PyObject* modifyScore(PyObject* self, PyObject* args) { + //设置玩家分数 + static PyObject* setScore(PyObject* self, PyObject* args) { const char* objname = ""; - int count; PlayerScoreSetFunction mode; - Py_PARSE("sii", &objname, &count, &mode); + int count; + Py_PARSE("si", &objname, &count); Py_GET_PLAYER; + p->setScore(objname, count); + Py_RETURN_NONE; + } + //增加玩家分数 + static PyObject* addScore(PyObject* self, PyObject* args) { + const char* objname = ""; + int count; + Py_PARSE("si", &objname, &count); + Py_GET_PLAYER; + p->addScore(objname, count); + Py_RETURN_NONE; + } + //减少玩家分数 + static PyObject* reduceScore(PyObject* self, PyObject* args) { + const char* objname = ""; + int count; + Py_PARSE("si", &objname, &count); + Py_GET_PLAYER; + p->reduceScore(objname, count); Py_RETURN_NONE; } //增加等级 @@ -425,7 +435,7 @@ struct PyEntity { Py_PARSE("ss|i", &title, &side_data, &order); Py_GET_PLAYER; vector> data; - fifo_json value = StringToJson(side_data); + fifo_json value = ToJson(side_data); if (value.is_object()) for (auto& [key, val] : value.items()) { data.push_back({ key, val }); @@ -529,7 +539,9 @@ struct PyEntity { { "resendAllChunks", resendAllChunks, METH_NOARGS, nullptr }, { "disconnect", disconnect, METH_VARARGS, nullptr }, { "getScore", getScore, METH_VARARGS, nullptr }, - { "modifyScore", modifyScore, METH_VARARGS, nullptr }, + { "setScore", setScore, METH_VARARGS, nullptr }, + { "addScore", addScore, METH_VARARGS, nullptr }, + { "reduceScore", reduceScore, METH_VARARGS, nullptr }, { "addLevel", addLevel, METH_VARARGS, nullptr }, { "transferServer", transferServer, METH_VARARGS, nullptr }, { "sendCustomForm", sendCustomForm, METH_VARARGS, nullptr }, @@ -597,11 +609,9 @@ PyTypeObject PyEntity_Type{ 0, /* tp_version_tag */ nullptr, /* tp_finalize */ }; + PyObject* ToEntity(Actor* ptr) { - PyEntity* obj = nullptr; - //Py_BEGIN_CALL; - obj = PyObject_New(PyEntity, &PyEntity_Type); - //Py_END_CALL; + PyEntity* obj = PyObject_New(PyEntity, &PyEntity_Type); obj->actor = ptr; return reinterpret_cast(obj); } diff --git a/mod/Module.cpp b/mod/Module.cpp index 7f2638f9..58be9686 100644 --- a/mod/Module.cpp +++ b/mod/Module.cpp @@ -156,140 +156,92 @@ static PyObject* setBlock(PyObject*, PyObject* args) { bs->setBlock(bp, *b, 0, nullptr); Py_RETURN_NONE; } -//获取一个结构 +//从指定地点获取JSON字符串NBT结构数据 static PyObject* getStructure(PyObject*, PyObject* args) { - BlockPos pos1, pos2; int did; - Py_PARSE("iiiiiii", + BlockPos pos1, pos2; + int did; + bool ignore_entities = true; + bool ignore_blocks = false; + Py_PARSE("iiiiiii|bb", &pos1.x, &pos1.y, &pos1.z, - &pos2.x, &pos2.y, &pos2.z, &did + &pos2.x, &pos2.y, &pos2.z, &did, + &ignore_entities, &ignore_blocks ); - if (Global == nullptr) - Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Level::getBlockSource(did); - if (bs == nullptr) - 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"s); - st.fillFromWorld(*bs, start, ss); - - return ToPyStr(ToJson(st.save()).dump(4)); + auto st = StructureTemplate::fromWorld("name", did, pos1, pos2, ignore_entities, ignore_blocks); + return ToPyStr(ToJson(*st.save()).dump(4)); } -static PyObject* setStructure(PyObject*, PyObject* args, PyObject* kwds) { - Py_KERWORDS_LIST("data", "x", "y", "x", "dim"); +//从JSON字符串NBT结构数据导出结构到指定地点 +static PyObject* setStructure(PyObject*, PyObject* args) { const char* data = ""; - BlockPos pos; int did; - Py_PARSE_WITH_KERWORDS("siiii|b", &data, &pos.x, &pos.y, &pos.z, &did); - if (Global == nullptr) - Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Level::getBlockSource(did); - if (bs == nullptr) - Py_RETURN_ERROR("Unknown dimension ID"); - fifo_json value = StringToJson(data); - fifo_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, false, false); - StructureTemplate st("tmp"); - st.fromTag("tmp", *ToCompoundTag(value)); - st.placeInWorld(*bs, *Global->getBlockPalette(), pos, ss, nullptr, true); - for (int x = 0; x != size.x; ++x) { + BlockPos pos; + int did; + Mirror mir = None_15; + Rotation rot = None_14; + Py_PARSE("siiii|ii", + &data, &pos.x, &pos.y, &pos.z, + &did, &mir, &rot + ); + StructureTemplate::fromTag("name", *ToCompoundTag(ToJson(data))) + .toWorld(did, pos, mir, rot); + /*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, bp); } } - } + }*/ Py_RETURN_NONE; } //从指定地点获取二进制NBT结构数据 -static PyObject* getStructureRaw(PyObject*, PyObject* args) { - BlockPos pos1, pos2; int did; - Py_PARSE("iiiiiii", +static PyObject* getStructureBinary(PyObject*, PyObject* args) { + BlockPos pos1, pos2; + int did; + bool ignore_entities = true; + bool ignore_blocks = false; + Py_PARSE("iiiiiii|bb", &pos1.x, &pos1.y, &pos1.z, - &pos2.x, &pos2.y, &pos2.z, &did + &pos2.x, &pos2.y, &pos2.z, &did, + &ignore_entities, &ignore_blocks + ); + auto st = StructureTemplate::fromWorld("name", did, pos1, pos2, ignore_entities, ignore_blocks); + BinaryStream binary_stream; + serialize::write(st.save(), &binary_stream); + return PyBytes_FromStringAndSize( + binary_stream.getAndReleaseData().c_str(), + binary_stream.getLength() ); - if (Global == nullptr) - Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Level::getBlockSource(did); - if (bs == nullptr) - 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); - CompoundTag* t = st.save().get(); - BinaryStream* stream = new BinaryStream(); - serialize::write(t, stream); - size_t sizet = stream->getLength(); - auto result = PyBytes_FromStringAndSize(stream->getAndReleaseData().c_str(), sizet); - stream->~BinaryStream(); - return result; } //从二进制NBT结构数据导出结构到指定地点 -static PyObject* setStructureRaw(PyObject*, PyObject* args, PyObject* kwds) { - Py_KERWORDS_LIST("data", "x", "y", "x", "dim"); - const char* data; - Py_ssize_t datasize; - //Py_buffer data; - BlockPos pos; int did; - Py_PARSE_WITH_KERWORDS("y#iiii|b", &data, &datasize, &pos.x, &pos.y, &pos.z, &did); - if (Global == nullptr) - Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Level::getBlockSource(did); - if (bs == nullptr) - Py_RETURN_ERROR("Unknown dimension ID"); - ReadOnlyBinaryStream* stream = new ReadOnlyBinaryStream(new std::string(data, datasize)); +static PyObject* setStructureBinary(PyObject*, PyObject* args) { + const char* data = ""; + Py_ssize_t data_size; + BlockPos pos; + int did; + Mirror mir = None_15; + Rotation rot = None_14; + Py_PARSE("y#iiii|ii", + &data, &data_size, &pos.x, &pos.y, &pos.z, + &did, &mir, &rot + ); + ReadOnlyBinaryStream binary_stream = new string(data, data_size); //printf("bufferlength: %d\n",stream->mBuffer->length()); - auto tag = serialize::read(static_cast(stream)); + auto tag = serialize::read(&binary_stream); //printf("deserialized.\n"); if (tag->getTagType() != Tag::Type::Compound) Py_RETURN_ERROR("Invalid Tag"); - auto& t = *tag->asCompoundTag(); - if (t.contains("size") || t["size"]->getTagType() != Tag::Type::List) + if (tag->contains("size") || (*tag)["size"]->getTagType() != Tag::Type::List) Py_RETURN_ERROR("Invalid Tag"); - auto& t_size = *t["size"]->asListTag(); - BlockPos size{ - const_cast(t_size[0])->asIntTag()->value(), - const_cast(t_size[1])->asIntTag()->value(), - const_cast(t_size[2])->asIntTag()->value(), - }; - StructureSettings ss(size, true, false); - StructureTemplate st("tmp"); - st.fromTag("", *tag); - st.placeInWorld(*bs, *Global->getBlockPalette(), pos, ss, nullptr, true); - for (int x = 0; x != size.x; ++x) { + StructureTemplate::fromTag("name", *tag) + .toWorld(did, pos, mir, rot); + /*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, bp); // idk what will happen, origin: neighborChanged(bp) } } - } + }*/ Py_RETURN_NONE; } //产生爆炸 @@ -298,29 +250,26 @@ static PyObject* explode(PyObject*, PyObject* args) { float power; bool destroy; float range; bool fire; Py_PARSE("fffifbfb", - &pos.x, &pos.y, &pos.z, &did, &power, &destroy, &range, &fire + &pos.x, &pos.y, &pos.z, &did, + &power, &destroy, &range, &fire ); if (Global == nullptr) Py_RETURN_ERROR("Level is not set"); BlockSource* bs = Level::getBlockSource(did); if (!bs) Py_RETURN_ERROR("Unknown dimension ID"); - SymCall("?explode@Level@@UEAAXAEAVBlockSource@@PEAVActor@@AEBVVec3@@M_N3M3@Z", - Global, bs, nullptr, pos, power, fire, destroy, range, true); + Global->explode(*bs, nullptr, pos, power, fire, destroy, range, true); Py_RETURN_NONE; } //生成物品 static PyObject* spawnItem(PyObject*, PyObject* args) { - const char* data = ""; + const char* item_data = ""; Vec3 pos; int did; - Py_PARSE("sfffi", &data, &pos.x, &pos.y, &pos.z, &did); + Py_PARSE("sfffi", &item_data, &pos.x, &pos.y, &pos.z, &did); + ItemStack item = LoadItemFromString(item_data); if (Global == nullptr) Py_RETURN_ERROR("Level is not set"); - BlockSource* bs = Level::getBlockSource(did); - if (!bs) - Py_RETURN_ERROR("Unknown dimension ID"); - ItemStack item = LoadItemFromString(data); - Global->getSpawner().spawnItem(pos, did, &item); // Todo + Global->getSpawner().spawnItem(pos, did, &item); Py_RETURN_NONE; } //是否为史莱姆区块 @@ -342,9 +291,8 @@ static PyObject* setSignBlockMessage(PyObject*, PyObject* args) { BlockSource* bs = Level::getBlockSource(did); if (bs == nullptr) 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); + SignBlockActor* sign = static_cast(bs->getBlockEntity(bp)); + sign->setMessage(name, name); sign->setChanged(); Py_RETURN_NONE; } @@ -363,9 +311,9 @@ static PyMethodDef Methods[]{ { "getBlock", getBlock, METH_VARARGS, nullptr }, { "setBlock", setBlock, METH_VARARGS, nullptr }, { "getStructure", getStructure, METH_VARARGS, nullptr }, - { "setStructure", (PyCFunction)setStructure, METH_VARARGS | METH_KEYWORDS, nullptr }, - { "getStructureRaw", getStructureRaw, METH_VARARGS, nullptr }, - { "setStructureRaw", (PyCFunction)setStructureRaw, METH_VARARGS | METH_KEYWORDS, nullptr }, + { "setStructure", setStructure, METH_VARARGS, nullptr }, + { "getStructureBinary", getStructureBinary, METH_VARARGS, nullptr }, + { "setStructureBinary", setStructureBinary, METH_VARARGS, nullptr }, { "explode", explode, METH_VARARGS, nullptr }, { "spawnItem", spawnItem, METH_VARARGS, nullptr }, { "isSlimeChunk", isSlimeChunk, METH_VARARGS, nullptr }, diff --git a/mod/NBT.h b/mod/NBT.h index 91bf7335..bbf1e3b0 100644 --- a/mod/NBT.h +++ b/mod/NBT.h @@ -13,98 +13,102 @@ #include #include "Tool.h" -inline fifo_json ToJson(unique_ptr t); -inline fifo_json ToJson(unique_ptr t); +inline fifo_json ToJson(const ListTag& t); +inline fifo_json ToJson(const CompoundTag& t); inline unique_ptr ToListTag(const fifo_json& value); inline unique_ptr ToCompoundTag(const fifo_json& value); -inline fifo_json ToJson(unique_ptr t) { - fifo_json value(json_t::array); - for (auto& c : t->value()) { - switch (t->getElementType()) { +inline fifo_json ToJson(const ListTag& t) { + fifo_json json = fifo_json::array(); + for (auto& c : t) { + switch (t.getElementType()) { case Tag::Type::End: + logger.error("EndTag in ListTag"); break; case Tag::Type::Byte: - value.push_back(c->asByteTag()->value()); + json.push_back(c->asByteTag()->value()); break; case Tag::Type::Short: - value.push_back(c->asShortTag()->value()); + json.push_back(c->asShortTag()->value()); break; case Tag::Type::Int: - value.push_back(c->asIntTag()->value()); + json.push_back(c->asIntTag()->value()); break; case Tag::Type::Int64: - value.push_back(c->asInt64Tag()->value()); + json.push_back(c->asInt64Tag()->value()); break; case Tag::Type::Float: - value.push_back(c->asFloatTag()->value()); + json.push_back(c->asFloatTag()->value()); break; case Tag::Type::Double: - value.push_back(c->asDoubleTag()->value()); + json.push_back(c->asDoubleTag()->value()); break; case Tag::Type::ByteArray: - + logger.error("ByteArrayTag in ListTag"); break; case Tag::Type::String: - value.push_back(c->asStringTag()->value()); + json.push_back(c->asStringTag()->value()); break; case Tag::Type::List: - value.push_back(ToJson(unique_ptr(c->asListTag()))); + json.push_back(ToJson(*c->asListTag())); break; case Tag::Type::Compound: - value.push_back(ToJson(unique_ptr(c->asCompoundTag()))); + json.push_back(ToJson(*c->asCompoundTag())); break; } } - return value; + return json; } -inline fifo_json ToJson(unique_ptr t) { - fifo_json value; - for (auto& x : t->value()) { - Tag::Type type = x.second.getTagType(); - fifo_json& son = value[x.first + std::to_string(static_cast(type))]; +inline fifo_json ToJson(const CompoundTag& t) { + fifo_json json = fifo_json::object(); + for (auto& [key, val] : t) { + Tag* tag = const_cast(val.get()); + Tag::Type type = tag->getTagType(); + fifo_json& son = json[key + std::to_string(static_cast(type))]; switch (type) { case Tag::Type::End: + logger.error("EndTag in CompoundTag"); break; case Tag::Type::Byte: - son = x.second.asByteTag()->value(); + son = tag->asByteTag()->value(); break; case Tag::Type::Short: - son = x.second.asShortTag()->value(); + son = tag->asShortTag()->value(); break; case Tag::Type::Int: - son = x.second.asIntTag()->value(); + son = tag->asIntTag()->value(); break; case Tag::Type::Int64: - son = x.second.asInt64Tag()->value(); + son = tag->asInt64Tag()->value(); break; case Tag::Type::Float: - son = x.second.asFloatTag()->value(); + son = tag->asFloatTag()->value(); break; case Tag::Type::Double: - son = x.second.asDoubleTag()->value(); + son = tag->asDoubleTag()->value(); break; case Tag::Type::ByteArray: - for (size_t i = 0; i < x.second.asByteArrayTag()->value().size; ++i) { - auto c = x.second.asByteArrayTag()->value().data[i]; + for (size_t i = 0; i < tag->asByteArrayTag()->value().size; ++i) { + auto c = tag->asByteArrayTag()->value().data[i]; son.push_back(c); } break; case Tag::Type::String: - son = x.second.asStringTag()->value(); + son = tag->asStringTag()->value(); break; case Tag::Type::List: - son = ToJson(unique_ptr(x.second.asListTag())); + son = ToJson(*tag->asListTag()); break; case Tag::Type::Compound: - son = ToJson(unique_ptr(x.second.asCompoundTag())); + son = ToJson(*tag->asCompoundTag()); break; case Tag::Type::IntArray: + logger.error("IntArrayTag in CompoundTag"); break; default: break; } } - return value; + return json; } inline unique_ptr ToListTag(const fifo_json& value) { auto list = ListTag::create(); @@ -209,7 +213,7 @@ inline unique_ptr ToCompoundTag(const fifo_json& value) { } inline ItemStack LoadItemFromString(std::string_view str) { - return ItemStack::fromTag(*ToCompoundTag(StringToJson(str))); + return ItemStack::fromTag(*ToCompoundTag(ToJson(str))); } inline ItemStack LoadItemFromJson(fifo_json data) { return ItemStack::fromTag(*ToCompoundTag(data)); diff --git a/mod/Tool.h b/mod/Tool.h index fdb7c03c..94c8ccbc 100644 --- a/mod/Tool.h +++ b/mod/Tool.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,7 @@ using std::unique_ptr; using json_t = nlohmann::detail::value_t; //字符串转JSON,本插件采用 https://json.nlohmann.me 的JSON库3.10.4版本 -inline fifo_json StringToJson(std::string_view str) { +inline fifo_json ToJson(std::string_view str) { try { return fifo_json::parse(str); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; diff --git a/mod/Version.h b/mod/Version.h index 474907f6..f5e868ca 100644 --- a/mod/Version.h +++ b/mod/Version.h @@ -2,4 +2,4 @@ constexpr unsigned PYR_MAJOR_VERSION = 1; constexpr unsigned PYR_MINOR_VERSION = 9; constexpr unsigned PYR_MICRO_VERSION = 0; -constexpr const char* PYR_VERSION = "v1.9.0_preview_1"; \ No newline at end of file +constexpr const char* PYR_VERSION = "v1.9.0_preview_2"; \ No newline at end of file