From d537c8d79fdcfa154f4262d75406aafd2a8ad5a5 Mon Sep 17 00:00:00 2001
From: twoone3 <3197653242@qq.com>
Date: Thu, 3 Feb 2022 15:26:04 +0800
Subject: [PATCH] =?UTF-8?q?1.9.6=E6=9B=B4=E6=96=B0=20-=20=E4=BF=AE?=
=?UTF-8?q?=E5=A4=8DgetPlayerList=E7=9A=84=E5=86=85=E5=AD=98=E6=B3=84?=
=?UTF-8?q?=E9=9C=B2=20-=20=E4=BF=AE=E5=A4=8DregisterCommand=E5=87=BD?=
=?UTF-8?q?=E6=95=B0=E5=9B=9E=E8=B0=83=20-=20=E6=96=B0=E5=A2=9EPyEntity::g?=
=?UTF-8?q?etGameMode=E5=87=BD=E6=95=B0=20-=20=E6=96=B0=E5=A2=9EPyBlockIns?=
=?UTF-8?q?tance::getPos/getDimensionId=E5=87=BD=E6=95=B0=20-=20=E4=BF=AE?=
=?UTF-8?q?=E5=A4=8DPyEntity=E5=9C=A8MobHurtEvent=E4=B8=AD=E7=A9=BA?=
=?UTF-8?q?=E6=8C=87=E9=92=88=E8=8E=B7=E5=8F=96=E5=AD=97=E7=AC=A6=E4=B8=B2?=
=?UTF-8?q?=E4=B8=BA=E7=A9=BA=E6=8C=87=E9=92=88=E7=9A=84=E9=97=AE=E9=A2=98?=
=?UTF-8?q?=20-=20=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86=E6=BA=90=E6=96=87?=
=?UTF-8?q?=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
BDSpyrunner.vcxproj | 12 ++--
BDSpyrunner.vcxproj.filters | 18 ++----
mod/CPython.cpp | 87 ---------------------------
mod/{Tool.h => Common.h} | 15 +++--
mod/Event.cpp | 87 +++++++++------------------
mod/Main.cpp | 32 +++++++++-
mod/Main.h | 7 +++
mod/Module.cpp | 23 ++++---
mod/Module.h | 4 +-
mod/NBT.h | 5 +-
mod/PyBlockInstance.cpp | 94 +++++++++++++++--------------
mod/PyBlockInstance.h | 5 --
mod/PyEntity.cpp | 113 ++++++++++++++---------------------
mod/PyEntity.h | 5 --
mod/PyItemStack.cpp | 55 ++++++-----------
mod/PyItemStack.h | 5 --
mod/PyUtils.cpp | 90 ++++++++++++++++++++++++++++
mod/{CPython.h => PyUtils.h} | 90 +++++++++++++++++++++++-----
mod/Tool.cpp | 18 ------
mod/Version.h | 4 +-
20 files changed, 379 insertions(+), 390 deletions(-)
delete mode 100644 mod/CPython.cpp
rename mod/{Tool.h => Common.h} (83%)
create mode 100644 mod/Main.h
delete mode 100644 mod/PyBlockInstance.h
delete mode 100644 mod/PyEntity.h
delete mode 100644 mod/PyItemStack.h
create mode 100644 mod/PyUtils.cpp
rename mod/{CPython.h => PyUtils.h} (51%)
delete mode 100644 mod/Tool.cpp
diff --git a/BDSpyrunner.vcxproj b/BDSpyrunner.vcxproj
index 51d30517..b8c8381b 100644
--- a/BDSpyrunner.vcxproj
+++ b/BDSpyrunner.vcxproj
@@ -71,19 +71,17 @@ copy $(OutputPath)$(ProjectName).pdb ..\BDS\plugins\$(ProjectName).pdb
-
-
+
+
-
-
-
-
-
+
+
+
diff --git a/BDSpyrunner.vcxproj.filters b/BDSpyrunner.vcxproj.filters
index 464a5808..90106a4e 100644
--- a/BDSpyrunner.vcxproj.filters
+++ b/BDSpyrunner.vcxproj.filters
@@ -39,39 +39,33 @@
源文件
-
- 源文件
-
-
+
源文件
-
+
头文件
头文件
-
- 头文件
-
头文件
-
+
头文件
头文件
-
+
头文件
-
+
头文件
-
+
头文件
diff --git a/mod/CPython.cpp b/mod/CPython.cpp
deleted file mode 100644
index 54d7748f..00000000
--- a/mod/CPython.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "CPython.h"
-#include "Tool.h"
-
-std::string PyObjectToStr(PyObject* obj) {
- return PyUnicode_AsUTF8(PyObject_Repr(obj));
-}
-
-std::string PyUnicodeToStr(PyObject* obj) {
- return PyUnicode_AsUTF8(obj);
-}
-
-PyObject* StrToPyUnicode(std::string_view str) {
- //检测是否有相同字符串 return PyUnicode_InternFromString(str.data());
- return PyUnicode_FromStringAndSize(str.data(), str.size());
-}
-
-//list转vector
-std::vector ToStrArray(PyObject* list) {
- std::vector arr;
- if (PyList_Check(list)) {
- for (Py_ssize_t i = 0; i < PyList_Size(list); i++) {
- arr.push_back(PyUnicode_AsUTF8(PyList_GetItem(list, i)));
- }
- }
- return arr;
-}
-
-//Vec3转list
-PyObject* ToList(const Vec3& vec) {
- PyObject* list = PyList_New(3);
- PyList_SetItem(list, 0, PyFloat_FromDouble(vec.x));
- PyList_SetItem(list, 1, PyFloat_FromDouble(vec.y));
- PyList_SetItem(list, 2, PyFloat_FromDouble(vec.z));
- return list;
-}
-
-//方块坐标转list
-PyObject* ToList(const BlockPos& bp) {
- PyObject* list = PyList_New(3);
- PyList_SetItem(list, 0, PyLong_FromLong(bp.x));
- PyList_SetItem(list, 1, PyLong_FromLong(bp.y));
- PyList_SetItem(list, 2, PyLong_FromLong(bp.z));
- return list;
-}
-
-//打印错误信息
-void Py_PrintErrors() {
- if (PyErr_Occurred()) {
- //PyObject* type;
- //PyObject* value;
- //PyObject* traceback;
- //PyErr_Fetch(&type, &value, &traceback);
- //if (PyUnicode_Check(value)) {
- // logger.error("{}", PyUnicodeToStr(value));
- //}
- //else if (PyTuple_Check(value)) {
- // PyObject* info = reinterpret_cast(value)->args;
- // auto size = PyTuple_Size(info);
- // if (size == 1) {
- // logger.error("{}: {}", Py_TYPE(value)->tp_name, PyUnicodeToStr(PyTuple_GetItem(info, 0)));
- // }
- // else if (size == 2) {
- // logger.error("{}: {}", Py_TYPE(value)->tp_name, PyUnicodeToStr(PyTuple_GetItem(info, 0)));
- // PyObject* location = PyTuple_GetItem(info, 1);
- // logger.error("File: {} Line: {} Column: {}",
- // PyUnicodeToStr(PyTuple_GetItem(location, 0)),
- // PyObjectToStr(PyTuple_GetItem(location, 1)),
- // PyObjectToStr(PyTuple_GetItem(location, 2))
- // );
- // logger.error(" {}", PyObjectToStr(PyTuple_GetItem(location, 3)));
- // }
- //}
- //logger.info("{}", PyObjectToStr(traceback));
- //PyObject_Print(type, stdout, 0);
- //PyObject_Print(value, stdout, 0);
- //PyErr_Restore(type, value, traceback);
- PyErr_Print();
- }
-}
-
-PyGILGuard::PyGILGuard() {
- gil_ = PyGILState_Ensure();
-}
-
-PyGILGuard::~PyGILGuard() {
- PyGILState_Release(gil_);
-}
diff --git a/mod/Tool.h b/mod/Common.h
similarity index 83%
rename from mod/Tool.h
rename to mod/Common.h
index 0e9f292c..d2195549 100644
--- a/mod/Tool.h
+++ b/mod/Common.h
@@ -43,15 +43,14 @@
#include
#include
#include
-/*JSON*/
-#include
-using json_t = nlohmann::detail::value_t;
-
-//字符串转JSON,本插件采用 https://json.nlohmann.me 的JSON库
-fifo_json CompoundTagToJson(std::string_view str);
-
-bool IsPlayer(Actor* ptr);
+inline bool IsPlayer(Actor* ptr) {
+ if (ptr == nullptr)
+ return false;
+ if (ptr->getEntityTypeId() != 319)
+ return false;
+ return true;
+}
inline Logger logger("BDSpyrunner");
diff --git a/mod/Event.cpp b/mod/Event.cpp
index 58f96199..3c3a61ef 100644
--- a/mod/Event.cpp
+++ b/mod/Event.cpp
@@ -1,82 +1,37 @@
#include "Event.h"
-#include "Tool.h"
+#include "Common.h"
#include "Module.h"
using namespace std;
//事件回调助手,初始化对象将申请GIL
class Callbacker {
public:
- Callbacker(EventCode t) :
- type_(t), arg_(nullptr), gil_() {
+ Callbacker(EventCode t) {
+ type_ = t;
+ arg_ = nullptr;
}
~Callbacker() {
- //if (arg_ == nullptr)
- // logger.error("意外的空指针");
- //logger.info("{}", PyObjectToStr(arg_));
- //Py_XDECREF(arg_);
}
//事件回调
bool callback() {
- bool intercept = true;
+ bool pass = true;
//如果没有则跳过
auto& cbs = g_callback_functions[type_];
for (auto cb : cbs) {
- PyObject* result = _PyObject_FastCall(cb, &arg_, 1);
- Py_PrintErrors();
- if (result == Py_False)
- intercept = false;
- Py_XDECREF(result);
+ PyCaller pc;
+ pass = pc.call(cb, arg_) != Py_False;
}
- //Py_XDECREF(arg_);
- return intercept;
+ return pass;
}
- Callbacker& setArg(PyObject* arg) {
- arg_ = arg;
- return *this;
- }
- Callbacker& insert(string_view key, PyObject* item) {
+ template
+ Callbacker& insert(string_view key, Arg item) {
if (arg_ == nullptr)
arg_ = PyDict_New();
- PyDict_SetItemString(arg_, key.data(), item);
- Py_DECREF(item);
+ PyObject* obj = ToPyObject(item);
+ PyDict_SetItemString(arg_, key.data(), obj);
+ Py_DECREF(obj);
return *this;
}
- Callbacker& insert(string_view key, string_view item) {
- return insert(key, StrToPyUnicode(item));
- }
- Callbacker& insert(string_view key, Actor* item) {
- return insert(key, ToPyEntity(item));
- }
- Callbacker& insert(string_view key, ItemStack* item) {
- return insert(key, ToPyItemStack(item));
- }
- Callbacker& insert(string_view key, const BlockPos& item) {
- return insert(key, ToList(item));
- }
- Callbacker& insert(string_view key, BlockInstance& item) {
- return insert(key, ToPyBlockInstance(&item));
- }
- Callbacker& insert(string_view key, const Vec3& item) {
- return insert(key, ToList(item));
- }
- Callbacker& insert(string_view key, short item) {
- return insert(key, PyLong_FromLong(item));
- }
- Callbacker& insert(string_view key, int item) {
- return insert(key, PyLong_FromLong(item));
- }
- Callbacker& insert(string_view key, unsigned item) {
- return insert(key, PyLong_FromUnsignedLong(item));
- }
- Callbacker& insert(string_view key, long long item) {
- return insert(key, PyLong_FromLongLong(item));
- }
- Callbacker& insert(string_view key, unsigned long long item) {
- return insert(key, PyLong_FromUnsignedLongLong(item));
- }
- Callbacker& insert(string_view key, float item) {
- return insert(key, PyLong_FromDouble(item));
- }
private:
EventCode type_;
PyObject* arg_;
@@ -254,6 +209,9 @@ void EnableEventListener(EventCode code) {
EVENT_END;
break;
case EventCode::onWitherBossDestroy:
+ EVENT_BEGIN(WitherBossDestroyEvent);
+ //TODO: AABB and WitherBoss
+ EVENT_END;
break;
case EventCode::onPlaceBlock:
EVENT_BEGIN(PlayerPlaceBlockEvent);
@@ -265,19 +223,28 @@ void EnableEventListener(EventCode code) {
break;
case EventCode::onOpenContainer:
EVENT_BEGIN(PlayerOpenContainerEvent);
- //TODO: container
EVENT_INSERT(BlockInstance);
+ //TODO: EVENT_INSERT(Container);
EVENT_INSERT(Player);
EVENT_END;
break;
case EventCode::onCloseContainer:
EVENT_BEGIN(PlayerCloseContainerEvent);
- //TODO: container
EVENT_INSERT(BlockInstance);
+ //TODO: EVENT_INSERT(Container);
EVENT_INSERT(Player);
EVENT_END;
break;
case EventCode::onContainerChange:
+ EVENT_BEGIN(ContainerChangeEvent);
+ EVENT_INSERT(Actor);
+ EVENT_INSERT(BlockInstance);
+ //TODO: EVENT_INSERT(Container);
+ EVENT_INSERT(NewItemStack);
+ EVENT_INSERT(Player);
+ EVENT_INSERT(PreviousItemStack);
+ EVENT_INSERT(Slot);
+ EVENT_END;
break;
case EventCode::onOpenContainerScreen:
break;
diff --git a/mod/Main.cpp b/mod/Main.cpp
index 22eb52de..fa21c609 100644
--- a/mod/Main.cpp
+++ b/mod/Main.cpp
@@ -1,4 +1,6 @@
-#include "Module.h"
+#include "Main.h"
+#include "Common.h"
+#include "Module.h"
#include "NBT.h"
#include "Version.h"
@@ -8,6 +10,15 @@ using namespace std;
namespace fs = filesystem;
+//字符串转JSON,本插件采用 https://json.nlohmann.me 的JSON库
+fifo_json StrToJson(std::string_view str) {
+ try { return fifo_json::parse(str); }
+ catch (const std::exception& e) {
+ logger.error("Parsing JSON failed! {}", e.what());
+ return nullptr;
+ }
+}
+
//初始化Python类
void PyClassInit() {
if (PyType_Ready(&PyEntity_Type) < 0)
@@ -74,6 +85,23 @@ THook(int, "main", int argc, char* argv[], char* envp[]) {
return true;
}
);
+ //命令监听
+ Event::PlayerCmdEvent::subscribe(
+ [](Event::PlayerCmdEvent e) {
+ for (auto& [cmd, data] : g_commands) {
+ if (e.mCommand == cmd) {
+ PyGILGuard _gil;
+ PyObject* p = ToPyObject(e.mPlayer);
+ PyObject* result = _PyObject_FastCall(data.second, &p, 1);
+ Py_PrintErrors();
+ Py_DECREF(p);
+ Py_XDECREF(result);
+ return false;
+ }
+ }
+ return true;
+ }
+ );
return original(argc, argv, envp);
}
//Dll主函数
@@ -167,7 +195,7 @@ static Json AccessUrlForJson(const wchar_t* url) {
} while (size);
InternetCloseHandle(handle2);
InternetCloseHandle(hSession);
- return CompoundTagToJson(data);
+ return StrToJson(data);
}
//访问url
static void AccessUrlForFile(const wchar_t* url, string_view filename) {
diff --git a/mod/Main.h b/mod/Main.h
new file mode 100644
index 00000000..40384e37
--- /dev/null
+++ b/mod/Main.h
@@ -0,0 +1,7 @@
+#pragma once
+#include
+
+using json_t = nlohmann::detail::value_t;
+
+//字符串转JSON,本插件采用 https://json.nlohmann.me 的JSON库
+fifo_json StrToJson(std::string_view str);
diff --git a/mod/Module.cpp b/mod/Module.cpp
index bf9ecda7..fcf64258 100644
--- a/mod/Module.cpp
+++ b/mod/Module.cpp
@@ -21,7 +21,7 @@ constexpr int IsSlimeChunk(unsigned x, unsigned z) {
}
//获取BDS版本
static PyObject* getBDSVersion(PyObject*, PyObject*) {
- return StrToPyUnicode(Common::getGameVersionString());
+ return ToPyObject(Common::getGameVersionString());
}
//指令输出
static PyObject* logout(PyObject*, PyObject* args) {
@@ -75,17 +75,16 @@ static PyObject* getPlayerByXuid(PyObject*, PyObject* args) {
Player* p = Level::getPlayer(xuid);
if (p == nullptr)
Py_RETURN_ERROR("Failed to find player");
- return ToPyEntity(p);
+ return ToPyObject(p);
}
//获取玩家列表
static PyObject* getPlayerList(PyObject*, PyObject* args) {
PyObject* list = PyList_New(0);
- Level::forEachPlayer(
- [list](Player& p)->bool {
- PyList_Append(list, ToPyEntity(&p));
- return true;
- }
- );
+ for (auto p : Level::getAllPlayers()) {
+ PyObject* player = ToPyObject(p);
+ PyList_Append(list, player);
+ Py_DECREF(player);
+ }
return list;
}
static PyObject* setServerMotd(PyObject*, PyObject* args) {
@@ -94,7 +93,7 @@ static PyObject* setServerMotd(PyObject*, PyObject* args) {
if (Global == nullptr)
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",
- uintptr_t, ServerNetworkHandler*, const string&, bool)(Global, name, true);
+ uintptr_t, ServerNetworkHandler*, const string&, bool)(Global, name, true);
Py_RETURN_NONE;
}
//根据坐标设置方块
@@ -109,7 +108,7 @@ static PyObject* getBlock(PyObject*, PyObject* args) {
auto bi = BlockInstance::createBlockInstance(b, bp, did);
auto ubi = make_unique(bi);
- return ToPyBlockInstance(ubi.get());
+ return ToPyObject(ubi.get());
}
static PyObject* setBlock(PyObject*, PyObject* args) {
const char* name = "";
@@ -137,7 +136,7 @@ static PyObject* getStructure(PyObject*, PyObject* args) {
&ignore_entities, &ignore_blocks
);
auto st = StructureTemplate::fromWorld("name", did, pos1, pos2, ignore_entities, ignore_blocks);
- return StrToPyUnicode(CompoundTagToJson(*st.save()).dump(4));
+ return ToPyObject(CompoundTagToJson(*st.save()).dump(4));
}
//从JSON字符串NBT结构数据导出结构到指定地点
static PyObject* setStructure(PyObject*, PyObject* args) {
@@ -150,7 +149,7 @@ static PyObject* setStructure(PyObject*, PyObject* args) {
&data, &pos.x, &pos.y, &pos.z,
&did, &mir, &rot
);
- StructureTemplate::fromTag("name", *ToCompoundTag(CompoundTagToJson(data)))
+ StructureTemplate::fromTag("name", *ToCompoundTag(StrToJson(data)))
.toWorld(did, pos, mir, rot);
/*for (int x = 0; x != size.x; ++x) {
for (int y = 0; y != size.y; ++y) {
diff --git a/mod/Module.h b/mod/Module.h
index 01dd16be..f502c8dc 100644
--- a/mod/Module.h
+++ b/mod/Module.h
@@ -1,7 +1,5 @@
#pragma once
-#include "PyEntity.h"
-#include "PyItemStack.h"
-#include "PyBlockInstance.h"
+#include "PyUtils.h"
#include "Event.h"
//Py函数表
diff --git a/mod/NBT.h b/mod/NBT.h
index b2aa38fa..228b2ebc 100644
--- a/mod/NBT.h
+++ b/mod/NBT.h
@@ -1,5 +1,6 @@
#pragma once
-#include "Tool.h"
+#include "Common.h"
+#include "Main.h"
template
class serialize {
@@ -14,7 +15,7 @@ std::unique_ptr ToListTag(const fifo_json& value);
std::unique_ptr ToCompoundTag(const fifo_json& value);
inline ItemStack LoadItemFromString(std::string_view str) {
- return ItemStack::fromTag(*ToCompoundTag(CompoundTagToJson(str)));
+ return ItemStack::fromTag(*ToCompoundTag(StrToJson(str)));
}
inline ItemStack LoadItemFromJson(fifo_json data) {
return ItemStack::fromTag(*ToCompoundTag(data));
diff --git a/mod/PyBlockInstance.cpp b/mod/PyBlockInstance.cpp
index 1f95245b..d8322fc5 100644
--- a/mod/PyBlockInstance.cpp
+++ b/mod/PyBlockInstance.cpp
@@ -1,74 +1,70 @@
-#include "PyBlockInstance.h"
-#include "Tool.h"
+#include "PyUtils.h"
#include "NBT.h"
-#define Py_GET_BLOCKINSTANCE Py_GET_BLOCKINSTANCE2(nullptr)
-#define Py_GET_BLOCKINSTANCE2(ret) BlockInstance* bi = getBlock(self);if (bi == nullptr)return ret
+#define Py_GET_BLOCK auto block = reinterpret_cast(self)->block
+#define Py_GET_BLOCKPOS auto pos = reinterpret_cast(self)->pos
+#define Py_GET_DIMENSIONID auto dim = reinterpret_cast(self)->dim
using namespace std;
struct PyBlockInstance {
PyObject_HEAD;
- BlockInstance* value;
+ Block* block;
+ BlockPos pos;
+ int dim;
- static BlockInstance* getBlock(PyObject* self) {
- if (reinterpret_cast(self)->value)
- return reinterpret_cast(self)->value;
- else
- Py_RETURN_ERROR("This value pointer is nullptr");
- }
static int print(PyObject* self, FILE* file, int) {
- Py_GET_BLOCKINSTANCE2(-1);
- fputs(bi->getBlock()->getName().c_str(), file);
+ Py_GET_BLOCK;
+ fputs(block->getName().c_str(), file);
return 0;
}
static PyObject* repr(PyObject* self) {
- Py_GET_BLOCKINSTANCE2(StrToPyUnicode(""));
- return StrToPyUnicode(bi->getBlock()->getName().getString());
+ Py_GET_BLOCK;
+ return ToPyObject(block->getName().getString());
}
static Py_hash_t hash(PyObject* self) {
return reinterpret_cast(self);
}
static PyObject* str(PyObject* self) {
- Py_GET_BLOCKINSTANCE2(StrToPyUnicode(""));
- return StrToPyUnicode(bi->getBlock()->getName().getString());
+ Py_GET_BLOCK;
+ return ToPyObject(block->getName().getString());
}
static PyObject* rich_compare(PyObject* self, PyObject* other, int op) {
switch (op) {
- //<
- case Py_LT:break;
- //<=
- case Py_LE:break;
- //==
- case Py_EQ:
- if (getBlock(self) == getBlock(other))
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
+ case Py_LT:// <
+ break;
+ case Py_LE:// <=
+ break;
+ case Py_EQ:// ==
break;
- //!=
- case Py_NE:
- if (getBlock(self) != getBlock(other))
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
+ case Py_NE:// !=
+ break;
+ case Py_GT:// >
+ break;
+ case Py_GE:// >=
break;
- //>
- case Py_GT:break;
- //>=
- case Py_GE:break;
}
Py_RETURN_NOTIMPLEMENTED;
}
- static PyObject* getName(PyObject* self, PyObject*) {
- Py_GET_BLOCKINSTANCE;
- return StrToPyUnicode(bi->getBlock()->getName().getString());
+ Py_METHOD_DEFINE(getName) {
+ Py_GET_BLOCK;
+ return ToPyObject(block->getName().getString());
+ }
+ Py_METHOD_DEFINE(getPos) {
+ Py_GET_BLOCKPOS;
+ return ToPyObject(pos);
+ }
+ Py_METHOD_DEFINE(getDimensionId) {
+ Py_GET_DIMENSIONID;
+ return ToPyObject(dim);
}
inline static PyMethodDef Methods[]{
- { "getName", getName, METH_NOARGS, nullptr },
- { nullptr }
+ Py_METHOD_NOARGS(getName),
+ Py_METHOD_NOARGS(getPos),
+ Py_METHOD_NOARGS(getDimensionId),
+ Py_METHOD_END
};
};
@@ -123,8 +119,18 @@ PyTypeObject PyBlockInstance_Type{
nullptr, /* tp_finalize */
};
-PyObject* ToPyBlockInstance(BlockInstance* ptr) {
+PyObject* ToPyObject(BlockInstance* ptr) {
+ PyBlockInstance* obj = PyObject_New(PyBlockInstance, &PyBlockInstance_Type);
+ obj->block = ptr->getBlock();
+ obj->pos = ptr->getPosition();
+ obj->dim = ptr->getDimensionId();
+ return reinterpret_cast(obj);
+}
+
+PyObject* ToPyObject(BlockInstance& bi) {
PyBlockInstance* obj = PyObject_New(PyBlockInstance, &PyBlockInstance_Type);
- obj->value = ptr;
+ obj->block = bi.getBlock();
+ obj->pos = bi.getPosition();
+ obj->dim = bi.getDimensionId();
return reinterpret_cast(obj);
}
diff --git a/mod/PyBlockInstance.h b/mod/PyBlockInstance.h
deleted file mode 100644
index 52ce57a3..00000000
--- a/mod/PyBlockInstance.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-#include "CPython.h"
-
-extern PyTypeObject PyBlockInstance_Type;
-PyObject* ToPyBlockInstance(class BlockInstance* ptr);
diff --git a/mod/PyEntity.cpp b/mod/PyEntity.cpp
index dff2e104..fa962664 100644
--- a/mod/PyEntity.cpp
+++ b/mod/PyEntity.cpp
@@ -1,98 +1,77 @@
-#include "PyEntity.h"
-#include "Tool.h"
+#include "PyUtils.h"
#include "NBT.h"
#define Py_GET_PLAYER Py_GET_PLAYER2(nullptr)
-#define Py_GET_PLAYER2(ret) Player* p = getPlayer(self);if (p == nullptr)return ret
+#define Py_GET_PLAYER2(ret) auto p = reinterpret_cast(reinterpret_cast(self)->value);if (p == nullptr)return ret
#define Py_GET_ACTOR Py_GET_ACTOR2(nullptr)
-#define Py_GET_ACTOR2(ret) Actor* a = getActor(self);if (a == nullptr)return ret
+#define Py_GET_ACTOR2(ret) auto a = reinterpret_cast(self)->value;if (a == nullptr)return ret
using namespace std;
+
struct PyEntity {
PyObject_HEAD;
Actor* value;
- static Actor* getActor(PyObject* self) {
- if (reinterpret_cast(self)->value)
- return reinterpret_cast(self)->value;
- else
- Py_RETURN_ERROR("This entity pointer is nullptr");
- }
- static Player* getPlayer(PyObject* self) {
- if (IsPlayer(reinterpret_cast(self)->value))
- return reinterpret_cast(reinterpret_cast(self)->value);
- else
- Py_RETURN_ERROR("This entity pointer is nullptr or is not player pointer");
- }
static int print(PyObject* self, FILE* file, int) {
Py_GET_ACTOR2(-1);
fputs(a->getNameTag().c_str(), file);
return 0;
}
static PyObject* repr(PyObject* self) {
- Py_GET_ACTOR2(StrToPyUnicode(""));
- return StrToPyUnicode(a->getNameTag());
+ Py_GET_ACTOR2(ToPyObject(""));
+ return ToPyObject(a->getNameTag());
}
static Py_hash_t hash(PyObject* self) {
return reinterpret_cast(self);
}
static PyObject* str(PyObject* self) {
- Py_GET_ACTOR2(StrToPyUnicode(""));
- return StrToPyUnicode(a->getNameTag());
+ Py_GET_ACTOR2(ToPyObject(""));
+ return ToPyObject(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 (getActor(self) == getActor(other))
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
+ case Py_LT:// <
+ break;
+ case Py_LE:// <=
break;
- //!=
- case Py_NE:
- if (getActor(self) != getActor(other))
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
+ case Py_EQ:// ==
+ return ToPyObject(reinterpret_cast(self)->value == reinterpret_cast(other)->value);
+ case Py_NE:// !=
+ return ToPyObject(reinterpret_cast(self)->value != reinterpret_cast(other)->value);
+ case Py_GT:// >
+ break;
+ case Py_GE:// >=
break;
- //>
- case Py_GT:break;
- //>=
- case Py_GE:break;
}
Py_RETURN_NOTIMPLEMENTED;
}
//获取名字
Py_METHOD_DEFINE(getName) {
- Py_GET_ACTOR;
- return StrToPyUnicode(a->getNameTag());
+ Py_GET_ACTOR2(ToPyObject(""));
+ return ToPyObject(a->getNameTag());
}
Py_METHOD_DEFINE(setName) {
const char* name = "";
Py_PARSE("s", &name);
Py_GET_PLAYER;
p->setName(name);
+ Py_RETURN_NONE;
}
//获取UUID
Py_METHOD_DEFINE(getUuid) {
Py_GET_PLAYER;
- return StrToPyUnicode(p->getUuid());
+ return ToPyObject(p->getUuid());
}
//获取XUID
Py_METHOD_DEFINE(getXuid) {
Py_GET_PLAYER;
- return StrToPyUnicode(p->getXuid());
+ return ToPyObject(p->getXuid());
}
//获取坐标
Py_METHOD_DEFINE(getPos) {
Py_GET_ACTOR;
- return ToList(a->getPos());
+ return ToPyObject(a->getPos());
}
//获取维度ID
Py_METHOD_DEFINE(getDimensionId) {
@@ -126,14 +105,14 @@ struct PyEntity {
//string type;
//SymCall("?EntityTypeToString@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@W4ActorType@@W4ActorTypeNamespaceRules@@@Z",
// &type, a->getEntityTypeId());
- return StrToPyUnicode(a->getTypeName());
+ return ToPyObject(a->getTypeName());
}
//获取nbt数据
Py_METHOD_DEFINE(getNBT) {
Py_GET_ACTOR;
auto t = CompoundTag::create();
a->save(*t);
- return StrToPyUnicode(CompoundTagToJson(*t).dump(4));
+ return ToPyObject(CompoundTagToJson(*t).dump(4));
}
//获取生命值
Py_METHOD_DEFINE(getHealth) {
@@ -160,7 +139,7 @@ struct PyEntity {
//获取设备id
Py_METHOD_DEFINE(getPlatformOnlineId) {
Py_GET_PLAYER;
- return StrToPyUnicode(p->getPlatformOnlineId());
+ return ToPyObject(p->getPlatformOnlineId());
}
//获取设备类型
Py_METHOD_DEFINE(getPlatform) {
@@ -171,7 +150,7 @@ struct PyEntity {
Py_METHOD_DEFINE(getIP) {
Py_GET_PLAYER;
auto ni = p->getNetworkIdentifier();
- return StrToPyUnicode(Global->getAdr(*ni).ToString(false, ':'));
+ return ToPyObject(Global->getAdr(*ni).ToString(false, ':'));
}
//获取玩家所有物品
Py_METHOD_DEFINE(getAllItem) {
@@ -191,14 +170,14 @@ struct PyEntity {
}
items_json["OffHand"] = CompoundTagToJson(*p->getOffhandSlot().save());
items_json["Hand"] = CompoundTagToJson(*p->getSelectedItem().save());
- return StrToPyUnicode(items_json.dump(4));
+ return ToPyObject(items_json.dump(4));
}
//设置玩家所有物品
Py_METHOD_DEFINE(setAllItem) {
const char* items_data = "";
Py_PARSE("s", &items_data);
Py_GET_PLAYER;
- fifo_json items_json(CompoundTagToJson(items_data));
+ fifo_json items_json(StrToJson(items_data));
if (items_json.contains("Inventory")) {
auto& items = p->getInventory();
fifo_json& inventory = items_json["Inventory"];
@@ -361,10 +340,8 @@ struct PyEntity {
return nullptr;
p->sendCustomFormPacket(str,
[p, callback](string arg) {
- PyGILGuard gil;
- PyObject* result = PyObject_CallFunction(callback, "Os", ToPyEntity(p), arg.c_str());
- Py_PrintErrors();
- Py_XDECREF(result);
+ PyCaller pc;
+ pc.call(callback, p, arg);
}
);
Py_RETURN_NONE;
@@ -385,10 +362,8 @@ struct PyEntity {
Py_RETURN_ERROR("The number of buttons is not equal to the number of images");
p->sendSimpleFormPacket(title, content, buttons, images,
[p, callback](int arg) {
- PyGILGuard gil;
- PyObject* result = PyObject_CallFunction(callback, "Oi", ToPyEntity(p), arg);
- Py_PrintErrors();
- Py_XDECREF(result);
+ PyCaller pc;
+ pc.call(callback, p, arg);
}
);
Py_RETURN_NONE;
@@ -405,10 +380,8 @@ struct PyEntity {
return nullptr;
p->sendModalFormPacket(title, content, button1, button2,
[p, callback](bool arg) {
- PyGILGuard gil;
- PyObject* result = PyObject_CallFunction(callback, "OO", ToPyEntity(p), arg ? Py_True : Py_False);
- Py_PrintErrors();
- Py_XDECREF(result);
+ PyCaller pc;
+ pc.call(callback, p, arg);
}
);
Py_RETURN_NONE;
@@ -421,7 +394,7 @@ struct PyEntity {
Py_PARSE("ss|i", &title, &side_data, &order);
Py_GET_PLAYER;
vector> data;
- fifo_json value = CompoundTagToJson(side_data);
+ fifo_json value = StrToJson(side_data);
if (value.is_object())
for (auto& [key, val] : value.items()) {
data.push_back({ key, val });
@@ -470,7 +443,7 @@ struct PyEntity {
auto tags = a->getTags();
PyObject* list = PyList_New(0);
for (size_t i = 0; i < tags.size(); i++) {
- PyList_Append(list, StrToPyUnicode(tags[i]));
+ PyList_Append(list, ToPyObject(tags[i]));
}
return list;
}
@@ -480,6 +453,11 @@ struct PyEntity {
a->kill();
Py_RETURN_NONE;
}
+ //获取游戏模式
+ Py_METHOD_DEFINE(getGameMode) {
+ Py_GET_PLAYER;
+ return PyLong_FromLong(p->getPlayerGameType());
+ }
inline static PyMethodDef Methods[]{
Py_METHOD_NOARGS(getName),
@@ -528,10 +506,11 @@ struct PyEntity {
Py_METHOD_VARARGS(removeTag),
Py_METHOD_NOARGS(getTags),
Py_METHOD_NOARGS(kill),
+ Py_METHOD_NOARGS(getGameMode),
Py_METHOD_END
};
};
-//Entity类型
+
PyTypeObject PyEntity_Type{
PyVarObject_HEAD_INIT(nullptr, 0)
"Entity", /* tp_name */
@@ -583,7 +562,7 @@ PyTypeObject PyEntity_Type{
nullptr, /* tp_finalize */
};
-PyObject* ToPyEntity(Actor* ptr) {
+PyObject* ToPyObject(Actor* ptr) {
PyEntity* obj = PyObject_New(PyEntity, &PyEntity_Type);
obj->value = ptr;
return reinterpret_cast(obj);
diff --git a/mod/PyEntity.h b/mod/PyEntity.h
deleted file mode 100644
index ba40f5d4..00000000
--- a/mod/PyEntity.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-#include "CPython.h"
-
-extern PyTypeObject PyEntity_Type;
-PyObject* ToPyEntity(class Actor* ptr);
diff --git a/mod/PyItemStack.cpp b/mod/PyItemStack.cpp
index 466209c5..51203195 100644
--- a/mod/PyItemStack.cpp
+++ b/mod/PyItemStack.cpp
@@ -1,9 +1,8 @@
-#include "PyItemStack.h"
-#include "Tool.h"
+#include "PyUtils.h"
#include "NBT.h"
#define Py_GET_ITEMSTACK Py_GET_ITEMSTACK2(nullptr)
-#define Py_GET_ITEMSTACK2(ret) ItemStack* i = getItemStack(self);if (i == nullptr)return ret
+#define Py_GET_ITEMSTACK2(ret) auto i = reinterpret_cast(self)->value;if (i == nullptr)return ret
using namespace std;
@@ -11,63 +10,47 @@ struct PyItemStack {
PyObject_HEAD;
ItemStack* value;
- static ItemStack* getItemStack(PyObject* self) {
- if (reinterpret_cast(self)->value)
- return reinterpret_cast(self)->value;
- else
- Py_RETURN_ERROR("This value pointer is nullptr");
- }
static int print(PyObject* self, FILE* file, int) {
Py_GET_ITEMSTACK2(-1);
fputs(i->getName().c_str(), file);
return 0;
}
static PyObject* repr(PyObject* self) {
- Py_GET_ITEMSTACK2(StrToPyUnicode(""));
- return StrToPyUnicode(i->getName());
+ Py_GET_ITEMSTACK2(ToPyObject(""));
+ return ToPyObject(i->getName());
}
static Py_hash_t hash(PyObject* self) {
return reinterpret_cast(self);
}
static PyObject* str(PyObject* self) {
- Py_GET_ITEMSTACK2(StrToPyUnicode(""));
- return StrToPyUnicode(i->getName());
+ Py_GET_ITEMSTACK2(ToPyObject(""));
+ return ToPyObject(i->getName());
}
static PyObject* rich_compare(PyObject* self, PyObject* other, int op) {
switch (op) {
- //<
- case Py_LT:break;
- //<=
- case Py_LE:break;
- //==
- case Py_EQ:
- if (getItemStack(self) == getItemStack(other))
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
+ case Py_LT:// <
+ break;
+ case Py_LE:// <=
+ break;
+ case Py_EQ:// ==
+ return ToPyObject(reinterpret_cast(self)->value == reinterpret_cast(other)->value);
+ case Py_NE:// !=
+ return ToPyObject(reinterpret_cast(self)->value != reinterpret_cast(other)->value);
+ case Py_GT:// >
break;
- //!=
- case Py_NE:
- if (getItemStack(self) != getItemStack(other))
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
+ case Py_GE:// >=
break;
- //>
- case Py_GT:break;
- //>=
- case Py_GE:break;
}
Py_RETURN_NOTIMPLEMENTED;
}
Py_METHOD_DEFINE(getName) {
Py_GET_ITEMSTACK;
- return StrToPyUnicode(i->getName());
+ return ToPyObject(i->getName());
}
Py_METHOD_DEFINE(getNBT) {
Py_GET_ITEMSTACK;
- return StrToPyUnicode(CompoundTagToJson(*i->getNbt()));
+ return ToPyObject(CompoundTagToJson(*i->getNbt()).dump(4));
}
inline static PyMethodDef Methods[]{
@@ -128,7 +111,7 @@ PyTypeObject PyItemStack_Type{
nullptr, /* tp_finalize */
};
-PyObject* ToPyItemStack(ItemStack* ptr) {
+PyObject* ToPyObject(ItemStack* ptr) {
PyItemStack* obj = PyObject_New(PyItemStack, &PyItemStack_Type);
obj->value = ptr;
return reinterpret_cast(obj);
diff --git a/mod/PyItemStack.h b/mod/PyItemStack.h
deleted file mode 100644
index 1cbad45f..00000000
--- a/mod/PyItemStack.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-#include "CPython.h"
-
-extern PyTypeObject PyItemStack_Type;
-PyObject* ToPyItemStack(class ItemStack* ptr);
diff --git a/mod/PyUtils.cpp b/mod/PyUtils.cpp
new file mode 100644
index 00000000..540b5e40
--- /dev/null
+++ b/mod/PyUtils.cpp
@@ -0,0 +1,90 @@
+#include "PyUtils.h"
+#include "Common.h"
+
+
+//打印错误信息
+void Py_PrintErrors() {
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ }
+}
+
+//PyObject转string
+std::string PyObjectToStr(PyObject* obj) {
+ return PyUnicode_AsUTF8(PyObject_Repr(obj));
+}
+
+//PyObject转string
+std::string PyUnicodeToStr(PyObject* obj) {
+ return PyUnicode_AsUTF8(obj);
+}
+
+//list转vector
+std::vector ToStrArray(PyObject* list) {
+ std::vector arr;
+ if (PyList_Check(list)) {
+ for (Py_ssize_t i = 0; i < PyList_Size(list); i++) {
+ arr.push_back(PyUnicode_AsUTF8(PyList_GetItem(list, i)));
+ }
+ }
+ return arr;
+}
+
+PyObject* ToPyObject(PyObject* obj) {
+ return obj;
+}
+
+PyObject* ToPyObject(std::string_view str) {
+ return PyUnicode_FromStringAndSize(str.data(), str.size());
+}
+
+//string转Unicode
+PyObject* ToPyObject(const std::string& str) {
+ return PyUnicode_FromStringAndSize(str.data(), str.size());
+}
+
+PyObject* ToPyObject(const char* str) {
+ return PyUnicode_FromString(str);
+}
+
+//Vec3转list
+PyObject* ToPyObject(const Vec3& vec) {
+ PyObject* list = PyList_New(3);
+ PyList_SetItem(list, 0, PyFloat_FromDouble(vec.x));
+ PyList_SetItem(list, 1, PyFloat_FromDouble(vec.y));
+ PyList_SetItem(list, 2, PyFloat_FromDouble(vec.z));
+ return list;
+}
+
+//方块坐标转list
+PyObject* ToPyObject(const BlockPos& bp) {
+ PyObject* list = PyList_New(3);
+ PyList_SetItem(list, 0, PyLong_FromLong(bp.x));
+ PyList_SetItem(list, 1, PyLong_FromLong(bp.y));
+ PyList_SetItem(list, 2, PyLong_FromLong(bp.z));
+ return list;
+}
+
+PyObject* ToPyObject(bool b) {
+ if (b)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
+PyObject* ToPyObject(short s) {
+ return PyLong_FromLong(s);
+}
+
+PyObject* ToPyObject(int i) {
+ return PyLong_FromLong(i);
+}
+
+PyObject* ToPyObject(long long l) {
+ return PyLong_FromLongLong(l);
+}
+
+PyObject* ToPyObject(double d) {
+ return PyFloat_FromDouble(d);
+}
+
diff --git a/mod/CPython.h b/mod/PyUtils.h
similarity index 51%
rename from mod/CPython.h
rename to mod/PyUtils.h
index e1f4c93b..8c3a2d1b 100644
--- a/mod/CPython.h
+++ b/mod/PyUtils.h
@@ -1,7 +1,7 @@
#pragma once
#define PY_SSIZE_T_CLEAN
#include "../include/Python.h"
-#include
+#include "Common.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 }
@@ -28,23 +28,83 @@
// Py_END_ALLOW_THREADS;\
// if (!_has_gil)PyGILState_Release(_gil_state)
+//打印错误信息
+void Py_PrintErrors();
+//PyObject转string
+std::string PyObjectToStr(PyObject* obj);
+//PyObject转string
+std::string PyUnicodeToStr(PyObject* obj);
+//list转vector
+std::vector ToStrArray(PyObject* list);
+//PyObject转PyObject
+PyObject* ToPyObject(PyObject* obj);
+//string转PyUnicode
+PyObject* ToPyObject(std::string_view str);
+//string转PyUnicode
+PyObject* ToPyObject(const std::string& str);
+//string转PyUnicode
+PyObject* ToPyObject(const char* str);
+//Vec3转list
+PyObject* ToPyObject(const Vec3& vec);
+//BlockPos转list
+PyObject* ToPyObject(const BlockPos& bp);
+//bool转PyObject
+PyObject* ToPyObject(bool b);
+//short转PyObject
+PyObject* ToPyObject(short s);
+//int转PyObject
+PyObject* ToPyObject(int i);
+//long long转PyObject
+PyObject* ToPyObject(long long l);
+//double转PyObject
+PyObject* ToPyObject(double d);
+
+extern PyTypeObject PyBlockInstance_Type;
+PyObject* ToPyObject(BlockInstance* ptr);
+PyObject* ToPyObject(BlockInstance& bi);
+
+extern PyTypeObject PyEntity_Type;
+PyObject* ToPyObject(Actor* ptr);
+
+extern PyTypeObject PyItemStack_Type;
+PyObject* ToPyObject(ItemStack* ptr);
+
class PyGILGuard {
public:
- PyGILGuard();
- ~PyGILGuard();
+ PyGILGuard() {
+ gil_ = PyGILState_Ensure();
+ }
+ ~PyGILGuard() {
+ PyGILState_Release(gil_);
+ }
private:
PyGILState_STATE gil_;
};
-std::string PyObjectToStr(PyObject* obj);
-std::string PyUnicodeToStr(PyObject* obj);
-//字符串转Unicode
-PyObject* StrToPyUnicode(std::string_view str);
-//list转vector
-std::vector ToStrArray(PyObject* list);
-//Vec3转list
-PyObject* ToList(const Vec3& vec);
-//方块坐标转list
-PyObject* ToList(const BlockPos& bp);
-//打印错误信息
-void Py_PrintErrors();
\ No newline at end of file
+class PyCaller {
+public:
+ PyCaller() {
+ }
+ ~PyCaller() {
+ Py_DECREF(result_);
+ }
+ PyObject* callVector(PyObject* func, const vector& args) {
+ return result_ = _PyObject_FastCall(func, args.data(), args.size());
+ }
+ template
+ PyObject* call(PyObject* func, Args... args) {
+ vector vargs;
+ (vargs.push_back(ToPyObject(args)), ...);
+ callVector(func, vargs);
+ Py_PrintErrors();
+ for (auto arg : vargs) {
+ Py_DECREF(arg);
+ }
+ return result_;
+ }
+
+private:
+ PyGILGuard gil_;
+ vector args_;
+ PyObject* result_;
+};
diff --git a/mod/Tool.cpp b/mod/Tool.cpp
deleted file mode 100644
index 064c8524..00000000
--- a/mod/Tool.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "Tool.h"
-
-//字符串转JSON,本插件采用 https://json.nlohmann.me 的JSON库
-fifo_json CompoundTagToJson(std::string_view str) {
- try { return fifo_json::parse(str); }
- catch (const std::exception& e) {
- logger.error("Parsing JSON failed! {}", e.what());
- return nullptr;
- }
-}
-
-bool IsPlayer(Actor* ptr) {
- if (ptr == nullptr)
- return false;
- if (ptr->getEntityTypeId() != 319)
- return false;
- return true;
-}
diff --git a/mod/Version.h b/mod/Version.h
index 5c64fba2..9d7c365f 100644
--- a/mod/Version.h
+++ b/mod/Version.h
@@ -1,5 +1,5 @@
#pragma once
constexpr unsigned PYR_VERSION_MAJOR = 1;
constexpr unsigned PYR_VERSION_MINOR = 9;
-constexpr unsigned PYR_VERSION_MICRO = 5;
-constexpr const char* PYR_VERSION = "v1.9.5";
\ No newline at end of file
+constexpr unsigned PYR_VERSION_MICRO = 6;
+constexpr const char* PYR_VERSION = "v1.9.6";
\ No newline at end of file