From 7cd7341d6ce66d8545d255006276d03a2ef1a03f Mon Sep 17 00:00:00 2001 From: odorajbotoj Date: Sat, 12 Oct 2024 21:11:41 +0800 Subject: [PATCH] set export and refactor lua api --- CHANGELOG.md | 1 + src/cfsp/CFSP.cpp | 11 +- src/cfsp/base/Macros.h | 12 +- src/cfsp/base/Mod.h | 9 - src/cfsp/commands/Sp.cpp | 193 +- src/cfsp/simplayer/CFSP.h | 146 +- src/cfsp/simplayer/SimPlayer.cpp | 26 +- src/cfsp/simplayer/luaapi/BlockInfo.cpp | 305 +++ src/cfsp/simplayer/luaapi/BlockInfo.h | 146 ++ src/cfsp/simplayer/luaapi/BlockPos.cpp | 203 ++ src/cfsp/simplayer/luaapi/BlockPos.h | 54 + src/cfsp/simplayer/luaapi/BlockSource.cpp | 61 + src/cfsp/simplayer/luaapi/BlockSource.h | 26 + src/cfsp/simplayer/luaapi/ItemInfo.cpp | 363 ++++ src/cfsp/simplayer/luaapi/ItemInfo.h | 167 ++ src/cfsp/simplayer/luaapi/Level.cpp | 87 + src/cfsp/simplayer/luaapi/Level.h | 32 + src/cfsp/simplayer/luaapi/Log.cpp | 26 + src/cfsp/simplayer/luaapi/Log.h | 17 + src/cfsp/simplayer/luaapi/SimPlayer.cpp | 575 ++++++ src/cfsp/simplayer/luaapi/SimPlayer.h | 90 + src/cfsp/simplayer/luaapi/SpLuaApi.cpp | 2117 +-------------------- src/cfsp/simplayer/luaapi/SpLuaApi.h | 2 +- src/cfsp/simplayer/luaapi/Utils.cpp | 104 + src/cfsp/simplayer/luaapi/Utils.h | 24 + src/cfsp/simplayer/luaapi/Vec2.cpp | 193 ++ src/cfsp/simplayer/luaapi/Vec2.h | 56 + src/cfsp/simplayer/luaapi/Vec3.cpp | 225 +++ src/cfsp/simplayer/luaapi/Vec3.h | 62 + xmake.lua | 1 + 30 files changed, 3039 insertions(+), 2295 deletions(-) create mode 100644 src/cfsp/simplayer/luaapi/BlockInfo.cpp create mode 100644 src/cfsp/simplayer/luaapi/BlockInfo.h create mode 100644 src/cfsp/simplayer/luaapi/BlockPos.cpp create mode 100644 src/cfsp/simplayer/luaapi/BlockPos.h create mode 100644 src/cfsp/simplayer/luaapi/BlockSource.cpp create mode 100644 src/cfsp/simplayer/luaapi/BlockSource.h create mode 100644 src/cfsp/simplayer/luaapi/ItemInfo.cpp create mode 100644 src/cfsp/simplayer/luaapi/ItemInfo.h create mode 100644 src/cfsp/simplayer/luaapi/Level.cpp create mode 100644 src/cfsp/simplayer/luaapi/Level.h create mode 100644 src/cfsp/simplayer/luaapi/Log.cpp create mode 100644 src/cfsp/simplayer/luaapi/Log.h create mode 100644 src/cfsp/simplayer/luaapi/SimPlayer.cpp create mode 100644 src/cfsp/simplayer/luaapi/SimPlayer.h create mode 100644 src/cfsp/simplayer/luaapi/Utils.cpp create mode 100644 src/cfsp/simplayer/luaapi/Utils.h create mode 100644 src/cfsp/simplayer/luaapi/Vec2.cpp create mode 100644 src/cfsp/simplayer/luaapi/Vec2.h create mode 100644 src/cfsp/simplayer/luaapi/Vec3.cpp create mode 100644 src/cfsp/simplayer/luaapi/Vec3.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 69a870c..1a97c49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,5 +10,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added + Move CoralFans SimulatedPlayer System from [CoralFans](https://github.com/CoralFans-Dev/CoralFans) to here ++ Added Script Arg [1.0.0]: https://github.com/CoralFans-Dev/CFSP/releases/tag/v1.0.0 diff --git a/src/cfsp/CFSP.cpp b/src/cfsp/CFSP.cpp index e228d17..3a8e831 100644 --- a/src/cfsp/CFSP.cpp +++ b/src/cfsp/CFSP.cpp @@ -1,6 +1,8 @@ #include "cfsp/CFSP.h" #include "cfsp/base/Mod.h" #include "cfsp/commands/Command.h" +#include "cfsp/simplayer/CFSP.h" +#include "cfsp/simplayer/Hooks.h" #include "ll/api/Config.h" #include "ll/api/i18n/I18n.h" #include "ll/api/mod/RegisterHelper.h" @@ -42,6 +44,8 @@ bool CFSP::load() { bool CFSP::enable() { auto& mod = coral_fans::cfsp::mod(); + hookSimPlayer(true); + // get DefaultDataLoadHelper mod.getDefaultDataLoadHelper() = static_cast(ll::memory::resolveSymbol("??_7DefaultDataLoadHelper@@6B@")); @@ -53,12 +57,15 @@ bool CFSP::enable() { if (mod.getConfig().command.sp.enabled) commands::registerSpCommand(mod.getConfig().command.sp.permission); // load simplayer data - mod.getSimPlayerManager().load(); + SimPlayerManager::getInstance().load(); return true; } -bool CFSP::disable() { return true; } +bool CFSP::disable() { + hookSimPlayer(false); + return true; +} } // namespace coral_fans::cfsp diff --git a/src/cfsp/base/Macros.h b/src/cfsp/base/Macros.h index 9d5217a..2dae17c 100644 --- a/src/cfsp/base/Macros.h +++ b/src/cfsp/base/Macros.h @@ -22,10 +22,16 @@ break; \ } +#ifdef CFSPEXP +#define CFSP_API __declspec(dllexport) +#else +#define CFSP_API __declspec(dllimport) +#endif + // SimPlayer reg def #define SP_REG_DEF(NAME, ...) \ - std::pair simPlayer##NAME(Player*, std::string const&, bool, __VA_ARGS__); \ - std::pair group##NAME(Player*, std::string const&, __VA_ARGS__); + CFSP_API std::pair simPlayer##NAME(Player*, std::string const&, bool, __VA_ARGS__); \ + CFSP_API std::pair group##NAME(Player*, std::string const&, __VA_ARGS__); // SimPlayer def with arg #define SP_DEF_WA(NAME, ACTION, ARG_TYPE) \ @@ -192,7 +198,7 @@ return {"translate.simplayer.success"_tr(), true}; \ } -#define LUAAPI(name) static int lua_api_##name(lua_State* L) +#define LUAAPI(name) int lua_api_##name(lua_State* L) #define LUA_ARG_COUNT_CHECK_C(i) \ if (lua_gettop(L) != (i)) return luaL_error(L, "%d args expected", (i)); diff --git a/src/cfsp/base/Mod.h b/src/cfsp/base/Mod.h index b1d7031..656df08 100644 --- a/src/cfsp/base/Mod.h +++ b/src/cfsp/base/Mod.h @@ -1,7 +1,6 @@ #pragma once #include "cfsp/Config.h" -#include "cfsp/simplayer/CFSP.h" #include "mc/dataloadhelper/DefaultDataLoadHelper.h" @@ -10,19 +9,11 @@ namespace coral_fans::cfsp { class CFSPMod { private: config::Config mConfig; - SimPlayerManager mSimPlayerManager; DefaultDataLoadHelper* mDefaultDataLoadHelper; public: inline config::Config& getConfig() { return this->mConfig; } - inline SimPlayerManager& getSimPlayerManager() { return this->mSimPlayerManager; } inline DefaultDataLoadHelper*& getDefaultDataLoadHelper() { return this->mDefaultDataLoadHelper; } - -public: - inline void tick() { mSimPlayerManager.tick(); } - -public: - const std::string VERSION = "1.0.0"; }; CFSPMod& mod(); diff --git a/src/cfsp/commands/Sp.cpp b/src/cfsp/commands/Sp.cpp index 97da5da..2d8a5a9 100644 --- a/src/cfsp/commands/Sp.cpp +++ b/src/cfsp/commands/Sp.cpp @@ -1,6 +1,7 @@ #include "cfsp/Config.h" #include "cfsp/base/Macros.h" #include "cfsp/base/Mod.h" +#include "cfsp/simplayer/CFSP.h" #include "ll/api/command/CommandHandle.h" #include "ll/api/command/CommandRegistrar.h" #include "ll/api/command/runtime/ParamKind.h" @@ -72,6 +73,17 @@ void registerSpCommand(CommandPermissionLevel permission) { ll::command::CommandRegistrar::getInstance().tryRegisterSoftEnum("spname", {}); ll::command::CommandRegistrar::getInstance().tryRegisterSoftEnum("gname", {}); + // sp version + spCommand.overload().text("version").execute([](CommandOrigin const&, CommandOutput& output) { +#ifdef VERSION + output.success(VERSION); +#endif +#ifdef COMMITID + output.success("Commit ID: {}", COMMITID); +#endif + output.success("SimPlayerManager Version: {}\n - SimPlayerInfo Version: {}", MANAGER_VERSION, INFO_VERSION); + }); + // sp c autorespawn spCommand.runtimeOverload() .text("c") @@ -81,7 +93,7 @@ void registerSpCommand(CommandPermissionLevel permission) { auto& mod = coral_fans::cfsp::mod(); if (origin.getPermissionsLevel() < mod.getConfig().simPlayer.adminPermission) return output.error("command.sp.error.permissiondenied"_tr()); - mod.getSimPlayerManager().setAutoRespawn(self["isopen"].get()); + SimPlayerManager::getInstance().setAutoRespawn(self["isopen"].get()); output.success("command.sp.success"_tr()); }); @@ -94,21 +106,21 @@ void registerSpCommand(CommandPermissionLevel permission) { auto& mod = coral_fans::cfsp::mod(); if (origin.getPermissionsLevel() < mod.getConfig().simPlayer.adminPermission) return output.error("command.sp.error.permissiondenied"_tr()); - mod.getSimPlayerManager().setAutoJoin(self["isopen"].get()); + SimPlayerManager::getInstance().setAutoJoin(self["isopen"].get()); output.success("command.sp.success"_tr()); }); // sp list g spCommand.runtimeOverload().text("list").text("g").execute( [](CommandOrigin const&, CommandOutput& output, ll::command::RuntimeCommand const&) { - output.success(coral_fans::cfsp::mod().getSimPlayerManager().listGroup()); + output.success(coral_fans::cfsp::SimPlayerManager::getInstance().listGroup()); } ); // sp list p spCommand.runtimeOverload().text("list").text("p").execute( [](CommandOrigin const&, CommandOutput& output, ll::command::RuntimeCommand const&) { - output.success(coral_fans::cfsp::mod().getSimPlayerManager().listSimPlayer()); + output.success(coral_fans::cfsp::SimPlayerManager::getInstance().listSimPlayer()); } ); @@ -120,8 +132,10 @@ void registerSpCommand(CommandPermissionLevel permission) { .execute([](CommandOrigin const& origin, CommandOutput& output, ll::command::RuntimeCommand const& self) { COMMAND_CHECK_PLAYER COMMAND_SIMPLAYER_CHECKPERMLIST - auto rst = - mod.getSimPlayerManager().createGroup(player, self["name"].get()); + auto rst = SimPlayerManager::getInstance().createGroup( + player, + self["name"].get() + ); if (rst.second) output.success(rst.first); else output.error(rst.first); }); @@ -134,7 +148,7 @@ void registerSpCommand(CommandPermissionLevel permission) { .execute([](CommandOrigin const& origin, CommandOutput& output, ll::command::RuntimeCommand const& self) { COMMAND_CHECK_PLAYER COMMAND_SIMPLAYER_CHECKPERMLIST - auto rst = coral_fans::cfsp::mod().getSimPlayerManager().deleteGroup( + auto rst = coral_fans::cfsp::SimPlayerManager::getInstance().deleteGroup( player, self["name"].get() ); @@ -151,7 +165,7 @@ void registerSpCommand(CommandPermissionLevel permission) { .execute([](CommandOrigin const& origin, CommandOutput& output, ll::command::RuntimeCommand const& self) { COMMAND_CHECK_PLAYER COMMAND_SIMPLAYER_CHECKPERMLIST - auto rst = coral_fans::cfsp::mod().getSimPlayerManager().addSpToGroup( + auto rst = coral_fans::cfsp::SimPlayerManager::getInstance().addSpToGroup( player, self["name"].get(), self["simplayer"].get() @@ -169,7 +183,7 @@ void registerSpCommand(CommandPermissionLevel permission) { .execute([](CommandOrigin const& origin, CommandOutput& output, ll::command::RuntimeCommand const& self) { COMMAND_CHECK_PLAYER COMMAND_SIMPLAYER_CHECKPERMLIST - auto rst = coral_fans::cfsp::mod().getSimPlayerManager().rmSpFromGroup( + auto rst = coral_fans::cfsp::SimPlayerManager::getInstance().rmSpFromGroup( player, self["name"].get(), self["simplayer"].get() @@ -189,7 +203,7 @@ void registerSpCommand(CommandPermissionLevel permission) { COMMAND_SIMPLAYER_CHECKPERMLIST if (self["player"].get().results(origin).size() != 1) return output.error("command.sp.error.toomanyobj"_tr()); - auto rst = coral_fans::cfsp::mod().getSimPlayerManager().addAdminToGroup( + auto rst = coral_fans::cfsp::SimPlayerManager::getInstance().addAdminToGroup( player, self["name"].get(), self["player"].get().results(origin).data->front() @@ -209,7 +223,7 @@ void registerSpCommand(CommandPermissionLevel permission) { COMMAND_SIMPLAYER_CHECKPERMLIST if (self["player"].get().results(origin).size() != 1) return output.error("command.sp.error.toomanyobj"_tr()); - auto rst = coral_fans::cfsp::mod().getSimPlayerManager().rmAdminFromGroup( + auto rst = coral_fans::cfsp::SimPlayerManager::getInstance().rmAdminFromGroup( player, self["name"].get(), self["player"].get().results(origin).data->front() @@ -226,7 +240,7 @@ void registerSpCommand(CommandPermissionLevel permission) { .execute([](CommandOrigin const& origin, CommandOutput& output, ll::command::RuntimeCommand const& self) { COMMAND_CHECK_PLAYER COMMAND_SIMPLAYER_CHECKPERMLIST - auto rst = coral_fans::cfsp::mod().getSimPlayerManager().spawnSimPlayer( + auto rst = coral_fans::cfsp::SimPlayerManager::getInstance().spawnSimPlayer( player, self["name"].get(), player->getFeetPos(), @@ -246,7 +260,7 @@ void registerSpCommand(CommandPermissionLevel permission) { .execute([](CommandOrigin const& origin, CommandOutput& output, ll::command::RuntimeCommand const& self) { COMMAND_CHECK_PLAYER COMMAND_SIMPLAYER_CHECKPERMLIST - auto rst = coral_fans::cfsp::mod().getSimPlayerManager().spawnSimPlayer( + auto rst = coral_fans::cfsp::SimPlayerManager::getInstance().spawnSimPlayer( player, self["name"].get(), self["pos"].get().getPosition(player->getFeetPos()), @@ -269,7 +283,7 @@ void registerSpCommand(CommandPermissionLevel permission) { .execute([](CommandOrigin const& origin, CommandOutput& output, ll::command::RuntimeCommand const& self) { COMMAND_CHECK_PLAYER COMMAND_SIMPLAYER_CHECKPERMLIST - auto rst = coral_fans::cfsp::mod().getSimPlayerManager().spawnSimPlayer( + auto rst = coral_fans::cfsp::SimPlayerManager::getInstance().spawnSimPlayer( player, self["name"].get(), self["pos"].get().getPosition(player->getFeetPos()), @@ -287,7 +301,7 @@ void registerSpCommand(CommandPermissionLevel permission) { .execute([](CommandOrigin const& origin, CommandOutput& output, ll::command::RuntimeCommand const& self) { COMMAND_CHECK_PLAYER COMMAND_SIMPLAYER_CHECKPERMLIST - auto rst = coral_fans::cfsp::mod().getSimPlayerManager().spawnGroup( + auto rst = coral_fans::cfsp::SimPlayerManager::getInstance().spawnGroup( player, self["name"].get() ); @@ -302,14 +316,11 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, {}, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().despawnSimPlayer( - player, - self["name"].get(), - false - ); + return coral_fans::cfsp::SimPlayerManager::getInstance() + .despawnSimPlayer(player, self["name"].get(), false); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().despawnGroup( + return coral_fans::cfsp::SimPlayerManager::getInstance().despawnGroup( player, self["name"].get() ); @@ -322,14 +333,11 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, {}, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().rmSimPlayer( - player, - self["name"].get(), - false - ); + return coral_fans::cfsp::SimPlayerManager::getInstance() + .rmSimPlayer(player, self["name"].get(), false); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().rmGroup( + return coral_fans::cfsp::SimPlayerManager::getInstance().rmGroup( player, self["name"].get() ); @@ -342,14 +350,11 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, {}, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().respawnSimPlayer( - player, - self["name"].get(), - false - ); + return coral_fans::cfsp::SimPlayerManager::getInstance() + .respawnSimPlayer(player, self["name"].get(), false); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().respawnGroup( + return coral_fans::cfsp::SimPlayerManager::getInstance().respawnGroup( player, self["name"].get() ); @@ -362,14 +367,11 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, {}, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerStop( - player, - self["name"].get(), - false - ); + return coral_fans::cfsp::SimPlayerManager::getInstance() + .simPlayerStop(player, self["name"].get(), false); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupStop( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupStop( player, self["name"].get() ); @@ -386,7 +388,7 @@ void registerSpCommand(CommandPermissionLevel permission) { enableArg, {}, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerSneaking( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerSneaking( player, self["name"].get(), false, @@ -394,7 +396,7 @@ void registerSpCommand(CommandPermissionLevel permission) { ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupSneaking( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupSneaking( player, self["name"].get(), self["enable"].get() @@ -408,7 +410,7 @@ void registerSpCommand(CommandPermissionLevel permission) { enableArg, {}, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerSwimming( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerSwimming( player, self["name"].get(), false, @@ -416,7 +418,7 @@ void registerSpCommand(CommandPermissionLevel permission) { ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupSwimming( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupSwimming( player, self["name"].get(), self["enable"].get() @@ -435,7 +437,7 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, taskArg, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerAttack( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerAttack( player, self["name"].get(), false, @@ -444,7 +446,7 @@ void registerSpCommand(CommandPermissionLevel permission) { ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupAttack( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupAttack( player, self["name"].get(), self["interval"].has_value() ? self["interval"].get() : 20, @@ -463,7 +465,7 @@ void registerSpCommand(CommandPermissionLevel permission) { strArg, taskArg, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerChat( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerChat( player, self["name"].get(), false, @@ -473,7 +475,7 @@ void registerSpCommand(CommandPermissionLevel permission) { ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupChat( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupChat( player, self["name"].get(), self["message"].get(), @@ -489,7 +491,7 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, taskArg, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerDestroy( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerDestroy( player, self["name"].get(), false, @@ -498,7 +500,7 @@ void registerSpCommand(CommandPermissionLevel permission) { ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupDestroy( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupDestroy( player, self["name"].get(), self["interval"].has_value() ? self["interval"].get() : 20, @@ -513,14 +515,11 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, {}, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerDropSelectedItem( - player, - self["name"].get(), - false - ); + return coral_fans::cfsp::SimPlayerManager::getInstance() + .simPlayerDropSelectedItem(player, self["name"].get(), false); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupDropSelectedItem( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupDropSelectedItem( player, self["name"].get() ); @@ -533,14 +532,11 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, {}, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerDropInv( - player, - self["name"].get(), - false - ); + return coral_fans::cfsp::SimPlayerManager::getInstance() + .simPlayerDropInv(player, self["name"].get(), false); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupDropInv( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupDropInv( player, self["name"].get() ); @@ -554,7 +550,7 @@ void registerSpCommand(CommandPermissionLevel permission) { .execute([](CommandOrigin const& origin, CommandOutput& output, ll::command::RuntimeCommand const& self) { COMMAND_CHECK_PLAYER COMMAND_SIMPLAYER_CHECKPERMLIST - auto rst = coral_fans::cfsp::mod().getSimPlayerManager().simPlayerSwap( + auto rst = coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerSwap( player, self["name"].get() ); @@ -568,7 +564,7 @@ void registerSpCommand(CommandPermissionLevel permission) { strArg, taskArg, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerRunCmd( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerRunCmd( player, self["name"].get(), false, @@ -578,7 +574,7 @@ void registerSpCommand(CommandPermissionLevel permission) { ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupRunCmd( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupRunCmd( player, self["name"].get(), self["str"].get(), @@ -598,7 +594,7 @@ void registerSpCommand(CommandPermissionLevel permission) { itemArg, {}, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerSelect( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerSelect( player, self["name"].get(), false, @@ -606,7 +602,7 @@ void registerSpCommand(CommandPermissionLevel permission) { ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupSelect( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupSelect( player, self["name"].get(), self["item"].get().getId() @@ -620,7 +616,7 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, taskArg, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerInteract( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerInteract( player, self["name"].get(), false, @@ -629,7 +625,7 @@ void registerSpCommand(CommandPermissionLevel permission) { ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupInteract( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupInteract( player, self["name"].get(), self["interval"].has_value() ? self["interval"].get() : 20, @@ -644,7 +640,7 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, taskArg, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerJump( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerJump( player, self["name"].get(), false, @@ -653,7 +649,7 @@ void registerSpCommand(CommandPermissionLevel permission) { ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupJump( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupJump( player, self["name"].get(), self["interval"].has_value() ? self["interval"].get() : 20, @@ -674,7 +670,7 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, useTaskArg, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerUse( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerUse( player, self["name"].get(), false, @@ -684,7 +680,7 @@ void registerSpCommand(CommandPermissionLevel permission) { ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupUse( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupUse( player, self["name"].get(), self["tick"].has_value() ? self["tick"].get() : 40, @@ -700,7 +696,7 @@ void registerSpCommand(CommandPermissionLevel permission) { {}, taskArg, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerBuild( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerBuild( player, self["name"].get(), false, @@ -709,7 +705,7 @@ void registerSpCommand(CommandPermissionLevel permission) { ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupBuild( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupBuild( player, self["name"].get(), self["interval"].has_value() ? self["interval"].get() : 20, @@ -737,8 +733,7 @@ void registerSpCommand(CommandPermissionLevel permission) { else if (hit.mType == HitResultType::Tile) pos = hit.mPos; else pos = player->getPosition(); } - return coral_fans::cfsp::mod() - .getSimPlayerManager() + return coral_fans::cfsp::SimPlayerManager::getInstance() .simPlayerLookAt(player, self["name"].get(), false, pos); }, [](Player* player, ll::command::RuntimeCommand const& self) { @@ -751,11 +746,8 @@ void registerSpCommand(CommandPermissionLevel permission) { else if (hit.mType == HitResultType::Tile) pos = hit.mPos; else pos = player->getPosition(); } - return coral_fans::cfsp::mod().getSimPlayerManager().groupLookAt( - player, - self["name"].get(), - pos - ); + return coral_fans::cfsp::SimPlayerManager::getInstance() + .groupLookAt(player, self["name"].get(), pos); } ); @@ -773,8 +765,7 @@ void registerSpCommand(CommandPermissionLevel permission) { if (hit) pos = hit.mPos; else pos = player->getFeetPos(); } - return coral_fans::cfsp::mod() - .getSimPlayerManager() + return coral_fans::cfsp::SimPlayerManager::getInstance() .simPlayerMoveTo(player, self["name"].get(), false, pos); }, [](Player* player, ll::command::RuntimeCommand const& self) { @@ -786,11 +777,8 @@ void registerSpCommand(CommandPermissionLevel permission) { if (hit) pos = hit.mPos; else pos = player->getFeetPos(); } - return coral_fans::cfsp::mod().getSimPlayerManager().groupMoveTo( - player, - self["name"].get(), - pos - ); + return coral_fans::cfsp::SimPlayerManager::getInstance() + .groupMoveTo(player, self["name"].get(), pos); } ); @@ -808,8 +796,7 @@ void registerSpCommand(CommandPermissionLevel permission) { if (hit) pos = hit.mPos; else pos = player->getFeetPos(); } - return coral_fans::cfsp::mod() - .getSimPlayerManager() + return coral_fans::cfsp::SimPlayerManager::getInstance() .simPlayerNavTo(player, self["name"].get(), false, pos); }, [](Player* player, ll::command::RuntimeCommand const& self) { @@ -821,41 +808,41 @@ void registerSpCommand(CommandPermissionLevel permission) { if (hit) pos = hit.mPos; else pos = player->getFeetPos(); } - return coral_fans::cfsp::mod().getSimPlayerManager().groupNavTo( - player, - self["name"].get(), - pos - ); + return coral_fans::cfsp::SimPlayerManager::getInstance() + .groupNavTo(player, self["name"].get(), pos); } ); - std::array, 1> intervalArg{ - std::make_pair("interval", ll::command::ParamKind::Int) - }; std::array, 1> pathArg{ std::make_pair("path", ll::command::ParamKind::FilePath) }; + std::array, 2> intervalArgArg{ + std::make_pair("interval", ll::command::ParamKind::Int), + std::make_pair("arg", ll::command::ParamKind::RawText) + }; ::regSubCmd( spCommand, "script", pathArg, - intervalArg, + intervalArgArg, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().simPlayerScript( + return coral_fans::cfsp::SimPlayerManager::getInstance().simPlayerScript( player, self["name"].get(), false, self["path"].get().getText(), - self["interval"].has_value() ? self["interval"].get() : 20 + self["interval"].has_value() ? self["interval"].get() : 20, + self["arg"].has_value() ? self["arg"].get().getText() : "" ); }, [](Player* player, ll::command::RuntimeCommand const& self) { - return coral_fans::cfsp::mod().getSimPlayerManager().groupScript( + return coral_fans::cfsp::SimPlayerManager::getInstance().groupScript( player, self["name"].get(), self["path"].get().getText(), - self["interval"].has_value() ? self["interval"].get() : 20 + self["interval"].has_value() ? self["interval"].get() : 20, + self["arg"].has_value() ? self["arg"].get().getText() : "" ); } ); diff --git a/src/cfsp/simplayer/CFSP.h b/src/cfsp/simplayer/CFSP.h index a0cc561..1e66d16 100644 --- a/src/cfsp/simplayer/CFSP.h +++ b/src/cfsp/simplayer/CFSP.h @@ -31,6 +31,8 @@ #include #include +#define MANAGER_VERSION 1 +#define INFO_VERSION 1 namespace coral_fans::cfsp { @@ -79,19 +81,19 @@ class SimPlayerManager { } } // functions - inline std::string getName() { return name; } - inline std::string getXuid() { return xuid; } - inline int getStatus() { return status; } - inline Vec3 getPos() { return simPlayer->getPosition(); } - inline Vec3 getFeetPos() { return simPlayer->getFeetPos(); } - inline BlockPos getStandingOn() { return simPlayer->getBlockPosCurrentlyStandingOn(simPlayer); } - inline Vec2 getRot() { return simPlayer->getRotation(); } - inline int getHealth() { return simPlayer->getHealth(); } - inline float getHunger() { return simPlayer->getAttribute(SimulatedPlayer::HUNGER).getCurrentValue(); } - inline bool sneaking(bool enable) { + CFSP_API inline std::string getName() { return name; } + CFSP_API inline std::string getXuid() { return xuid; } + CFSP_API inline int getStatus() { return status; } + CFSP_API inline Vec3 getPos() { return simPlayer->getPosition(); } + CFSP_API inline Vec3 getFeetPos() { return simPlayer->getFeetPos(); } + CFSP_API inline BlockPos getStandingOn() { return simPlayer->getBlockPosCurrentlyStandingOn(simPlayer); } + CFSP_API inline Vec2 getRot() { return simPlayer->getRotation(); } + CFSP_API inline int getHealth() { return simPlayer->getHealth(); } + CFSP_API inline float getHunger() { return simPlayer->getAttribute(SimulatedPlayer::HUNGER).getCurrentValue(); } + CFSP_API inline bool sneaking(bool enable) { return enable ? simPlayer->simulateSneaking() : simPlayer->simulateStopSneaking(); } - void swimming(bool enable) { + CFSP_API void swimming(bool enable) { if (enable) { simPlayer->startSwimming(); taskid = scheduler->add(1, [sp = this->simPlayer](unsigned long long) { @@ -106,13 +108,13 @@ class SimPlayerManager { }); } } - bool attack() { + CFSP_API bool attack() { const auto& hit = simPlayer->traceRay(5.25f, true, false); if (hit) return simPlayer->simulateAttack(hit.getEntity()); else return false; } - inline void chat(std::string const& msg) { simPlayer->simulateChat(msg); } - bool destroy() { + CFSP_API inline void chat(std::string const& msg) { simPlayer->simulateChat(msg); } + CFSP_API bool destroy() { const auto& hit = simPlayer->traceRay(5.25f, false, true); if (hit) return simPlayer->simulateDestroyBlock( @@ -121,8 +123,8 @@ class SimPlayerManager { ); else return false; } - inline bool dropSelectedItem() { return simPlayer->simulateDropSelectedItem(); } - bool dropInv() { + CFSP_API inline bool dropSelectedItem() { return simPlayer->simulateDropSelectedItem(); } + CFSP_API bool dropInv() { bool rst = true; if (simPlayer->getSelectedItem() != ItemStack::EMPTY_ITEM) rst &= simPlayer->simulateDropSelectedItem(); int sel = simPlayer->getSelectedItemSlot(); @@ -135,7 +137,7 @@ class SimPlayerManager { } return rst; } - void swap(Player* player) { + CFSP_API void swap(Player* player) { // get data auto& spInv = simPlayer->getInventory(); const auto spOffhand = simPlayer->getOffhandSlot(); @@ -178,7 +180,7 @@ class SimPlayerManager { // refresh player->refreshInventory(); } - bool runCmd(std::string const& cmd) { + CFSP_API bool runCmd(std::string const& cmd) { CommandContext ctx(cmd, std::make_unique(PlayerCommandOrigin(*simPlayer))); auto mc = ll::service::getMinecraft(); if (mc) { @@ -187,11 +189,11 @@ class SimPlayerManager { } return false; } - std::pair getBlockPosFromView() { + CFSP_API std::pair getBlockPosFromView() { const auto& hit = simPlayer->traceRay(5.25f, false, true); return {hit.mBlockPos, hit.mType == HitResultType::Tile}; } - int searchInInvWithId(int id, int start = 0) { + CFSP_API int searchInInvWithId(int id, int start = 0) { auto& inv = simPlayer->getInventory(); int size = inv.getContainerSize(); for (int i = start; i < size; ++i) { @@ -199,7 +201,7 @@ class SimPlayerManager { } return -1; } - int searchInInvWithName(std::string const& itemName, int start = 0) { + CFSP_API int searchInInvWithName(std::string const& itemName, int start = 0) { auto& inv = simPlayer->getInventory(); int size = inv.getContainerSize(); for (int i = start; i < size; ++i) { @@ -209,14 +211,14 @@ class SimPlayerManager { } return -1; } - bool selectSlot(int slot) { + CFSP_API bool selectSlot(int slot) { int maxslot = simPlayer->getInventory().getContainerSize(); if (slot < 0 || slot >= maxslot) return false; int sel = simPlayer->getSelectedItemSlot(); utils::swapItemInContainer(simPlayer, sel, slot); return true; } - bool select(int id) { + CFSP_API bool select(int id) { int sel = simPlayer->getSelectedItemSlot(); int target = searchInInvWithId(id); if (target == sel) target = searchInInvWithId(id, sel + 1); @@ -224,41 +226,41 @@ class SimPlayerManager { utils::swapItemInContainer(simPlayer, sel, target); return true; } - const ItemStack& getItemFromInv(int slot) { + CFSP_API const ItemStack& getItemFromInv(int slot) { auto& inv = simPlayer->getInventory(); return inv.getItem(slot); } - inline bool interact() { return simPlayer->simulateInteract(); } - inline bool jump() { return simPlayer->simulateJump(); } - void useItem(int delay) { + CFSP_API inline bool interact() { return simPlayer->simulateInteract(); } + CFSP_API inline bool jump() { return simPlayer->simulateJump(); } + CFSP_API void useItem(int delay) { simPlayer->simulateUseItemInSlot(simPlayer->getSelectedItemSlot()); taskid = scheduler->add(delay, [sp = this->simPlayer](unsigned long long) { if (sp) sp->simulateStopUsingItem(); return false; }); } - inline void startBuild() { simPlayer->simulateStartBuildInSlot(simPlayer->getSelectedItemSlot()); } - inline void lookAt(Vec3 const& pos) { simPlayer->simulateLookAt(pos, ::sim::LookDuration{}); } - inline void moveTo(Vec3 const& pos) { simPlayer->simulateMoveToLocation(pos, 4.3f, true); } - inline void navigateTo(Vec3 const& pos) { simPlayer->simulateNavigateToLocation(pos, 4.3f); } - inline void cancelTask() { scheduler->cancel(taskid); } - inline void cancelScript() { scheduler->cancel(scriptid); } - bool isTaskFree() { + CFSP_API inline void startBuild() { simPlayer->simulateStartBuildInSlot(simPlayer->getSelectedItemSlot()); } + CFSP_API inline void lookAt(Vec3 const& pos) { simPlayer->simulateLookAt(pos, ::sim::LookDuration{}); } + CFSP_API inline void moveTo(Vec3 const& pos) { simPlayer->simulateMoveToLocation(pos, 4.3f, true); } + CFSP_API inline void navigateTo(Vec3 const& pos) { simPlayer->simulateNavigateToLocation(pos, 4.3f); } + CFSP_API inline void cancelTask() { scheduler->cancel(taskid); } + CFSP_API inline void cancelScript() { scheduler->cancel(scriptid); } + CFSP_API bool isTaskFree() { if (scheduler->isRunning(taskid)) return false; else { taskid = 0; return true; } } - bool isScriptFree() { + CFSP_API bool isScriptFree() { if (scheduler->isRunning(scriptid)) return false; else { scriptid = 0; return true; } } - inline bool isFree() { return isTaskFree() && isScriptFree(); } - void stopAction() { + CFSP_API inline bool isFree() { return isTaskFree() && isScriptFree(); } + CFSP_API void stopAction() { simPlayer->simulateStopBuild(); simPlayer->simulateStopDestroyingBlock(); simPlayer->simulateStopFlying(); @@ -268,7 +270,7 @@ class SimPlayerManager { if (scheduler->isRunning(taskid)) cancelTask(); taskid = 0; } - void stop() { + CFSP_API void stop() { stopAction(); if (scheduler->isRunning(scriptid)) cancelScript(); scriptid = 0; @@ -286,7 +288,7 @@ class SimPlayerManager { bool autorespawn; bool autojoin; -public: +private: SimPlayerManager() : mOnlineCount(0), mSpawnCount(0), @@ -294,8 +296,14 @@ class SimPlayerManager { autorespawn(false), autojoin(false) {} ~SimPlayerManager() { this->mScheduler->clear(); } - SimPlayerManager(const SimPlayerManager&) = delete; - SimPlayerManager& operator=(const SimPlayerManager&) = delete; + SimPlayerManager(const SimPlayerManager&); + SimPlayerManager& operator=(const SimPlayerManager&); + +public: + CFSP_API static SimPlayerManager& getInstance() { + static SimPlayerManager inst; + return inst; + } private: friend class boost::serialization::access; @@ -315,40 +323,40 @@ class SimPlayerManager { void refreshSoftEnum(); public: - void save(); - void load(); - inline void tick() { this->mScheduler->tick(); } + CFSP_API void save(); + CFSP_API void load(); + inline void tick() { this->mScheduler->tick(); } public: - std::string listSimPlayer(); - std::string listGroup(); + CFSP_API std::string listSimPlayer(); + CFSP_API std::string listGroup(); public: - inline void setAutoRespawn(bool isopen) { this->autorespawn = isopen; } - inline void setAutoJoin(bool isopen) { this->autojoin = isopen; } - inline bool getAutoRespawn() { return this->autorespawn; } - inline bool getAutoJoin() { return this->autojoin; } + CFSP_API inline void setAutoRespawn(bool isopen) { this->autorespawn = isopen; } + CFSP_API inline void setAutoJoin(bool isopen) { this->autojoin = isopen; } + CFSP_API inline bool getAutoRespawn() { return this->autorespawn; } + CFSP_API inline bool getAutoJoin() { return this->autojoin; } public: - std::pair createGroup(Player*, std::string const&); - std::pair deleteGroup(Player*, std::string const&); - std::pair addSpToGroup(Player*, std::string const&, std::string const&); - std::pair rmSpFromGroup(Player*, std::string const&, std::string const&); - std::pair addAdminToGroup(Player*, std::string const&, Player*); - std::pair rmAdminFromGroup(Player*, std::string const&, Player*); + CFSP_API std::pair createGroup(Player*, std::string const&); + CFSP_API std::pair deleteGroup(Player*, std::string const&); + CFSP_API std::pair addSpToGroup(Player*, std::string const&, std::string const&); + CFSP_API std::pair rmSpFromGroup(Player*, std::string const&, std::string const&); + CFSP_API std::pair addAdminToGroup(Player*, std::string const&, Player*); + CFSP_API std::pair rmAdminFromGroup(Player*, std::string const&, Player*); public: - std::pair spawnSimPlayer(Player*, std::string const&, Vec3 const&, Vec2 const&); - std::pair spawnGroup(Player*, std::string const&); - std::pair despawnSimPlayer(Player*, std::string const&, bool); - std::pair despawnGroup(Player*, std::string const&); - std::pair rmSimPlayer(Player*, std::string const&, bool); - std::pair rmGroup(Player*, std::string const&); - std::pair respawnSimPlayer(Player*, std::string const&, bool); - std::pair respawnGroup(Player*, std::string const&); + CFSP_API std::pair spawnSimPlayer(Player*, std::string const&, Vec3 const&, Vec2 const&); + CFSP_API std::pair spawnGroup(Player*, std::string const&); + CFSP_API std::pair despawnSimPlayer(Player*, std::string const&, bool); + CFSP_API std::pair despawnGroup(Player*, std::string const&); + CFSP_API std::pair rmSimPlayer(Player*, std::string const&, bool); + CFSP_API std::pair rmGroup(Player*, std::string const&); + CFSP_API std::pair respawnSimPlayer(Player*, std::string const&, bool); + CFSP_API std::pair respawnGroup(Player*, std::string const&); public: - void setDead(std::string const&); + CFSP_API void setDead(std::string const&); public: SP_REG_DEF(Stop) @@ -359,7 +367,7 @@ class SimPlayerManager { SP_REG_DEF(Destroy, int, int) SP_REG_DEF(DropSelectedItem) SP_REG_DEF(DropInv) - std::pair simPlayerSwap(Player*, std::string const&); + CFSP_API std::pair simPlayerSwap(Player*, std::string const&); SP_REG_DEF(RunCmd, std::string const&, int, int) SP_REG_DEF(Select, int) SP_REG_DEF(Interact, int, int) @@ -369,10 +377,10 @@ class SimPlayerManager { SP_REG_DEF(LookAt, Vec3 const&) SP_REG_DEF(MoveTo, Vec3 const&) SP_REG_DEF(NavTo, Vec3 const&) - SP_REG_DEF(Script, std::string const&, int) + SP_REG_DEF(Script, std::string const&, int, std::string const&) }; } // namespace coral_fans::cfsp -BOOST_CLASS_VERSION(coral_fans::cfsp::SimPlayerManager, 1) -BOOST_CLASS_VERSION(coral_fans::cfsp::SimPlayerManager::SimPlayerInfo, 1) \ No newline at end of file +BOOST_CLASS_VERSION(coral_fans::cfsp::SimPlayerManager, MANAGER_VERSION) +BOOST_CLASS_VERSION(coral_fans::cfsp::SimPlayerManager::SimPlayerInfo, INFO_VERSION) \ No newline at end of file diff --git a/src/cfsp/simplayer/SimPlayer.cpp b/src/cfsp/simplayer/SimPlayer.cpp index 332a26f..67e842c 100644 --- a/src/cfsp/simplayer/SimPlayer.cpp +++ b/src/cfsp/simplayer/SimPlayer.cpp @@ -36,7 +36,6 @@ #include #include - namespace coral_fans::cfsp { namespace sputils { @@ -628,7 +627,8 @@ std::pair SimPlayerManager::simPlayerScript( std::string const& spname, bool noCheck, std::string const& arg, - int interval + int interval, + std::string const& luaArg ) { using ll::i18n_literals::operator""_tr; auto uuid = player->getUuid(); @@ -639,13 +639,18 @@ std::pair SimPlayerManager::simPlayerScript( if (it->second.status != SimPlayerStatus::Alive) return {"translate.simplayer.error.statuserror"_tr(), false}; if (!it->second.isFree()) return {"translate.simplayer.error.nonfree"_tr(), false}; // run script - if (it->second.simPlayer) return sputils::lua_api::execLuaScript(arg, interval, it->second); + if (it->second.simPlayer) return sputils::lua_api::execLuaScript(arg, interval, luaArg, it->second); return {"translate.simplayer.success"_tr(), true}; } return {"translate.simplayer.error.permissiondenied"_tr(), false}; } -std::pair -SimPlayerManager::groupScript(Player* player, std::string const& gname, std::string const& arg, int interval) { +std::pair SimPlayerManager::groupScript( + Player* player, + std::string const& gname, + std::string const& arg, + int interval, + std::string const& luaArg +) { using ll::i18n_literals::operator""_tr; auto adminIt = this->mGroupAdminMap.find(gname); auto it = this->mGroupNameMap.find(gname); @@ -653,7 +658,7 @@ SimPlayerManager::groupScript(Player* player, std::string const& gname, std::str return {"translate.simplayer.error.notfound"_tr(), false}; if (adminIt->second.find(player->getUuid().asString()) == adminIt->second.end()) return {"translate.simplayer.error.permissiondenied"_tr(), false}; - for (auto const& v : it->second) this->simPlayerScript(player, v, true, arg, interval); + for (auto const& v : it->second) this->simPlayerScript(player, v, true, arg, interval, luaArg); return {"translate.simplayer.success"_tr(), true}; } @@ -664,7 +669,8 @@ LL_TYPE_INSTANCE_HOOK( "?tick@Level@@UEAAXXZ", void ) { - mod().getSimPlayerManager().tick(); + origin(); + SimPlayerManager::getInstance().tick(); } LL_TYPE_INSTANCE_HOOK( @@ -677,7 +683,7 @@ LL_TYPE_INSTANCE_HOOK( ) { origin(source); if (this->isSimulatedPlayer()) { - auto& manager = mod().getSimPlayerManager(); + auto& manager = SimPlayerManager::getInstance(); manager.setDead(this->getRealName()); if (manager.getAutoRespawn()) manager.respawnSimPlayer(this, this->getRealName(), true); } @@ -692,7 +698,7 @@ LL_TYPE_INSTANCE_HOOK( CommandOrigin const& arg1, CommandOutput& arg2 ) { - mod().getSimPlayerManager().save(); + SimPlayerManager::getInstance().save(); origin(arg1, arg2); } @@ -705,7 +711,7 @@ LL_TYPE_INSTANCE_HOOK( std::chrono::steady_clock::time_point unknown ) { CFSP::getInstance().getSelf().getLogger().debug("call LevelStorageManager::saveGameData"); - mod().getSimPlayerManager().save(); + SimPlayerManager::getInstance().save(); origin(unknown); } diff --git a/src/cfsp/simplayer/luaapi/BlockInfo.cpp b/src/cfsp/simplayer/luaapi/BlockInfo.cpp new file mode 100644 index 0000000..65a8e2e --- /dev/null +++ b/src/cfsp/simplayer/luaapi/BlockInfo.cpp @@ -0,0 +1,305 @@ +#include "cfsp/simplayer/luaapi/BlockInfo.h" +#include "cfsp/base/Macros.h" +#include "cfsp/base/Utils.h" +#include "cfsp/simplayer/luaapi/Utils.h" +#include "mc/nbt/Tag.h" +#include "mc/world/level/BlockPos.h" +#include "mc/world/level/BlockSource.h" +#include + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata blockinfo begin + +LUAAPI(blockinfo_getName) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushstring(L, (*binfo)->name.c_str()); + return 1; +} + +LUAAPI(blockinfo_getType) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushstring(L, (*binfo)->type.c_str()); + return 1; +} + +LUAAPI(blockinfo_getId) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushinteger(L, (*binfo)->id); + return 1; +} + +LUAAPI(blockinfo_getPos) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); + *bp = (*binfo)->pos; + luaL_setmetatable(L, "blockpos_mt"); + return 1; +} + +LUAAPI(blockinfo_getDim) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushinteger(L, (*binfo)->dim); + return 1; +} + +LUAAPI(blockinfo_getVariant) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushinteger(L, (*binfo)->variant); + return 1; +} + +LUAAPI(blockinfo_getTranslucency) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushnumber(L, (*binfo)->translucency); + return 1; +} + +LUAAPI(blockinfo_getThickness) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushnumber(L, (*binfo)->thickness); + return 1; +} + +LUAAPI(blockinfo_isAir) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isAir); + return 1; +} + +LUAAPI(blockinfo_isBounceBlock) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isBounceBlock); + return 1; +} + +LUAAPI(blockinfo_isButtonBlock) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isButtonBlock); + return 1; +} + +LUAAPI(blockinfo_isCropBlock) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isCropBlock); + return 1; +} + +LUAAPI(blockinfo_isDoorBlock) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isDoorBlock); + return 1; +} + +LUAAPI(blockinfo_isFallingBlock) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isFallingBlock); + return 1; +} + +LUAAPI(blockinfo_isFenceBlock) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isFenceBlock); + return 1; +} + +LUAAPI(blockinfo_isFenceGateBlock) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isFenceGateBlock); + return 1; +} + +LUAAPI(blockinfo_isSlabBlock) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isSlabBlock); + return 1; +} + +LUAAPI(blockinfo_isStemBlock) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isStemBlock); + return 1; +} + +LUAAPI(blockinfo_isThinFenceBlock) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isThinFenceBlock); + return 1; +} + +LUAAPI(blockinfo_isUnbreakable) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isUnbreakable); + return 1; +} + +LUAAPI(blockinfo_isWaterBlockingBlock) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*binfo)->isWaterBlockingBlock); + return 1; +} + +LUAAPI(blockinfo_getNbtTable) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + compoundTagToLuaTable(L, *((*binfo)->tag)); + return 1; +} + +LUAAPI(blockinfo_getSnbt) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushstring(L, (*binfo)->tag->toSnbt(SnbtFormat::Minimize).c_str()); + return 1; +} + +LUAAPI(blockinfo_getSnbtWithPath) { + LUA_ARG_COUNT_CHECK_M(1) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + std::string path = luaL_checkstring(L, 2); + lua_settop(L, 0); + const auto& rst = utils::getNbtFromTag(*((*binfo)->tag), path); + lua_pushstring(L, rst.first.c_str()); + lua_pushboolean(L, rst.second); + return 2; +} + +LUAAPI(blockinfo_meta_eq) { + LUA_ARG_COUNT_CHECK_M(1) + BlockInfo** binfo1 = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo1 != nullptr) && ((*binfo1) != nullptr), 1, "invalid userdata"); + BlockInfo** binfo2 = (BlockInfo**)luaL_checkudata(L, 2, "blockinfo_mt"); + luaL_argcheck(L, (binfo2 != nullptr) && ((*binfo2) != nullptr), 2, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, ((**binfo1) == (**binfo2))); + return 1; +} + +LUAAPI(blockinfo_meta_gc) { + LUA_ARG_COUNT_CHECK_M(0) + BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); + luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + delete *binfo; + return 0; +} + +const luaL_Reg lua_reg_blockinfo_m[27] = { + {"getName", lua_api_blockinfo_getName }, + {"getType", lua_api_blockinfo_getType }, + {"getId", lua_api_blockinfo_getId }, + {"getPos", lua_api_blockinfo_getPos }, + {"getDim", lua_api_blockinfo_getDim }, + {"getVariant", lua_api_blockinfo_getVariant }, + {"getTranslucency", lua_api_blockinfo_getTranslucency }, + {"getThickness", lua_api_blockinfo_getThickness }, + {"isAir", lua_api_blockinfo_isAir }, + {"isBounceBlock", lua_api_blockinfo_isBounceBlock }, + {"isButtonBlock", lua_api_blockinfo_isButtonBlock }, + {"isCropBlock", lua_api_blockinfo_isCropBlock }, + {"isDoorBlock", lua_api_blockinfo_isDoorBlock }, + {"isFallingBlock", lua_api_blockinfo_isFallingBlock }, + {"isFenceBlock", lua_api_blockinfo_isFenceBlock }, + {"isFenceGateBlock", lua_api_blockinfo_isFenceGateBlock }, + {"isSlabBlock", lua_api_blockinfo_isSlabBlock }, + {"isStemBlock", lua_api_blockinfo_isStemBlock }, + {"isThinFenceBlock", lua_api_blockinfo_isThinFenceBlock }, + {"isUnbreakable", lua_api_blockinfo_isUnbreakable }, + {"isWaterBlockingBlock", lua_api_blockinfo_isWaterBlockingBlock}, + {"getNbtTable", lua_api_blockinfo_getNbtTable }, + {"getSnbt", lua_api_blockinfo_getSnbt }, + {"getSnbtWithPath", lua_api_blockinfo_getSnbtWithPath }, + {"__eq", lua_api_blockinfo_meta_eq }, + {"__gc", lua_api_blockinfo_meta_gc }, + {NULL, NULL } +}; + +LUAAPI(open_blockinfo) { + luaL_newmetatable(L, "blockinfo_mt"); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + luaL_setfuncs(L, lua_reg_blockinfo_m, 0); + luaL_newlib(L, lua_reg_null_c); + return 1; +} + +// userdata blockinfo end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/BlockInfo.h b/src/cfsp/simplayer/luaapi/BlockInfo.h new file mode 100644 index 0000000..2d7ec86 --- /dev/null +++ b/src/cfsp/simplayer/luaapi/BlockInfo.h @@ -0,0 +1,146 @@ +#pragma once + +#include "cfsp/base/Macros.h" +#include "mc/nbt/CompoundTag.h" +#include "mc/nbt/CompoundTagVariant.h" +#include "mc/nbt/Tag.h" +#include "mc/world/level/BlockPos.h" +#include "mc/world/level/BlockSource.h" +#include "mc/world/level/block/Block.h" +#include +#include + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata blockinfo begin + +class BlockInfo { +public: + std::string name; + std::string type; + int id; + BlockPos pos; + int dim; + int variant; + float translucency; + float thickness; + bool isAir; + bool isBounceBlock; + bool isButtonBlock; + bool isCropBlock; + bool isDoorBlock; + bool isFallingBlock; + bool isFenceBlock; + bool isFenceGateBlock; + bool isSlabBlock; + bool isStemBlock; + bool isThinFenceBlock; + bool isUnbreakable; + bool isWaterBlockingBlock; + std::unique_ptr tag; + +public: + BlockInfo(BlockPos const bp, int d, Block const& bl) + : name(bl.buildDescriptionName()), + type(bl.getTypeName()), + id(bl.getBlockItemId()), + pos(bp), + dim(d), + variant(bl.getVariant()), + translucency(bl.getTranslucency()), + thickness(bl.getThickness()), + isAir(bl.isAir()), + isBounceBlock(bl.isBounceBlock()), + isButtonBlock(bl.isButtonBlock()), + isCropBlock(bl.isCropBlock()), + isDoorBlock(bl.isDoorBlock()), + isFallingBlock(bl.isFallingBlock()), + isFenceBlock(bl.isFenceBlock()), + isFenceGateBlock(bl.isFenceGateBlock()), + isSlabBlock(bl.isSlabBlock()), + isStemBlock(bl.isStemBlock()), + isThinFenceBlock(bl.isThinFenceBlock()), + isUnbreakable(bl.isUnbreakable()), + isWaterBlockingBlock(bl.isWaterBlocking()), + tag(std::make_unique(bl.getSerializationId())) {} + + bool operator==(const BlockInfo& bi) const { + return name == bi.name && type == bi.type && id == bi.id && pos == bi.pos && dim == bi.dim + && variant == bi.variant && translucency == bi.translucency && thickness == bi.thickness + && isAir == bi.isAir && isBounceBlock == bi.isBounceBlock && isButtonBlock == bi.isButtonBlock + && isCropBlock == bi.isCropBlock && isDoorBlock == bi.isDoorBlock && isFallingBlock == bi.isFallingBlock + && isFenceBlock == bi.isFenceBlock && isFenceGateBlock == bi.isFenceGateBlock + && isSlabBlock == bi.isSlabBlock && isStemBlock == bi.isStemBlock && isThinFenceBlock == bi.isThinFenceBlock + && isUnbreakable == bi.isUnbreakable && isWaterBlockingBlock == bi.isWaterBlockingBlock + && *tag == (*bi.tag); + } +}; + +int lua_api_blockinfo_getName(lua_State*); + +int lua_api_blockinfo_getType(lua_State*); + +int lua_api_blockinfo_getId(lua_State*); + +int lua_api_blockinfo_getPos(lua_State*); + +int lua_api_blockinfo_getDim(lua_State*); + +int lua_api_blockinfo_getVariant(lua_State*); + +int lua_api_blockinfo_getTranslucency(lua_State*); + +int lua_api_blockinfo_getThickness(lua_State*); + +int lua_api_blockinfo_isAir(lua_State*); + +int lua_api_blockinfo_isBounceBlock(lua_State*); + +int lua_api_blockinfo_isButtonBlock(lua_State*); + +int lua_api_blockinfo_isCropBlock(lua_State*); + +int lua_api_blockinfo_isDoorBlock(lua_State*); + +int lua_api_blockinfo_isFallingBlock(lua_State*); + +int lua_api_blockinfo_isFenceBlock(lua_State*); + +int lua_api_blockinfo_isFenceGateBlock(lua_State*); + +int lua_api_blockinfo_isSlabBlock(lua_State*); + +int lua_api_blockinfo_isStemBlock(lua_State*); + +int lua_api_blockinfo_isThinFenceBlock(lua_State*); + +int lua_api_blockinfo_isUnbreakable(lua_State*); + +int lua_api_blockinfo_isWaterBlockingBlock(lua_State*); + +int lua_api_blockinfo_getNbtTable(lua_State*); + +int lua_api_blockinfo_getSnbt(lua_State*); + +int lua_api_blockinfo_getSnbtWithPath(lua_State*); + +int lua_api_blockinfo_meta_eq(lua_State*); + +int lua_api_blockinfo_meta_gc(lua_State*); + +extern const luaL_Reg lua_reg_blockinfo_m[27]; + +int lua_api_open_blockinfo(lua_State*); + +// userdata blockinfo end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/BlockPos.cpp b/src/cfsp/simplayer/luaapi/BlockPos.cpp new file mode 100644 index 0000000..cd4056f --- /dev/null +++ b/src/cfsp/simplayer/luaapi/BlockPos.cpp @@ -0,0 +1,203 @@ +#include "mc/world/level/BlockPos.h" +#include "cfsp/base/Macros.h" +#include "cfsp/simplayer/luaapi/Vec3.h" +#include "ll/api/base/StdInt.h" +#include "mc/math/Vec3.h" +#include "mc/world/level/BlockSource.h" +#include + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata blockpos begin + +LUAAPI(blockpos_new) { + LUA_ARG_COUNT_CHECK_C(3) + int x = static_cast(luaL_checkinteger(L, 1)); + int y = static_cast(luaL_checkinteger(L, 2)); + int z = static_cast(luaL_checkinteger(L, 3)); + lua_settop(L, 0); + BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); + bp->x = x; + bp->y = y; + bp->z = z; + luaL_setmetatable(L, "blockpos_mt"); + return 1; +} + +LUAAPI(blockpos_newMax) { + LUA_ARG_COUNT_CHECK_C(0) + BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); + *bp = BlockPos::MAX; + luaL_setmetatable(L, "blockpos_mt"); + return 1; +} + +LUAAPI(blockpos_newMin) { + LUA_ARG_COUNT_CHECK_C(0) + BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); + *bp = BlockPos::MIN; + luaL_setmetatable(L, "blockpos_mt"); + return 1; +} + +LUAAPI(blockpos_newOne) { + LUA_ARG_COUNT_CHECK_C(0) + BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); + *bp = BlockPos::ONE; + luaL_setmetatable(L, "blockpos_mt"); + return 1; +} + +LUAAPI(blockpos_newZero) { + LUA_ARG_COUNT_CHECK_C(0) + BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); + *bp = BlockPos::ZERO; + luaL_setmetatable(L, "blockpos_mt"); + return 1; +} + +const luaL_Reg lua_reg_blockpos_c[6] = { + {"new", lua_api_blockpos_new }, + {"newMax", lua_api_blockpos_newMax }, + {"newMin", lua_api_blockpos_newMin }, + {"newOne", lua_api_blockpos_newOne }, + {"newZero", lua_api_blockpos_newZero}, + {NULL, NULL } +}; + +LUAAPI(blockpos_get) { + LUA_ARG_COUNT_CHECK_M(0) + BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); + luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushinteger(L, bp->x); + lua_pushinteger(L, bp->y); + lua_pushinteger(L, bp->z); + return 3; +} + +LUAAPI(blockpos_bottomCenter) { + LUA_ARG_COUNT_CHECK_M(0) + BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); + luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); + lua_settop(L, 0); + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = bp->bottomCenter(); + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(blockpos_center) { + LUA_ARG_COUNT_CHECK_M(0) + BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); + luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); + lua_settop(L, 0); + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = bp->center(); + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(blockpos_toVec3) { + LUA_ARG_COUNT_CHECK_M(0) + BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); + luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); + lua_settop(L, 0); + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3(*bp); + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(blockpos_neighbor) { + LUA_ARG_COUNT_CHECK_M(1) + BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); + luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); + uchar facing = static_cast(luaL_checkinteger(L, 2)); + lua_settop(L, 0); + BlockPos* ret_bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); + *ret_bp = bp->neighbor(facing); + luaL_setmetatable(L, "blockpos_mt"); + return 1; +} + +LUAAPI(blockpos_meta_tostring) { + LUA_ARG_COUNT_CHECK_M(0) + BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); + luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushstring(L, bp->toString().c_str()); + return 1; +} + +LUAAPI(blockpos_meta_add) { + LUA_ARG_COUNT_CHECK_M(1) + BlockPos* bp1 = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); + luaL_argcheck(L, bp1 != nullptr, 1, "invalid userdata"); + BlockPos* bp2 = (BlockPos*)luaL_checkudata(L, 2, "blockpos_mt"); + luaL_argcheck(L, bp2 != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); + *bp = (*bp1) + (*bp2); + luaL_setmetatable(L, "blockpos_mt"); + return 1; +} + +LUAAPI(blockpos_meta_sub) { + LUA_ARG_COUNT_CHECK_M(1) + BlockPos* bp1 = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); + luaL_argcheck(L, bp1 != nullptr, 1, "invalid userdata"); + BlockPos* bp2 = (BlockPos*)luaL_checkudata(L, 2, "blockpos_mt"); + luaL_argcheck(L, bp2 != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); + *bp = (*bp1) - (*bp2); + luaL_setmetatable(L, "blockpos_mt"); + return 1; +} + +LUAAPI(blockpos_meta_eq) { + LUA_ARG_COUNT_CHECK_M(1) + BlockPos* bp1 = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); + luaL_argcheck(L, bp1 != nullptr, 1, "invalid userdata"); + BlockPos* bp2 = (BlockPos*)luaL_checkudata(L, 2, "blockpos_mt"); + luaL_argcheck(L, bp2 != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, ((*bp1) == (*bp2))); + return 1; +} + +const luaL_Reg lua_reg_blockpos_m[10] = { + {"get", lua_api_blockpos_get }, + {"bottomCenter", lua_api_blockpos_bottomCenter }, + {"center", lua_api_blockpos_center }, + {"toVec3", lua_api_blockpos_toVec3 }, + {"neighbor", lua_api_blockpos_neighbor }, + {"__tostring", lua_api_blockpos_meta_tostring}, + {"__add", lua_api_blockpos_meta_add }, + {"__sub", lua_api_blockpos_meta_sub }, + {"__eq", lua_api_blockpos_meta_eq }, + {NULL, NULL } +}; + +LUAAPI(open_blockpos) { + luaL_newmetatable(L, "blockpos_mt"); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + luaL_setfuncs(L, lua_reg_blockpos_m, 0); + luaL_newlib(L, lua_reg_blockpos_c); + return 1; +} + +// userdata blockpos end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/BlockPos.h b/src/cfsp/simplayer/luaapi/BlockPos.h new file mode 100644 index 0000000..d31dd77 --- /dev/null +++ b/src/cfsp/simplayer/luaapi/BlockPos.h @@ -0,0 +1,54 @@ +#pragma once + +#include "cfsp/base/Macros.h" + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata blockpos begin + +int lua_api_blockpos_new(lua_State*); + +int lua_api_blockpos_newMax(lua_State*); + +int lua_api_blockpos_newMin(lua_State*); + +int lua_api_blockpos_newOne(lua_State*); + +int lua_api_blockpos_newZero(lua_State*); + +extern const luaL_Reg lua_reg_blockpos_c[6]; + +int lua_api_blockpos_get(lua_State*); + +int lua_api_blockpos_bottomCenter(lua_State*); + +int lua_api_blockpos_center(lua_State*); + +int lua_api_blockpos_toVec3(lua_State*); + +int lua_api_blockpos_neighbor(lua_State*); + +int lua_api_blockpos_meta_tostring(lua_State*); + +int lua_api_blockpos_meta_add(lua_State*); + +int lua_api_blockpos_meta_sub(lua_State*); + +int lua_api_blockpos_meta_eq(lua_State*); + +extern const luaL_Reg lua_reg_blockpos_m[10]; + +int lua_api_open_blockpos(lua_State*); + +// userdata blockpos end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/BlockSource.cpp b/src/cfsp/simplayer/luaapi/BlockSource.cpp new file mode 100644 index 0000000..3f42f17 --- /dev/null +++ b/src/cfsp/simplayer/luaapi/BlockSource.cpp @@ -0,0 +1,61 @@ +#include "mc/world/level/BlockSource.h" +#include "cfsp/base/Macros.h" +#include "ll/api/service/Bedrock.h" +#include "mc/world/level/BlockPos.h" +#include "mc/world/level/Level.h" +#include "mc/world/level/dimension/Dimension.h" + +#include "cfsp/simplayer/luaapi/BlockInfo.h" +#include "cfsp/simplayer/luaapi/Utils.h" + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata blocksource begin + +LUAAPI(blocksource_getBlockInfo) { + LUA_ARG_COUNT_CHECK_M(1) + int* dimid = (int*)luaL_checkudata(L, 1, "blocksource_mt"); + luaL_argcheck(L, dimid != nullptr, 1, "invalid userdata"); + BlockPos* bp = (BlockPos*)luaL_checkudata(L, 2, "blockpos_mt"); + luaL_argcheck(L, bp != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + auto level = ll::service::getLevel(); + if (!level.has_value()) { + lua_pushnil(L); + lua_pushboolean(L, false); + return 2; + } + const auto& block = level->getDimension(*dimid)->getBlockSourceFromMainChunkSource().getBlock(*bp); + BlockInfo** binfo = (BlockInfo**)lua_newuserdata(L, sizeof(BlockInfo*)); + *binfo = new BlockInfo(*bp, *dimid, block); + luaL_setmetatable(L, "blockinfo_mt"); + lua_pushboolean(L, true); + return 2; +} + +const luaL_Reg lua_reg_blocksource_m[2] = { + {"getBlockInfo", lua_api_blocksource_getBlockInfo}, + {NULL, NULL } +}; + +LUAAPI(open_blocksource) { + luaL_newmetatable(L, "blocksource_mt"); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + luaL_setfuncs(L, lua_reg_blocksource_m, 0); + luaL_newlib(L, lua_reg_null_c); + return 1; +} + +// userdata blocksource end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/BlockSource.h b/src/cfsp/simplayer/luaapi/BlockSource.h new file mode 100644 index 0000000..06542b0 --- /dev/null +++ b/src/cfsp/simplayer/luaapi/BlockSource.h @@ -0,0 +1,26 @@ +#pragma once + +#include "cfsp/base/Macros.h" + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata blocksource begin + +int lua_api_blocksource_getBlockInfo(lua_State*); + +extern const luaL_Reg lua_reg_blocksource_m[2]; + +int lua_api_open_blocksource(lua_State*); + +// userdata blocksource end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/ItemInfo.cpp b/src/cfsp/simplayer/luaapi/ItemInfo.cpp new file mode 100644 index 0000000..1617bed --- /dev/null +++ b/src/cfsp/simplayer/luaapi/ItemInfo.cpp @@ -0,0 +1,363 @@ +#include "cfsp/simplayer/luaapi/ItemInfo.h" +#include "cfsp/base/Macros.h" +#include "cfsp/base/Utils.h" +#include "cfsp/simplayer/luaapi/Utils.h" +#include "mc/nbt/CompoundTag.h" +#include "mc/nbt/CompoundTagVariant.h" +#include "mc/nbt/Tag.h" +#include "mc/world/level/BlockSource.h" +#include "mc/world/level/block/Block.h" +#include +#include +#include + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata iteminfo begin + +LUAAPI(iteminfo_getName) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushstring(L, (*info)->name.c_str()); + return 1; +} + +LUAAPI(iteminfo_getType) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushstring(L, (*info)->type.c_str()); + return 1; +} + +LUAAPI(iteminfo_getId) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushinteger(L, (*info)->id); + return 1; +} + +LUAAPI(iteminfo_getCount) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushinteger(L, (*info)->count); + return 1; +} + +LUAAPI(iteminfo_getAux) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushinteger(L, (*info)->aux); + return 1; +} + +LUAAPI(iteminfo_getDamage) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushinteger(L, (*info)->damage); + return 1; +} + +LUAAPI(iteminfo_getAttackDamage) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushinteger(L, (*info)->attackDamage); + return 1; +} + +LUAAPI(iteminfo_getMaxDamage) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushinteger(L, (*info)->maxDamage); + return 1; +} + +LUAAPI(iteminfo_getMaxStackSize) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushinteger(L, (*info)->maxStackSize); + return 1; +} + +LUAAPI(iteminfo_getLore) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + int idx = 1; + lua_newtable(L); + for (const auto& item : (*info)->lore) { + lua_pushstring(L, item.c_str()); + lua_seti(L, -2, idx); + ++idx; + } + return 1; +} + +LUAAPI(iteminfo_isArmorItem) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isArmorItem); + return 1; +} + +LUAAPI(iteminfo_isBlock) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isBlock); + return 1; +} + +LUAAPI(iteminfo_isDamageableItem) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isDamageableItem); + return 1; +} + +LUAAPI(iteminfo_isDamaged) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isDamaged); + return 1; +} + +LUAAPI(iteminfo_isEnchanted) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isEnchanted); + return 1; +} + +LUAAPI(iteminfo_isEnchantingBook) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isEnchantingBook); + return 1; +} + +LUAAPI(iteminfo_isFireResistant) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isFireResistant); + return 1; +} + +LUAAPI(iteminfo_isFullStack) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isFullStack); + return 1; +} + +LUAAPI(iteminfo_isGlint) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isGlint); + return 1; +} + +LUAAPI(iteminfo_isHorseArmorItem) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isHorseArmorItem); + return 1; +} + +LUAAPI(iteminfo_isLiquidClipItem) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isLiquidClipItem); + return 1; +} + +LUAAPI(iteminfo_isMusicDiscItem) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isMusicDiscItem); + return 1; +} + +LUAAPI(iteminfo_isOffhandItem) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isOffhandItem); + return 1; +} + +LUAAPI(iteminfo_isPotionItem) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isPotionItem); + return 1; +} + +LUAAPI(iteminfo_isStackable) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isStackable); + return 1; +} + +LUAAPI(iteminfo_isWearableItem) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, (*info)->isWearableItem); + return 1; +} + +LUAAPI(iteminfo_getNbtTable) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + compoundTagToLuaTable(L, *((*info)->tag)); + return 1; +} + +LUAAPI(iteminfo_getSnbt) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushstring(L, (*info)->tag->toSnbt(SnbtFormat::Minimize).c_str()); + return 1; +} + +LUAAPI(iteminfo_getSnbtWithPath) { + LUA_ARG_COUNT_CHECK_M(1) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + std::string path = luaL_checkstring(L, 2); + lua_settop(L, 0); + const auto& rst = utils::getNbtFromTag(*((*info)->tag), path); + lua_pushstring(L, rst.first.c_str()); + lua_pushboolean(L, rst.second); + return 2; +} + +LUAAPI(iteminfo_meta_eq) { + LUA_ARG_COUNT_CHECK_M(1) + ItemInfo** info1 = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info1 != nullptr) && ((*info1) != nullptr), 1, "invalid userdata"); + ItemInfo** info2 = (ItemInfo**)luaL_checkudata(L, 2, "iteminfo_mt"); + luaL_argcheck(L, (info2 != nullptr) && ((*info2) != nullptr), 2, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, ((**info1) == (**info2))); + return 1; +} + +LUAAPI(iteminfo_meta_gc) { + LUA_ARG_COUNT_CHECK_M(0) + ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); + luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + delete *info; + return 0; +} + +const luaL_Reg lua_reg_iteminfo_m[32] = { + {"getName", lua_api_iteminfo_getName }, + {"getType", lua_api_iteminfo_getType }, + {"getId", lua_api_iteminfo_getId }, + {"getCount", lua_api_iteminfo_getCount }, + {"getAux", lua_api_iteminfo_getAux }, + {"getDamage", lua_api_iteminfo_getDamage }, + {"getAttackDamage", lua_api_iteminfo_getAttackDamage }, + {"getMaxDamage", lua_api_iteminfo_getMaxDamage }, + {"getMaxStackSize", lua_api_iteminfo_getMaxStackSize }, + {"getLore", lua_api_iteminfo_getLore }, + {"isArmorItem", lua_api_iteminfo_isArmorItem }, + {"isBlock", lua_api_iteminfo_isBlock }, + {"isDamageableItem", lua_api_iteminfo_isDamageableItem}, + {"isDamaged", lua_api_iteminfo_isDamaged }, + {"isEnchanted", lua_api_iteminfo_isEnchanted }, + {"isEnchantingBook", lua_api_iteminfo_isEnchantingBook}, + {"isFireResistant", lua_api_iteminfo_isFireResistant }, + {"isFullStack", lua_api_iteminfo_isFullStack }, + {"isGlint", lua_api_iteminfo_isGlint }, + {"isHorseArmorItem", lua_api_iteminfo_isHorseArmorItem}, + {"isLiquidClipItem", lua_api_iteminfo_isLiquidClipItem}, + {"isMusicDiscItem", lua_api_iteminfo_isMusicDiscItem }, + {"isOffhandItem", lua_api_iteminfo_isOffhandItem }, + {"isPotionItem", lua_api_iteminfo_isPotionItem }, + {"isStackable", lua_api_iteminfo_isStackable }, + {"isWearableItem", lua_api_iteminfo_isWearableItem }, + {"getNbtTable", lua_api_iteminfo_getNbtTable }, + {"getSnbt", lua_api_iteminfo_getSnbt }, + {"getSnbtWithPath", lua_api_iteminfo_getSnbtWithPath }, + {"__eq", lua_api_iteminfo_meta_eq }, + {"__gc", lua_api_iteminfo_meta_gc }, + {NULL, NULL } +}; + +LUAAPI(open_iteminfo) { + luaL_newmetatable(L, "iteminfo_mt"); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + luaL_setfuncs(L, lua_reg_iteminfo_m, 0); + luaL_newlib(L, lua_reg_null_c); + return 1; +} + +// userdata iteminfo end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/ItemInfo.h b/src/cfsp/simplayer/luaapi/ItemInfo.h new file mode 100644 index 0000000..5af8426 --- /dev/null +++ b/src/cfsp/simplayer/luaapi/ItemInfo.h @@ -0,0 +1,167 @@ +#pragma once + +#include "cfsp/base/Macros.h" +#include "mc/nbt/CompoundTag.h" +#include "mc/nbt/CompoundTagVariant.h" +#include "mc/nbt/Tag.h" +#include "mc/world/item/registry/ItemStack.h" +#include "mc/world/level/BlockSource.h" +#include "mc/world/level/block/Block.h" +#include +#include + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata iteminfo begin + +class ItemInfo { +public: + std::string name; + std::string type; + int id; + int count; + int aux; + int damage; + int attackDamage; + int maxDamage; + int maxStackSize; + std::vector lore; + bool isArmorItem; + bool isBlock; + bool isDamageableItem; + bool isDamaged; + bool isEnchanted; + bool isEnchantingBook; + bool isFireResistant; + bool isFullStack; + bool isGlint; + bool isHorseArmorItem; + bool isLiquidClipItem; + bool isMusicDiscItem; + bool isOffhandItem; + bool isPotionItem; + bool isStackable; + bool isWearableItem; + std::unique_ptr tag; + +public: + ItemInfo(ItemStack const& item) + : name(item.getCustomName().empty() ? item.getName() : item.getCustomName()), + type(item.getTypeName()), + id(item.getId()), + count(item.mCount), + aux(item.getAuxValue()), + damage(item.getDamageValue()), + attackDamage(item.getAttackDamage()), + maxDamage(item.getMaxDamage()), + maxStackSize(item.getMaxStackSize()), + lore(item.getCustomLore()), + isArmorItem(item.isArmorItem()), + isBlock(item.isBlock()), + isDamageableItem(item.isDamageableItem()), + isDamaged(item.isDamaged()), + isEnchanted(item.isEnchanted()), + isEnchantingBook(item.isEnchantingBook()), + isFireResistant(item.isFireResistant()), + isFullStack(item.isFullStack()), + isGlint(item.isGlint()), + isHorseArmorItem(item.isHorseArmorItem()), + isLiquidClipItem(item.isLiquidClipItem()), + isMusicDiscItem(item.isMusicDiscItem()), + isOffhandItem(item.isOffhandItem()), + isPotionItem(item.isPotionItem()), + isStackable(item.isStackable()), + isWearableItem(item.isHumanoidWearableItem()), + tag(item.save()) {} + bool operator==(const ItemInfo& rt) const { + return name == rt.name && type == rt.type && id == rt.id && count == rt.count && aux == rt.aux + && damage == rt.damage && attackDamage == rt.attackDamage && maxDamage == rt.maxDamage + && maxStackSize == rt.maxStackSize && lore == rt.lore && isArmorItem == rt.isArmorItem + && isBlock == rt.isBlock && isDamageableItem == rt.isDamageableItem && isDamaged == rt.isDamaged + && isEnchanted == rt.isEnchanted && isEnchantingBook == rt.isEnchantingBook + && isFireResistant == rt.isFireResistant && isFullStack == rt.isFullStack && isGlint == rt.isGlint + && isHorseArmorItem == rt.isHorseArmorItem && isLiquidClipItem == rt.isLiquidClipItem + && isMusicDiscItem == rt.isMusicDiscItem && isOffhandItem == rt.isOffhandItem + && isPotionItem == rt.isPotionItem && isStackable == rt.isStackable && isWearableItem == rt.isWearableItem + && (*tag) == (*rt.tag); + } +}; + +int lua_api_iteminfo_getName(lua_State*); + +int lua_api_iteminfo_getType(lua_State*); + +int lua_api_iteminfo_getId(lua_State*); + +int lua_api_iteminfo_getCount(lua_State*); + +int lua_api_iteminfo_getAux(lua_State*); + +int lua_api_iteminfo_getDamage(lua_State*); + +int lua_api_iteminfo_getAttackDamage(lua_State*); + +int lua_api_iteminfo_getMaxDamage(lua_State*); + +int lua_api_iteminfo_getMaxStackSize(lua_State*); + +int lua_api_iteminfo_getLore(lua_State*); + +int lua_api_iteminfo_isArmorItem(lua_State*); + +int lua_api_iteminfo_isBlock(lua_State*); + +int lua_api_iteminfo_isDamageableItem(lua_State*); + +int lua_api_iteminfo_isDamaged(lua_State*); + +int lua_api_iteminfo_isEnchanted(lua_State*); + +int lua_api_iteminfo_isEnchantingBook(lua_State*); + +int lua_api_iteminfo_isFireResistant(lua_State*); + +int lua_api_iteminfo_isFullStack(lua_State*); + +int lua_api_iteminfo_isGlint(lua_State*); + +int lua_api_iteminfo_isHorseArmorItem(lua_State*); + +int lua_api_iteminfo_isLiquidClipItem(lua_State*); + +int lua_api_iteminfo_isMusicDiscItem(lua_State*); + +int lua_api_iteminfo_isOffhandItem(lua_State*); + +int lua_api_iteminfo_isPotionItem(lua_State*); + +int lua_api_iteminfo_isStackable(lua_State*); + +int lua_api_iteminfo_isWearableItem(lua_State*); + +int lua_api_iteminfo_getNbtTable(lua_State*); + +int lua_api_iteminfo_getSnbt(lua_State*); + +int lua_api_iteminfo_getSnbtWithPath(lua_State*); + +int lua_api_iteminfo_meta_eq(lua_State*); + +int lua_api_iteminfo_meta_gc(lua_State*); + +extern const luaL_Reg lua_reg_iteminfo_m[32]; + +int lua_api_open_iteminfo(lua_State*); + +// userdata iteminfo end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/Level.cpp b/src/cfsp/simplayer/luaapi/Level.cpp new file mode 100644 index 0000000..5edcc0f --- /dev/null +++ b/src/cfsp/simplayer/luaapi/Level.cpp @@ -0,0 +1,87 @@ +#include "mc/world/level/Level.h" +#include "cfsp/base/Macros.h" +#include "cfsp/simplayer/luaapi/Utils.h" +#include "ll/api/service/Bedrock.h" +#include "mc/util/ProfilerLite.h" +#include "mc/world/level/Tick.h" + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata level begin + +LUAAPI(level_getDayTime) { + LUA_ARG_COUNT_CHECK_M(0) + luaL_checkudata(L, 1, "level_mt"); + lua_settop(L, 0); + auto level = ll::service::getLevel(); + if (!level.has_value()) { + lua_pushinteger(L, -1); + return 1; + } + lua_pushinteger(L, level->getTime() % 24000); + return 1; +} + +LUAAPI(level_getGameTime) { + LUA_ARG_COUNT_CHECK_M(0) + luaL_checkudata(L, 1, "level_mt"); + lua_settop(L, 0); + auto level = ll::service::getLevel(); + if (!level.has_value()) { + lua_pushinteger(L, -1); + return 1; + } + lua_pushinteger(L, level->getCurrentTick().t); + return 1; +} + +LUAAPI(level_getDay) { + LUA_ARG_COUNT_CHECK_M(0) + luaL_checkudata(L, 1, "level_mt"); + lua_settop(L, 0); + auto level = ll::service::getLevel(); + if (!level.has_value()) { + lua_pushinteger(L, -1); + return 1; + } + lua_pushinteger(L, level->getTime() / 24000); + return 1; +} + +LUAAPI(level_getMspt) { + LUA_ARG_COUNT_CHECK_M(0) + luaL_checkudata(L, 1, "level_mt"); + lua_settop(L, 0); + lua_pushnumber(L, static_cast(ProfilerLite::gProfilerLiteInstance.getServerTickTime().count() / 1000000.0)); + return 1; +} + +const luaL_Reg lua_reg_level_m[5] = { + {"getDayTime", lua_api_level_getDayTime }, + {"getGameTime", lua_api_level_getGameTime}, + {"getDay", lua_api_level_getDay }, + {"getMspt", lua_api_level_getMspt }, + {NULL, NULL } +}; + +LUAAPI(open_level) { + luaL_newmetatable(L, "level_mt"); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + luaL_setfuncs(L, lua_reg_level_m, 0); + luaL_newlib(L, lua_reg_null_c); + return 1; +} + +// userdata level end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/Level.h b/src/cfsp/simplayer/luaapi/Level.h new file mode 100644 index 0000000..7de8086 --- /dev/null +++ b/src/cfsp/simplayer/luaapi/Level.h @@ -0,0 +1,32 @@ +#pragma once + +#include "cfsp/base/Macros.h" + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata level begin + +int lua_api_level_getDayTime(lua_State*); + +int lua_api_level_getGameTime(lua_State*); + +int lua_api_level_getDay(lua_State*); + +int lua_api_level_getMspt(lua_State*); + +extern const luaL_Reg lua_reg_level_m[5]; + +int lua_api_open_level(lua_State*); + +// userdata level end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/Log.cpp b/src/cfsp/simplayer/luaapi/Log.cpp new file mode 100644 index 0000000..8d9f948 --- /dev/null +++ b/src/cfsp/simplayer/luaapi/Log.cpp @@ -0,0 +1,26 @@ +#include "boost/algorithm/string/join.hpp" +#include "cfsp/CFSP.h" +#include "cfsp/base/Macros.h" +#include "cfsp/simplayer/CFSP.h" +#include + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +LUAAPI(log) { + int count = lua_gettop(L); + std::list lst; + for (int i = 1; i <= count; ++i) lst.emplace_back(luaL_checkstring(L, i)); + CFSP::getInstance().getSelf().getLogger().info("[CFSP-Lua] {}", boost::algorithm::join(lst, "\t")); + return 0; +} + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/Log.h b/src/cfsp/simplayer/luaapi/Log.h new file mode 100644 index 0000000..51ad964 --- /dev/null +++ b/src/cfsp/simplayer/luaapi/Log.h @@ -0,0 +1,17 @@ +#pragma once + +#include "cfsp/base/Macros.h" + +extern "C" { +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +int lua_api_log(lua_State*); + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/SimPlayer.cpp b/src/cfsp/simplayer/luaapi/SimPlayer.cpp new file mode 100644 index 0000000..408256b --- /dev/null +++ b/src/cfsp/simplayer/luaapi/SimPlayer.cpp @@ -0,0 +1,575 @@ +#include "cfsp/base/Macros.h" +#include "cfsp/simplayer/CFSP.h" +#include "mc/math/Vec2.h" +#include "mc/math/Vec3.h" +#include "mc/world/level/BlockPos.h" +#include "mc/world/level/BlockSource.h" +#include +#include + +#include "cfsp/simplayer/luaapi/ItemInfo.h" +#include "cfsp/simplayer/luaapi/Utils.h" + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata simplayer begin + +LUAAPI(simplayer_getName) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushstring(L, (*spinfo)->getName().c_str()); + return 1; +} + +LUAAPI(simplayer_getXuid) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushstring(L, (*spinfo)->getXuid().c_str()); + return 1; +} + +LUAAPI(simplayer_getStatus) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushinteger(L, (*spinfo)->getStatus()); + return 1; +} + +LUAAPI(simplayer_getPos) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = (*spinfo)->getPos(); + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(simplayer_getFeetPos) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = (*spinfo)->getFeetPos(); + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(simplayer_getStandingOn) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + BlockPos* pos = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); + *pos = (*spinfo)->getStandingOn(); + luaL_setmetatable(L, "blockpos_mt"); + return 1; +} + +LUAAPI(simplayer_getRot) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + Vec2* pos = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *pos = (*spinfo)->getRot(); + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(simplayer_getHealth) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushinteger(L, (*spinfo)->getHealth()); + return 1; +} + +LUAAPI(simplayer_getHunger) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushnumber(L, (*spinfo)->getHunger()); + return 1; +} + +LUAAPI(simplayer_sneaking) { + LUA_ARG_COUNT_CHECK_M(1) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + luaL_argcheck( + L, + lua_isboolean(L, 2), + 2, + std::string{"boolean expected, got " + std::string{lua_typename(L, lua_type(L, 2))}}.c_str() + ); + lua_pushboolean(L, (*spinfo)->sneaking(lua_toboolean(L, 2))); + return 1; +} + +LUAAPI(simplayer_swimming) { + LUA_ARG_COUNT_CHECK_M(1) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + luaL_argcheck( + L, + lua_isboolean(L, 2), + 2, + std::string{"boolean expected, got " + std::string{lua_typename(L, lua_type(L, 2))}}.c_str() + ); + (*spinfo)->swimming(lua_toboolean(L, 2)); + return 0; +} + +LUAAPI(simplayer_attack) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushboolean(L, (*spinfo)->attack()); + return 1; +} + +LUAAPI(simplayer_chat) { + LUA_ARG_COUNT_CHECK_M(1) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + std::string msg = luaL_checkstring(L, 2); + lua_settop(L, 0); + (*spinfo)->chat(msg); + return 0; +} + +LUAAPI(simplayer_destroy) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushboolean(L, (*spinfo)->destroy()); + return 1; +} + +LUAAPI(simplayer_dropSelectedItem) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushboolean(L, (*spinfo)->dropSelectedItem()); + return 1; +} + +LUAAPI(simplayer_dropInv) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushboolean(L, (*spinfo)->dropInv()); + return 1; +} + +LUAAPI(simplayer_runCmd) { + LUA_ARG_COUNT_CHECK_M(1) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + std::string cmd = luaL_checkstring(L, 2); + lua_settop(L, 0); + lua_pushboolean(L, (*spinfo)->runCmd(cmd)); + return 1; +} + +LUAAPI(simplayer_getBlockPosFromView) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + const auto& rst = (*spinfo)->getBlockPosFromView(); + BlockPos* pos = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); + *pos = rst.first; + luaL_setmetatable(L, "blockpos_mt"); + lua_pushboolean(L, rst.second); + return 2; +} + +LUAAPI(simplayer_searchInInvWithId) { + int count = lua_gettop(L); + if (count < 2 || count > 3) return luaL_error(L, "1 or 2 args expected (without \"self\")"); + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + int id = static_cast(luaL_checkinteger(L, 2)); + int start = 0; + if (count == 3) start = static_cast(luaL_checkinteger(L, 3)); + lua_settop(L, 0); + lua_pushinteger(L, (*spinfo)->searchInInvWithId(id, start)); + return 1; +} + +LUAAPI(simplayer_searchInInvWithName) { + int count = lua_gettop(L); + if (count < 2 || count > 3) return luaL_error(L, "1 or 2 args expected (without \"self\")"); + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + std::string name = luaL_checkstring(L, 2); + int start = 0; + if (count == 3) start = static_cast(luaL_checkinteger(L, 3)); + lua_settop(L, 0); + lua_pushinteger(L, (*spinfo)->searchInInvWithName(name, start)); + return 1; +} + +LUAAPI(simplayer_selectSlot) { + LUA_ARG_COUNT_CHECK_M(1) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + int slot = static_cast(luaL_checkinteger(L, 2)); + lua_settop(L, 0); + lua_pushboolean(L, (*spinfo)->selectSlot(slot)); + return 1; +} + +LUAAPI(simplayer_select) { + LUA_ARG_COUNT_CHECK_M(1) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + int id = static_cast(luaL_checkinteger(L, 2)); + lua_settop(L, 0); + lua_pushboolean(L, (*spinfo)->select(id)); + return 1; +} + +LUAAPI(simplayer_getItemFromInv) { + LUA_ARG_COUNT_CHECK_M(1) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + int slot = static_cast(luaL_checkinteger(L, 2)); + lua_settop(L, 0); + ItemInfo** info = (ItemInfo**)lua_newuserdata(L, sizeof(ItemInfo*)); + *info = new ItemInfo((*spinfo)->getItemFromInv(slot)); + luaL_setmetatable(L, "iteminfo_mt"); + return 1; +} + +LUAAPI(simplayer_interact) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushboolean(L, (*spinfo)->interact()); + return 1; +} + +LUAAPI(simplayer_jump) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushboolean(L, (*spinfo)->jump()); + return 1; +} + +LUAAPI(simplayer_useItem) { + LUA_ARG_COUNT_CHECK_M(1) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + int delay = static_cast(luaL_checkinteger(L, 2)); + lua_settop(L, 0); + (*spinfo)->useItem(delay); + return 0; +} + +LUAAPI(simplayer_startBuild) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + (*spinfo)->startBuild(); + return 0; +} + +LUAAPI(simplayer_lookAt) { + LUA_ARG_COUNT_CHECK_M(1) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + Vec3* pos = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); + luaL_argcheck(L, pos != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + (*spinfo)->lookAt(*pos); + return 0; +} + +LUAAPI(simplayer_moveTo) { + LUA_ARG_COUNT_CHECK_M(1) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + Vec3* pos = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); + luaL_argcheck(L, pos != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + (*spinfo)->moveTo(*pos); + return 0; +} + +LUAAPI(simplayer_navigateTo) { + LUA_ARG_COUNT_CHECK_M(1) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + Vec3* pos = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); + luaL_argcheck(L, pos != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + (*spinfo)->navigateTo(*pos); + return 0; +} + +LUAAPI(simplayer_isTaskFree) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + lua_pushboolean(L, (*spinfo)->isTaskFree()); + return 1; +} + +LUAAPI(simplayer_stopAction) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck( + L, + (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), + 1, + "invalid userdata" + ); + lua_settop(L, 0); + (*spinfo)->stopAction(); + return 0; +} + +LUAAPI(simplayer_meta_gc) { + LUA_ARG_COUNT_CHECK_M(0) + SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); + luaL_argcheck(L, (spinfo != nullptr) && ((*spinfo) != nullptr), 1, "invalid userdata"); + lua_settop(L, 0); + delete *spinfo; + return 0; +} + +const luaL_Reg lua_reg_simplayer_m[34] = { + {"getName", lua_api_simplayer_getName }, + {"getXuid", lua_api_simplayer_getXuid }, + {"getStatus", lua_api_simplayer_getStatus }, + {"getPos", lua_api_simplayer_getPos }, + {"getFeetPos", lua_api_simplayer_getFeetPos }, + {"getStandingOn", lua_api_simplayer_getStandingOn }, + {"getRot", lua_api_simplayer_getRot }, + {"getHealth", lua_api_simplayer_getHealth }, + {"getHunger", lua_api_simplayer_getHunger }, + {"sneaking", lua_api_simplayer_sneaking }, + {"swimming", lua_api_simplayer_swimming }, + {"attack", lua_api_simplayer_attack }, + {"chat", lua_api_simplayer_chat }, + {"destroy", lua_api_simplayer_destroy }, + {"dropSelectedItem", lua_api_simplayer_dropSelectedItem }, + {"dropInv", lua_api_simplayer_dropInv }, + {"runCmd", lua_api_simplayer_runCmd }, + {"getBlockPosFromView", lua_api_simplayer_getBlockPosFromView}, + {"searchInInvWithId", lua_api_simplayer_searchInInvWithId }, + {"searchInInvWithName", lua_api_simplayer_searchInInvWithName}, + {"selectSlot", lua_api_simplayer_selectSlot }, + {"select", lua_api_simplayer_select }, + {"getItemFromInv", lua_api_simplayer_getItemFromInv }, + {"interact", lua_api_simplayer_interact }, + {"jump", lua_api_simplayer_jump }, + {"useItem", lua_api_simplayer_useItem }, + {"startBuild", lua_api_simplayer_startBuild }, + {"lookAt", lua_api_simplayer_lookAt }, + {"moveTo", lua_api_simplayer_moveTo }, + {"navigateTo", lua_api_simplayer_navigateTo }, + {"isTaskFree", lua_api_simplayer_isTaskFree }, + {"stopAction", lua_api_simplayer_stopAction }, + {"__gc", lua_api_simplayer_meta_gc }, + {NULL, NULL } +}; + +LUAAPI(open_simplayer) { + luaL_newmetatable(L, "simplayer_mt"); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + luaL_setfuncs(L, lua_reg_simplayer_m, 0); + luaL_newlib(L, lua_reg_null_c); + return 1; +} + +// userdata simplayer end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/SimPlayer.h b/src/cfsp/simplayer/luaapi/SimPlayer.h new file mode 100644 index 0000000..19aa60a --- /dev/null +++ b/src/cfsp/simplayer/luaapi/SimPlayer.h @@ -0,0 +1,90 @@ +#pragma once + +#include "cfsp/base/Macros.h" + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata simplayer begin + +int lua_api_simplayer_getName(lua_State*); + +int lua_api_simplayer_getXuid(lua_State*); + +int lua_api_simplayer_getStatus(lua_State*); + +int lua_api_simplayer_getPos(lua_State*); + +int lua_api_simplayer_getFeetPos(lua_State*); + +int lua_api_simplayer_getStandingOn(lua_State*); + +int lua_api_simplayer_getRot(lua_State*); + +int lua_api_simplayer_getHealth(lua_State*); + +int lua_api_simplayer_getHunger(lua_State*); + +int lua_api_simplayer_sneaking(lua_State*); + +int lua_api_simplayer_swimming(lua_State*); + +int lua_api_simplayer_attack(lua_State*); + +int lua_api_simplayer_chat(lua_State*); + +int lua_api_simplayer_destroy(lua_State*); + +int lua_api_simplayer_dropSelectedItem(lua_State*); + +int lua_api_simplayer_dropInv(lua_State*); + +int lua_api_simplayer_runCmd(lua_State*); + +int lua_api_simplayer_getBlockPosFromView(lua_State*); + +int lua_api_simplayer_searchInInvWithId(lua_State*); + +int lua_api_simplayer_searchInInvWithName(lua_State*); + +int lua_api_simplayer_selectSlot(lua_State*); + +int lua_api_simplayer_select(lua_State*); + +int lua_api_simplayer_getItemFromInv(lua_State*); + +int lua_api_simplayer_interact(lua_State*); + +int lua_api_simplayer_jump(lua_State*); + +int lua_api_simplayer_useItem(lua_State*); + +int lua_api_simplayer_startBuild(lua_State*); + +int lua_api_simplayer_lookAt(lua_State*); + +int lua_api_simplayer_moveTo(lua_State*); + +int lua_api_simplayer_navigateTo(lua_State*); + +int lua_api_simplayer_isTaskFree(lua_State*); + +int lua_api_simplayer_stopAction(lua_State*); + +int lua_api_simplayer_meta_gc(lua_State*); + +extern const luaL_Reg lua_reg_simplayer_m[34]; + +int lua_api_open_simplayer(lua_State*); + +// userdata simplayer end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/SpLuaApi.cpp b/src/cfsp/simplayer/luaapi/SpLuaApi.cpp index 61c86ba..62fd60f 100644 --- a/src/cfsp/simplayer/luaapi/SpLuaApi.cpp +++ b/src/cfsp/simplayer/luaapi/SpLuaApi.cpp @@ -1,37 +1,23 @@ -#include "boost/algorithm/string/join.hpp" #include "cfsp/CFSP.h" #include "cfsp/base/Macros.h" #include "cfsp/base/Mod.h" -#include "cfsp/base/Utils.h" #include "cfsp/simplayer/CFSP.h" -#include "ll/api/base/StdInt.h" -#include "ll/api/service/Bedrock.h" -#include "mc/math/Vec2.h" -#include "mc/math/Vec3.h" -#include "mc/nbt/ByteArrayTag.h" -#include "mc/nbt/ByteTag.h" -#include "mc/nbt/CompoundTag.h" -#include "mc/nbt/CompoundTagVariant.h" -#include "mc/nbt/FloatTag.h" -#include "mc/nbt/IntArrayTag.h" -#include "mc/nbt/IntTag.h" -#include "mc/nbt/ListTag.h" -#include "mc/nbt/ShortTag.h" -#include "mc/nbt/StringTag.h" -#include "mc/nbt/Tag.h" #include "mc/network/packet/TextPacket.h" -#include "mc/util/ProfilerLite.h" -#include "mc/world/item/registry/ItemStack.h" -#include "mc/world/level/BlockPos.h" -#include "mc/world/level/BlockSource.h" -#include "mc/world/level/Level.h" -#include "mc/world/level/block/Block.h" -#include "mc/world/level/dimension/Dimension.h" #include #include #include #include +#include "cfsp/simplayer/luaapi/BlockInfo.h" +#include "cfsp/simplayer/luaapi/BlockPos.h" +#include "cfsp/simplayer/luaapi/BlockSource.h" +#include "cfsp/simplayer/luaapi/ItemInfo.h" +#include "cfsp/simplayer/luaapi/Level.h" +#include "cfsp/simplayer/luaapi/Log.h" +#include "cfsp/simplayer/luaapi/SimPlayer.h" +#include "cfsp/simplayer/luaapi/Vec2.h" +#include "cfsp/simplayer/luaapi/Vec3.h" + extern "C" { #include "lauxlib.h" #include "lua.h" @@ -42,2074 +28,6 @@ namespace coral_fans::cfsp { namespace sputils::lua_api { -namespace { - -void compoundTagToLuaTable(lua_State* L, CompoundTagVariant tag) { - if (tag.hold(Tag::Compound)) { - lua_newtable(L); - for (const auto& item : tag.get()) { - lua_pushstring(L, item.first.c_str()); - compoundTagToLuaTable(L, item.second); - lua_settable(L, -3); - } - return; - } - if (tag.hold(Tag::ByteArray)) { - int idx = 1; - lua_newtable(L); - for (const auto& item : tag.get()) { - lua_pushinteger(L, item); - lua_seti(L, -2, idx); - ++idx; - } - return; - } - if (tag.hold(Tag::IntArray)) { - int idx = 1; - lua_newtable(L); - for (const auto& item : tag.get()) { - lua_pushinteger(L, item); - lua_seti(L, -2, idx); - ++idx; - } - return; - } - if (tag.hold(Tag::List)) { - int idx = 1; - lua_newtable(L); - for (const auto& item : tag.get()) { - compoundTagToLuaTable(L, item); - lua_seti(L, -2, idx); - ++idx; - } - return; - } - if (tag.hold(Tag::Byte)) { - lua_pushinteger(L, tag.get()); - return; - } - if (tag.hold(Tag::Double)) { - lua_pushnumber(L, tag.get()); - return; - } - if (tag.hold(Tag::Float)) { - lua_pushnumber(L, tag.get()); - return; - } - if (tag.hold(Tag::Int)) { - lua_pushinteger(L, tag.get()); - return; - } - if (tag.hold(Tag::Int64)) { - lua_pushinteger(L, tag.get()); - return; - } - if (tag.hold(Tag::Short)) { - lua_pushinteger(L, tag.get()); - return; - } - if (tag.hold(Tag::String)) { - lua_pushstring(L, tag.get().c_str()); - return; - } -} - -} // namespace - -namespace { - -LUAAPI(log) { - int count = lua_gettop(L); - std::list lst; - for (int i = 1; i <= count; ++i) lst.emplace_back(luaL_checkstring(L, i)); - CFSP::getInstance().getSelf().getLogger().info("[CFSP-Lua] {}", boost::algorithm::join(lst, "\t")); - return 0; -} - -// userdata vec3 begin - -LUAAPI(vec3_new) { - LUA_ARG_COUNT_CHECK_C(3) - float x = static_cast(luaL_checknumber(L, 1)); - float y = static_cast(luaL_checknumber(L, 2)); - float z = static_cast(luaL_checknumber(L, 3)); - lua_settop(L, 0); - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - pos->x = x; - pos->y = y; - pos->z = z; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newHalf) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::HALF; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newMax) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::MAX; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newMin) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::MIN; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newNegUnitX) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::NEG_UNIT_X; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newNegUnitY) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::NEG_UNIT_Y; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newNegUnitZ) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::NEG_UNIT_Z; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newOne) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::ONE; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newTwo) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::TWO; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newUnitX) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::UNIT_X; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newUnitY) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::UNIT_Y; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newUnitZ) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::UNIT_Z; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_newZero) { - LUA_ARG_COUNT_CHECK_C(0) - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3::ZERO; - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -static const luaL_Reg lua_reg_vec3_c[] = { - {"new", lua_api_vec3_new }, - {"newHalf", lua_api_vec3_newHalf }, - {"newMax", lua_api_vec3_newMax }, - {"newMin", lua_api_vec3_newMin }, - {"newNegUnitX", lua_api_vec3_newNegUnitX}, - {"newNegUnitY", lua_api_vec3_newNegUnitY}, - {"newNegUnitZ", lua_api_vec3_newNegUnitZ}, - {"newOne", lua_api_vec3_newOne }, - {"newTwo", lua_api_vec3_newTwo }, - {"newUnitX", lua_api_vec3_newUnitX }, - {"newUnitY", lua_api_vec3_newUnitY }, - {"newUnitZ", lua_api_vec3_newUnitZ }, - {"newZero", lua_api_vec3_newZero }, - {NULL, NULL } -}; - -LUAAPI(vec3_get) { - LUA_ARG_COUNT_CHECK_M(0) - Vec3* pos = (Vec3*)luaL_checkudata(L, 1, "vec3_mt"); - luaL_argcheck(L, pos != nullptr, 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushnumber(L, pos->x); - lua_pushnumber(L, pos->y); - lua_pushnumber(L, pos->z); - return 3; -} - -LUAAPI(vec3_meta_tostring) { - LUA_ARG_COUNT_CHECK_M(0) - Vec3* pos = (Vec3*)luaL_checkudata(L, 1, "vec3_mt"); - luaL_argcheck(L, pos != nullptr, 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushstring(L, pos->toString().c_str()); - return 1; -} - -LUAAPI(vec3_meta_add) { - LUA_ARG_COUNT_CHECK_M(1) - Vec3* pos1 = (Vec3*)luaL_checkudata(L, 1, "vec3_mt"); - luaL_argcheck(L, pos1 != nullptr, 1, "invalid userdata"); - Vec3* pos2 = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); - luaL_argcheck(L, pos2 != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = (*pos1) + (*pos2); - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_meta_sub) { - LUA_ARG_COUNT_CHECK_M(1) - Vec3* pos1 = (Vec3*)luaL_checkudata(L, 1, "vec3_mt"); - luaL_argcheck(L, pos1 != nullptr, 1, "invalid userdata"); - Vec3* pos2 = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); - luaL_argcheck(L, pos2 != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = (*pos1) - (*pos2); - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(vec3_meta_eq) { - LUA_ARG_COUNT_CHECK_M(1) - Vec3* pos1 = (Vec3*)luaL_checkudata(L, 1, "vec3_mt"); - luaL_argcheck(L, pos1 != nullptr, 1, "invalid userdata"); - Vec3* pos2 = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); - luaL_argcheck(L, pos2 != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, ((*pos1) == (*pos2))); - return 1; -} - -static const luaL_Reg lua_reg_vec3_m[] = { - {"get", lua_api_vec3_get }, - {"__tostring", lua_api_vec3_meta_tostring}, - {"__add", lua_api_vec3_meta_add }, - {"__sub", lua_api_vec3_meta_sub }, - {"__eq", lua_api_vec3_meta_eq }, - {NULL, NULL } -}; - -LUAAPI(open_vec3) { - luaL_newmetatable(L, "vec3_mt"); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - luaL_setfuncs(L, lua_reg_vec3_m, 0); - luaL_newlib(L, lua_reg_vec3_c); - return 1; -} - -// userdata vec3 end - -// userdata blockpos begin - -LUAAPI(blockpos_new) { - LUA_ARG_COUNT_CHECK_C(3) - int x = static_cast(luaL_checkinteger(L, 1)); - int y = static_cast(luaL_checkinteger(L, 2)); - int z = static_cast(luaL_checkinteger(L, 3)); - lua_settop(L, 0); - BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); - bp->x = x; - bp->y = y; - bp->z = z; - luaL_setmetatable(L, "blockpos_mt"); - return 1; -} - -LUAAPI(blockpos_newMax) { - LUA_ARG_COUNT_CHECK_C(0) - BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); - *bp = BlockPos::MAX; - luaL_setmetatable(L, "blockpos_mt"); - return 1; -} - -LUAAPI(blockpos_newMin) { - LUA_ARG_COUNT_CHECK_C(0) - BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); - *bp = BlockPos::MIN; - luaL_setmetatable(L, "blockpos_mt"); - return 1; -} - -LUAAPI(blockpos_newOne) { - LUA_ARG_COUNT_CHECK_C(0) - BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); - *bp = BlockPos::ONE; - luaL_setmetatable(L, "blockpos_mt"); - return 1; -} - -LUAAPI(blockpos_newZero) { - LUA_ARG_COUNT_CHECK_C(0) - BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); - *bp = BlockPos::ZERO; - luaL_setmetatable(L, "blockpos_mt"); - return 1; -} - -static const luaL_Reg lua_reg_blockpos_c[] = { - {"new", lua_api_blockpos_new }, - {"newMax", lua_api_blockpos_newMax }, - {"newMin", lua_api_blockpos_newMin }, - {"newOne", lua_api_blockpos_newOne }, - {"newZero", lua_api_blockpos_newZero}, - {NULL, NULL } -}; - -LUAAPI(blockpos_get) { - LUA_ARG_COUNT_CHECK_M(0) - BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); - luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushinteger(L, bp->x); - lua_pushinteger(L, bp->y); - lua_pushinteger(L, bp->z); - return 3; -} - -LUAAPI(blockpos_bottomCenter) { - LUA_ARG_COUNT_CHECK_M(0) - BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); - luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); - lua_settop(L, 0); - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = bp->bottomCenter(); - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(blockpos_center) { - LUA_ARG_COUNT_CHECK_M(0) - BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); - luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); - lua_settop(L, 0); - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = bp->center(); - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(blockpos_toVec3) { - LUA_ARG_COUNT_CHECK_M(0) - BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); - luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); - lua_settop(L, 0); - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = Vec3(*bp); - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(blockpos_neighbor) { - LUA_ARG_COUNT_CHECK_M(1) - BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); - luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); - uchar facing = static_cast(luaL_checkinteger(L, 2)); - lua_settop(L, 0); - BlockPos* ret_bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); - *ret_bp = bp->neighbor(facing); - luaL_setmetatable(L, "blockpos_mt"); - return 1; -} - -LUAAPI(blockpos_meta_tostring) { - LUA_ARG_COUNT_CHECK_M(0) - BlockPos* bp = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); - luaL_argcheck(L, bp != nullptr, 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushstring(L, bp->toString().c_str()); - return 1; -} - -LUAAPI(blockpos_meta_add) { - LUA_ARG_COUNT_CHECK_M(1) - BlockPos* bp1 = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); - luaL_argcheck(L, bp1 != nullptr, 1, "invalid userdata"); - BlockPos* bp2 = (BlockPos*)luaL_checkudata(L, 2, "blockpos_mt"); - luaL_argcheck(L, bp2 != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); - *bp = (*bp1) + (*bp2); - luaL_setmetatable(L, "blockpos_mt"); - return 1; -} - -LUAAPI(blockpos_meta_sub) { - LUA_ARG_COUNT_CHECK_M(1) - BlockPos* bp1 = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); - luaL_argcheck(L, bp1 != nullptr, 1, "invalid userdata"); - BlockPos* bp2 = (BlockPos*)luaL_checkudata(L, 2, "blockpos_mt"); - luaL_argcheck(L, bp2 != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); - *bp = (*bp1) - (*bp2); - luaL_setmetatable(L, "blockpos_mt"); - return 1; -} - -LUAAPI(blockpos_meta_eq) { - LUA_ARG_COUNT_CHECK_M(1) - BlockPos* bp1 = (BlockPos*)luaL_checkudata(L, 1, "blockpos_mt"); - luaL_argcheck(L, bp1 != nullptr, 1, "invalid userdata"); - BlockPos* bp2 = (BlockPos*)luaL_checkudata(L, 2, "blockpos_mt"); - luaL_argcheck(L, bp2 != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, ((*bp1) == (*bp2))); - return 1; -} - -static const luaL_Reg lua_reg_blockpos_m[] = { - {"get", lua_api_blockpos_get }, - {"bottomCenter", lua_api_blockpos_bottomCenter }, - {"center", lua_api_blockpos_center }, - {"toVec3", lua_api_blockpos_toVec3 }, - {"neighbor", lua_api_blockpos_neighbor }, - {"__tostring", lua_api_blockpos_meta_tostring}, - {"__add", lua_api_blockpos_meta_add }, - {"__sub", lua_api_blockpos_meta_sub }, - {"__eq", lua_api_blockpos_meta_eq }, - {NULL, NULL } -}; - -LUAAPI(open_blockpos) { - luaL_newmetatable(L, "blockpos_mt"); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - luaL_setfuncs(L, lua_reg_blockpos_m, 0); - luaL_newlib(L, lua_reg_blockpos_c); - return 1; -} - -// userdata blockpos end - -// userdata vec2 begin - -LUAAPI(vec2_new) { - LUA_ARG_COUNT_CHECK_C(2) - float x = static_cast(luaL_checknumber(L, 1)); - float y = static_cast(luaL_checknumber(L, 2)); - lua_settop(L, 0); - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - rot->x = x; - rot->y = y; - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(vec2_newLowest) { - LUA_ARG_COUNT_CHECK_C(0) - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *rot = Vec2::LOWEST; - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(vec2_newMax) { - LUA_ARG_COUNT_CHECK_C(0) - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *rot = Vec2::MAX; - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(vec2_newMin) { - LUA_ARG_COUNT_CHECK_C(0) - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *rot = Vec2::MIN; - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(vec2_newNegUnitX) { - LUA_ARG_COUNT_CHECK_C(0) - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *rot = Vec2::NEG_UNIT_X; - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(vec2_newNegUnitY) { - LUA_ARG_COUNT_CHECK_C(0) - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *rot = Vec2::NEG_UNIT_Y; - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(vec2_newOne) { - LUA_ARG_COUNT_CHECK_C(0) - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *rot = Vec2::ONE; - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(vec2_newUnitX) { - LUA_ARG_COUNT_CHECK_C(0) - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *rot = Vec2::UNIT_X; - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(vec2_newUnitY) { - LUA_ARG_COUNT_CHECK_C(0) - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *rot = Vec2::UNIT_Y; - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(vec2_newZero) { - LUA_ARG_COUNT_CHECK_C(0) - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *rot = Vec2::ZERO; - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -static const luaL_Reg lua_reg_vec2_c[] = { - {"new", lua_api_vec2_new }, - {"newLowest", lua_api_vec2_newLowest }, - {"newMax", lua_api_vec2_newMax }, - {"newMin", lua_api_vec2_newMin }, - {"newNegUnitX", lua_api_vec2_newNegUnitX}, - {"newNegUnitY", lua_api_vec2_newNegUnitY}, - {"newOne", lua_api_vec2_newOne }, - {"newUnitX", lua_api_vec2_newUnitX }, - {"newUnitY", lua_api_vec2_newUnitY }, - {"newZero", lua_api_vec2_newZero }, - {NULL, NULL } -}; - -LUAAPI(vec2_get) { - LUA_ARG_COUNT_CHECK_M(0) - Vec2* rot = (Vec2*)luaL_checkudata(L, 1, "vec2_mt"); - luaL_argcheck(L, rot != nullptr, 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushnumber(L, rot->x); - lua_pushnumber(L, rot->y); - return 2; -} - -LUAAPI(vec2_meta_tostring) { - LUA_ARG_COUNT_CHECK_M(0) - Vec2* rot = (Vec2*)luaL_checkudata(L, 1, "vec2_mt"); - luaL_argcheck(L, rot != nullptr, 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushstring(L, rot->toString().c_str()); - return 1; -} - -LUAAPI(vec2_meta_add) { - LUA_ARG_COUNT_CHECK_M(1) - Vec2* rot1 = (Vec2*)luaL_checkudata(L, 1, "vec2_mt"); - luaL_argcheck(L, rot1 != nullptr, 1, "invalid userdata"); - Vec2* rot2 = (Vec2*)luaL_checkudata(L, 2, "vec2_mt"); - luaL_argcheck(L, rot2 != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *rot = (*rot1) + (*rot2); - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(vec2_meta_sub) { - LUA_ARG_COUNT_CHECK_M(1) - Vec2* rot1 = (Vec2*)luaL_checkudata(L, 1, "vec2_mt"); - luaL_argcheck(L, rot1 != nullptr, 1, "invalid userdata"); - Vec2* rot2 = (Vec2*)luaL_checkudata(L, 2, "vec2_mt"); - luaL_argcheck(L, rot2 != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *rot = (*rot1) - (*rot2); - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(vec2_meta_eq) { - LUA_ARG_COUNT_CHECK_M(1) - Vec2* rot1 = (Vec2*)luaL_checkudata(L, 1, "vec2_mt"); - luaL_argcheck(L, rot1 != nullptr, 1, "invalid userdata"); - Vec2* rot2 = (Vec2*)luaL_checkudata(L, 2, "vec2_mt"); - luaL_argcheck(L, rot2 != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, ((*rot1) == (*rot2))); - return 1; -} - -static const luaL_Reg lua_reg_vec2_m[] = { - {"get", lua_api_vec2_get }, - {"__tostring", lua_api_vec2_meta_tostring}, - {"__add", lua_api_vec2_meta_add }, - {"__sub", lua_api_vec2_meta_sub }, - {"__eq", lua_api_vec2_meta_eq }, - {NULL, NULL } -}; - -LUAAPI(open_vec2) { - luaL_newmetatable(L, "vec2_mt"); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - luaL_setfuncs(L, lua_reg_vec2_m, 0); - luaL_newlib(L, lua_reg_vec2_c); - return 1; -} - -// userdata vec2 end - -static const luaL_Reg lua_reg_null_c[] = { - {NULL, NULL} -}; - -// userdata blockinfo begin - -class BlockInfo { -public: - std::string name; - std::string type; - int id; - BlockPos pos; - int dim; - int variant; - float translucency; - float thickness; - bool isAir; - bool isBounceBlock; - bool isButtonBlock; - bool isCropBlock; - bool isDoorBlock; - bool isFallingBlock; - bool isFenceBlock; - bool isFenceGateBlock; - bool isSlabBlock; - bool isStemBlock; - bool isThinFenceBlock; - bool isUnbreakable; - bool isWaterBlockingBlock; - std::unique_ptr tag; - -public: - BlockInfo(BlockPos const bp, int d, Block const& bl) - : name(bl.buildDescriptionName()), - type(bl.getTypeName()), - id(bl.getBlockItemId()), - pos(bp), - dim(d), - variant(bl.getVariant()), - translucency(bl.getTranslucency()), - thickness(bl.getThickness()), - isAir(bl.isAir()), - isBounceBlock(bl.isBounceBlock()), - isButtonBlock(bl.isButtonBlock()), - isCropBlock(bl.isCropBlock()), - isDoorBlock(bl.isDoorBlock()), - isFallingBlock(bl.isFallingBlock()), - isFenceBlock(bl.isFenceBlock()), - isFenceGateBlock(bl.isFenceGateBlock()), - isSlabBlock(bl.isSlabBlock()), - isStemBlock(bl.isStemBlock()), - isThinFenceBlock(bl.isThinFenceBlock()), - isUnbreakable(bl.isUnbreakable()), - isWaterBlockingBlock(bl.isWaterBlocking()), - tag(std::make_unique(bl.getSerializationId())) {} - - bool operator==(const BlockInfo& bi) const { - return name == bi.name && type == bi.type && id == bi.id && pos == bi.pos && dim == bi.dim - && variant == bi.variant && translucency == bi.translucency && thickness == bi.thickness - && isAir == bi.isAir && isBounceBlock == bi.isBounceBlock && isButtonBlock == bi.isButtonBlock - && isCropBlock == bi.isCropBlock && isDoorBlock == bi.isDoorBlock && isFallingBlock == bi.isFallingBlock - && isFenceBlock == bi.isFenceBlock && isFenceGateBlock == bi.isFenceGateBlock - && isSlabBlock == bi.isSlabBlock && isStemBlock == bi.isStemBlock && isThinFenceBlock == bi.isThinFenceBlock - && isUnbreakable == bi.isUnbreakable && isWaterBlockingBlock == bi.isWaterBlockingBlock - && *tag == (*bi.tag); - } -}; - -LUAAPI(blockinfo_getName) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushstring(L, (*binfo)->name.c_str()); - return 1; -} - -LUAAPI(blockinfo_getType) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushstring(L, (*binfo)->type.c_str()); - return 1; -} - -LUAAPI(blockinfo_getId) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushinteger(L, (*binfo)->id); - return 1; -} - -LUAAPI(blockinfo_getPos) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - BlockPos* bp = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); - *bp = (*binfo)->pos; - luaL_setmetatable(L, "blockpos_mt"); - return 1; -} - -LUAAPI(blockinfo_getDim) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushinteger(L, (*binfo)->dim); - return 1; -} - -LUAAPI(blockinfo_getVariant) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushinteger(L, (*binfo)->variant); - return 1; -} - -LUAAPI(blockinfo_getTranslucency) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushnumber(L, (*binfo)->translucency); - return 1; -} - -LUAAPI(blockinfo_getThickness) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushnumber(L, (*binfo)->thickness); - return 1; -} - -LUAAPI(blockinfo_isAir) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isAir); - return 1; -} - -LUAAPI(blockinfo_isBounceBlock) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isBounceBlock); - return 1; -} - -LUAAPI(blockinfo_isButtonBlock) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isButtonBlock); - return 1; -} - -LUAAPI(blockinfo_isCropBlock) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isCropBlock); - return 1; -} - -LUAAPI(blockinfo_isDoorBlock) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isDoorBlock); - return 1; -} - -LUAAPI(blockinfo_isFallingBlock) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isFallingBlock); - return 1; -} - -LUAAPI(blockinfo_isFenceBlock) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isFenceBlock); - return 1; -} - -LUAAPI(blockinfo_isFenceGateBlock) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isFenceGateBlock); - return 1; -} - -LUAAPI(blockinfo_isSlabBlock) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isSlabBlock); - return 1; -} - -LUAAPI(blockinfo_isStemBlock) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isStemBlock); - return 1; -} - -LUAAPI(blockinfo_isThinFenceBlock) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isThinFenceBlock); - return 1; -} - -LUAAPI(blockinfo_isUnbreakable) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isUnbreakable); - return 1; -} - -LUAAPI(blockinfo_isWaterBlockingBlock) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*binfo)->isWaterBlockingBlock); - return 1; -} - -LUAAPI(blockinfo_getNbtTable) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - compoundTagToLuaTable(L, *((*binfo)->tag)); - return 1; -} - -LUAAPI(blockinfo_getSnbt) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushstring(L, (*binfo)->tag->toSnbt(SnbtFormat::Minimize).c_str()); - return 1; -} - -LUAAPI(blockinfo_getSnbtWithPath) { - LUA_ARG_COUNT_CHECK_M(1) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - std::string path = luaL_checkstring(L, 2); - lua_settop(L, 0); - const auto& rst = utils::getNbtFromTag(*((*binfo)->tag), path); - lua_pushstring(L, rst.first.c_str()); - lua_pushboolean(L, rst.second); - return 2; -} - -LUAAPI(blockinfo_meta_eq) { - LUA_ARG_COUNT_CHECK_M(1) - BlockInfo** binfo1 = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo1 != nullptr) && ((*binfo1) != nullptr), 1, "invalid userdata"); - BlockInfo** binfo2 = (BlockInfo**)luaL_checkudata(L, 2, "blockinfo_mt"); - luaL_argcheck(L, (binfo2 != nullptr) && ((*binfo2) != nullptr), 2, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, ((**binfo1) == (**binfo2))); - return 1; -} - -LUAAPI(blockinfo_meta_gc) { - LUA_ARG_COUNT_CHECK_M(0) - BlockInfo** binfo = (BlockInfo**)luaL_checkudata(L, 1, "blockinfo_mt"); - luaL_argcheck(L, (binfo != nullptr) && ((*binfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - delete *binfo; - return 0; -} - -static const luaL_Reg lua_reg_blockinfo_m[] = { - {"getName", lua_api_blockinfo_getName }, - {"getType", lua_api_blockinfo_getType }, - {"getId", lua_api_blockinfo_getId }, - {"getPos", lua_api_blockinfo_getPos }, - {"getDim", lua_api_blockinfo_getDim }, - {"getVariant", lua_api_blockinfo_getVariant }, - {"getTranslucency", lua_api_blockinfo_getTranslucency }, - {"getThickness", lua_api_blockinfo_getThickness }, - {"isAir", lua_api_blockinfo_isAir }, - {"isBounceBlock", lua_api_blockinfo_isBounceBlock }, - {"isButtonBlock", lua_api_blockinfo_isButtonBlock }, - {"isCropBlock", lua_api_blockinfo_isCropBlock }, - {"isDoorBlock", lua_api_blockinfo_isDoorBlock }, - {"isFallingBlock", lua_api_blockinfo_isFallingBlock }, - {"isFenceBlock", lua_api_blockinfo_isFenceBlock }, - {"isFenceGateBlock", lua_api_blockinfo_isFenceGateBlock }, - {"isSlabBlock", lua_api_blockinfo_isSlabBlock }, - {"isStemBlock", lua_api_blockinfo_isStemBlock }, - {"isThinFenceBlock", lua_api_blockinfo_isThinFenceBlock }, - {"isUnbreakable", lua_api_blockinfo_isUnbreakable }, - {"isWaterBlockingBlock", lua_api_blockinfo_isWaterBlockingBlock}, - {"getNbtTable", lua_api_blockinfo_getNbtTable }, - {"getSnbt", lua_api_blockinfo_getSnbt }, - {"getSnbtWithPath", lua_api_blockinfo_getSnbtWithPath }, - {"__eq", lua_api_blockinfo_meta_eq }, - {"__gc", lua_api_blockinfo_meta_gc }, - {NULL, NULL } -}; - -LUAAPI(open_blockinfo) { - luaL_newmetatable(L, "blockinfo_mt"); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - luaL_setfuncs(L, lua_reg_blockinfo_m, 0); - luaL_newlib(L, lua_reg_null_c); - return 1; -} - -// userdata blockinfo end - -// userdata blocksource begin - -LUAAPI(blocksource_getBlockInfo) { - LUA_ARG_COUNT_CHECK_M(1) - int* dimid = (int*)luaL_checkudata(L, 1, "blocksource_mt"); - luaL_argcheck(L, dimid != nullptr, 1, "invalid userdata"); - BlockPos* bp = (BlockPos*)luaL_checkudata(L, 2, "blockpos_mt"); - luaL_argcheck(L, bp != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - auto level = ll::service::getLevel(); - if (!level.has_value()) { - lua_pushnil(L); - lua_pushboolean(L, false); - return 2; - } - const auto& block = level->getDimension(*dimid)->getBlockSourceFromMainChunkSource().getBlock(*bp); - BlockInfo** binfo = (BlockInfo**)lua_newuserdata(L, sizeof(BlockInfo*)); - *binfo = new BlockInfo(*bp, *dimid, block); - luaL_setmetatable(L, "blockinfo_mt"); - lua_pushboolean(L, true); - return 2; -} - -static const luaL_Reg lua_reg_blocksource_m[] = { - {"getBlockInfo", lua_api_blocksource_getBlockInfo}, - {NULL, NULL } -}; - -LUAAPI(open_blocksource) { - luaL_newmetatable(L, "blocksource_mt"); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - luaL_setfuncs(L, lua_reg_blocksource_m, 0); - luaL_newlib(L, lua_reg_null_c); - return 1; -} - -// userdata blocksource end - -// userdata level begin - -LUAAPI(level_getDayTime) { - LUA_ARG_COUNT_CHECK_M(0) - luaL_checkudata(L, 1, "level_mt"); - lua_settop(L, 0); - auto level = ll::service::getLevel(); - if (!level.has_value()) { - lua_pushinteger(L, -1); - return 1; - } - lua_pushinteger(L, level->getTime() % 24000); - return 1; -} - -LUAAPI(level_getGameTime) { - LUA_ARG_COUNT_CHECK_M(0) - luaL_checkudata(L, 1, "level_mt"); - lua_settop(L, 0); - auto level = ll::service::getLevel(); - if (!level.has_value()) { - lua_pushinteger(L, -1); - return 1; - } - lua_pushinteger(L, level->getCurrentTick().t); - return 1; -} - -LUAAPI(level_getDay) { - LUA_ARG_COUNT_CHECK_M(0) - luaL_checkudata(L, 1, "level_mt"); - lua_settop(L, 0); - auto level = ll::service::getLevel(); - if (!level.has_value()) { - lua_pushinteger(L, -1); - return 1; - } - lua_pushinteger(L, level->getTime() / 24000); - return 1; -} - -LUAAPI(level_getMspt) { - LUA_ARG_COUNT_CHECK_M(0) - luaL_checkudata(L, 1, "level_mt"); - lua_settop(L, 0); - lua_pushnumber(L, static_cast(ProfilerLite::gProfilerLiteInstance.getServerTickTime().count() / 1000000.0)); - return 1; -} - -const static luaL_Reg lua_reg_level_m[] = { - {"getDayTime", lua_api_level_getDayTime }, - {"getGameTime", lua_api_level_getGameTime}, - {"getDay", lua_api_level_getDay }, - {"getMspt", lua_api_level_getMspt }, - {NULL, NULL } -}; - -LUAAPI(open_level) { - luaL_newmetatable(L, "level_mt"); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - luaL_setfuncs(L, lua_reg_level_m, 0); - luaL_newlib(L, lua_reg_null_c); - return 1; -} - -// userdata level end - -// userdata iteminfo begin - -class ItemInfo { -public: - std::string name; - std::string type; - int id; - int count; - int aux; - int damage; - int attackDamage; - int maxDamage; - int maxStackSize; - std::vector lore; - bool isArmorItem; - bool isBlock; - bool isDamageableItem; - bool isDamaged; - bool isEnchanted; - bool isEnchantingBook; - bool isFireResistant; - bool isFullStack; - bool isGlint; - bool isHorseArmorItem; - bool isLiquidClipItem; - bool isMusicDiscItem; - bool isOffhandItem; - bool isPotionItem; - bool isStackable; - bool isWearableItem; - std::unique_ptr tag; - -public: - ItemInfo(ItemStack const& item) - : name(item.getCustomName().empty() ? item.getName() : item.getCustomName()), - type(item.getTypeName()), - id(item.getId()), - count(item.mCount), - aux(item.getAuxValue()), - damage(item.getDamageValue()), - attackDamage(item.getAttackDamage()), - maxDamage(item.getMaxDamage()), - maxStackSize(item.getMaxStackSize()), - lore(item.getCustomLore()), - isArmorItem(item.isArmorItem()), - isBlock(item.isBlock()), - isDamageableItem(item.isDamageableItem()), - isDamaged(item.isDamaged()), - isEnchanted(item.isEnchanted()), - isEnchantingBook(item.isEnchantingBook()), - isFireResistant(item.isFireResistant()), - isFullStack(item.isFullStack()), - isGlint(item.isGlint()), - isHorseArmorItem(item.isHorseArmorItem()), - isLiquidClipItem(item.isLiquidClipItem()), - isMusicDiscItem(item.isMusicDiscItem()), - isOffhandItem(item.isOffhandItem()), - isPotionItem(item.isPotionItem()), - isStackable(item.isStackable()), - isWearableItem(item.isHumanoidWearableItem()), - tag(item.save()) {} - bool operator==(const ItemInfo& rt) const { - return name == rt.name && type == rt.type && id == rt.id && count == rt.count && aux == rt.aux - && damage == rt.damage && attackDamage == rt.attackDamage && maxDamage == rt.maxDamage - && maxStackSize == rt.maxStackSize && lore == rt.lore && isArmorItem == rt.isArmorItem - && isBlock == rt.isBlock && isDamageableItem == rt.isDamageableItem && isDamaged == rt.isDamaged - && isEnchanted == rt.isEnchanted && isEnchantingBook == rt.isEnchantingBook - && isFireResistant == rt.isFireResistant && isFullStack == rt.isFullStack && isGlint == rt.isGlint - && isHorseArmorItem == rt.isHorseArmorItem && isLiquidClipItem == rt.isLiquidClipItem - && isMusicDiscItem == rt.isMusicDiscItem && isOffhandItem == rt.isOffhandItem - && isPotionItem == rt.isPotionItem && isStackable == rt.isStackable && isWearableItem == rt.isWearableItem - && (*tag) == (*rt.tag); - } -}; - -LUAAPI(iteminfo_getName) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushstring(L, (*info)->name.c_str()); - return 1; -} - -LUAAPI(iteminfo_getType) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushstring(L, (*info)->type.c_str()); - return 1; -} - -LUAAPI(iteminfo_getId) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushinteger(L, (*info)->id); - return 1; -} - -LUAAPI(iteminfo_getCount) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushinteger(L, (*info)->count); - return 1; -} - -LUAAPI(iteminfo_getAux) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushinteger(L, (*info)->aux); - return 1; -} - -LUAAPI(iteminfo_getDamage) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushinteger(L, (*info)->damage); - return 1; -} - -LUAAPI(iteminfo_getAttackDamage) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushinteger(L, (*info)->attackDamage); - return 1; -} - -LUAAPI(iteminfo_getMaxDamage) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushinteger(L, (*info)->maxDamage); - return 1; -} - -LUAAPI(iteminfo_getMaxStackSize) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushinteger(L, (*info)->maxStackSize); - return 1; -} - -LUAAPI(iteminfo_getLore) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - int idx = 1; - lua_newtable(L); - for (const auto& item : (*info)->lore) { - lua_pushstring(L, item.c_str()); - lua_seti(L, -2, idx); - ++idx; - } - return 1; -} - -LUAAPI(iteminfo_isArmorItem) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isArmorItem); - return 1; -} - -LUAAPI(iteminfo_isBlock) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isBlock); - return 1; -} - -LUAAPI(iteminfo_isDamageableItem) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isDamageableItem); - return 1; -} - -LUAAPI(iteminfo_isDamaged) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isDamaged); - return 1; -} - -LUAAPI(iteminfo_isEnchanted) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isEnchanted); - return 1; -} - -LUAAPI(iteminfo_isEnchantingBook) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isEnchantingBook); - return 1; -} - -LUAAPI(iteminfo_isFireResistant) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isFireResistant); - return 1; -} - -LUAAPI(iteminfo_isFullStack) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isFullStack); - return 1; -} - -LUAAPI(iteminfo_isGlint) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isGlint); - return 1; -} - -LUAAPI(iteminfo_isHorseArmorItem) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isHorseArmorItem); - return 1; -} - -LUAAPI(iteminfo_isLiquidClipItem) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isLiquidClipItem); - return 1; -} - -LUAAPI(iteminfo_isMusicDiscItem) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isMusicDiscItem); - return 1; -} - -LUAAPI(iteminfo_isOffhandItem) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isOffhandItem); - return 1; -} - -LUAAPI(iteminfo_isPotionItem) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isPotionItem); - return 1; -} - -LUAAPI(iteminfo_isStackable) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isStackable); - return 1; -} - -LUAAPI(iteminfo_isWearableItem) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, (*info)->isWearableItem); - return 1; -} - -LUAAPI(iteminfo_getNbtTable) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - compoundTagToLuaTable(L, *((*info)->tag)); - return 1; -} - -LUAAPI(iteminfo_getSnbt) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - lua_pushstring(L, (*info)->tag->toSnbt(SnbtFormat::Minimize).c_str()); - return 1; -} - -LUAAPI(iteminfo_getSnbtWithPath) { - LUA_ARG_COUNT_CHECK_M(1) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - std::string path = luaL_checkstring(L, 2); - lua_settop(L, 0); - const auto& rst = utils::getNbtFromTag(*((*info)->tag), path); - lua_pushstring(L, rst.first.c_str()); - lua_pushboolean(L, rst.second); - return 2; -} - -LUAAPI(iteminfo_meta_eq) { - LUA_ARG_COUNT_CHECK_M(1) - ItemInfo** info1 = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info1 != nullptr) && ((*info1) != nullptr), 1, "invalid userdata"); - ItemInfo** info2 = (ItemInfo**)luaL_checkudata(L, 2, "iteminfo_mt"); - luaL_argcheck(L, (info2 != nullptr) && ((*info2) != nullptr), 2, "invalid userdata"); - lua_settop(L, 0); - lua_pushboolean(L, ((**info1) == (**info2))); - return 1; -} - -LUAAPI(iteminfo_meta_gc) { - LUA_ARG_COUNT_CHECK_M(0) - ItemInfo** info = (ItemInfo**)luaL_checkudata(L, 1, "iteminfo_mt"); - luaL_argcheck(L, (info != nullptr) && ((*info) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - delete *info; - return 0; -} - -static const luaL_Reg lua_reg_iteminfo_m[] = { - {"getName", lua_api_iteminfo_getName }, - {"getType", lua_api_iteminfo_getType }, - {"getId", lua_api_iteminfo_getId }, - {"getCount", lua_api_iteminfo_getCount }, - {"getAux", lua_api_iteminfo_getAux }, - {"getDamage", lua_api_iteminfo_getDamage }, - {"getAttackDamage", lua_api_iteminfo_getAttackDamage }, - {"getMaxDamage", lua_api_iteminfo_getMaxDamage }, - {"getMaxStackSize", lua_api_iteminfo_getMaxStackSize }, - {"getLore", lua_api_iteminfo_getLore }, - {"isArmorItem", lua_api_iteminfo_isArmorItem }, - {"isBlock", lua_api_iteminfo_isBlock }, - {"isDamageableItem", lua_api_iteminfo_isDamageableItem}, - {"isDamaged", lua_api_iteminfo_isDamaged }, - {"isEnchanted", lua_api_iteminfo_isEnchanted }, - {"isEnchantingBook", lua_api_iteminfo_isEnchantingBook}, - {"isFireResistant", lua_api_iteminfo_isFireResistant }, - {"isFullStack", lua_api_iteminfo_isFullStack }, - {"isGlint", lua_api_iteminfo_isGlint }, - {"isHorseArmorItem", lua_api_iteminfo_isHorseArmorItem}, - {"isLiquidClipItem", lua_api_iteminfo_isLiquidClipItem}, - {"isMusicDiscItem", lua_api_iteminfo_isMusicDiscItem }, - {"isOffhandItem", lua_api_iteminfo_isOffhandItem }, - {"isPotionItem", lua_api_iteminfo_isPotionItem }, - {"isStackable", lua_api_iteminfo_isStackable }, - {"isWearableItem", lua_api_iteminfo_isWearableItem }, - {"getNbtTable", lua_api_iteminfo_getNbtTable }, - {"getSnbt", lua_api_iteminfo_getSnbt }, - {"getSnbtWithPath", lua_api_iteminfo_getSnbtWithPath }, - {"__eq", lua_api_iteminfo_meta_eq }, - {"__gc", lua_api_iteminfo_meta_gc }, - {NULL, NULL } -}; - -LUAAPI(open_iteminfo) { - luaL_newmetatable(L, "iteminfo_mt"); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - luaL_setfuncs(L, lua_reg_iteminfo_m, 0); - luaL_newlib(L, lua_reg_null_c); - return 1; -} - -// userdata iteminfo end - -// userdata simplayer begin - -LUAAPI(simplayer_getName) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushstring(L, (*spinfo)->getName().c_str()); - return 1; -} - -LUAAPI(simplayer_getXuid) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushstring(L, (*spinfo)->getXuid().c_str()); - return 1; -} - -LUAAPI(simplayer_getStatus) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushinteger(L, (*spinfo)->getStatus()); - return 1; -} - -LUAAPI(simplayer_getPos) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = (*spinfo)->getPos(); - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(simplayer_getFeetPos) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); - *pos = (*spinfo)->getFeetPos(); - luaL_setmetatable(L, "vec3_mt"); - return 1; -} - -LUAAPI(simplayer_getStandingOn) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - BlockPos* pos = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); - *pos = (*spinfo)->getStandingOn(); - luaL_setmetatable(L, "blockpos_mt"); - return 1; -} - -LUAAPI(simplayer_getRot) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - Vec2* pos = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); - *pos = (*spinfo)->getRot(); - luaL_setmetatable(L, "vec2_mt"); - return 1; -} - -LUAAPI(simplayer_getHealth) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushinteger(L, (*spinfo)->getHealth()); - return 1; -} - -LUAAPI(simplayer_getHunger) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushnumber(L, (*spinfo)->getHunger()); - return 1; -} - -LUAAPI(simplayer_sneaking) { - LUA_ARG_COUNT_CHECK_M(1) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - luaL_argcheck( - L, - lua_isboolean(L, 2), - 2, - std::string{"boolean expected, got " + std::string{lua_typename(L, lua_type(L, 2))}}.c_str() - ); - lua_pushboolean(L, (*spinfo)->sneaking(lua_toboolean(L, 2))); - return 1; -} - -LUAAPI(simplayer_swimming) { - LUA_ARG_COUNT_CHECK_M(1) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - luaL_argcheck( - L, - lua_isboolean(L, 2), - 2, - std::string{"boolean expected, got " + std::string{lua_typename(L, lua_type(L, 2))}}.c_str() - ); - (*spinfo)->swimming(lua_toboolean(L, 2)); - return 0; -} - -LUAAPI(simplayer_attack) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushboolean(L, (*spinfo)->attack()); - return 1; -} - -LUAAPI(simplayer_chat) { - LUA_ARG_COUNT_CHECK_M(1) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - std::string msg = luaL_checkstring(L, 2); - lua_settop(L, 0); - (*spinfo)->chat(msg); - return 0; -} - -LUAAPI(simplayer_destroy) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushboolean(L, (*spinfo)->destroy()); - return 1; -} - -LUAAPI(simplayer_dropSelectedItem) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushboolean(L, (*spinfo)->dropSelectedItem()); - return 1; -} - -LUAAPI(simplayer_dropInv) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushboolean(L, (*spinfo)->dropInv()); - return 1; -} - -LUAAPI(simplayer_runCmd) { - LUA_ARG_COUNT_CHECK_M(1) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - std::string cmd = luaL_checkstring(L, 2); - lua_settop(L, 0); - lua_pushboolean(L, (*spinfo)->runCmd(cmd)); - return 1; -} - -LUAAPI(simplayer_getBlockPosFromView) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - const auto& rst = (*spinfo)->getBlockPosFromView(); - BlockPos* pos = (BlockPos*)lua_newuserdata(L, sizeof(BlockPos)); - *pos = rst.first; - luaL_setmetatable(L, "blockpos_mt"); - lua_pushboolean(L, rst.second); - return 2; -} - -LUAAPI(simplayer_searchInInvWithId) { - int count = lua_gettop(L); - if (count < 2 || count > 3) return luaL_error(L, "1 or 2 args expected (without \"self\")"); - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - int id = static_cast(luaL_checkinteger(L, 2)); - int start = 0; - if (count == 3) start = static_cast(luaL_checkinteger(L, 3)); - lua_settop(L, 0); - lua_pushinteger(L, (*spinfo)->searchInInvWithId(id, start)); - return 1; -} - -LUAAPI(simplayer_searchInInvWithName) { - int count = lua_gettop(L); - if (count < 2 || count > 3) return luaL_error(L, "1 or 2 args expected (without \"self\")"); - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - std::string name = luaL_checkstring(L, 2); - int start = 0; - if (count == 3) start = static_cast(luaL_checkinteger(L, 3)); - lua_settop(L, 0); - lua_pushinteger(L, (*spinfo)->searchInInvWithName(name, start)); - return 1; -} - -LUAAPI(simplayer_selectSlot) { - LUA_ARG_COUNT_CHECK_M(1) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - int slot = static_cast(luaL_checkinteger(L, 2)); - lua_settop(L, 0); - lua_pushboolean(L, (*spinfo)->selectSlot(slot)); - return 1; -} - -LUAAPI(simplayer_select) { - LUA_ARG_COUNT_CHECK_M(1) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - int id = static_cast(luaL_checkinteger(L, 2)); - lua_settop(L, 0); - lua_pushboolean(L, (*spinfo)->select(id)); - return 1; -} - -LUAAPI(simplayer_getItemFromInv) { - LUA_ARG_COUNT_CHECK_M(1) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - int slot = static_cast(luaL_checkinteger(L, 2)); - lua_settop(L, 0); - ItemInfo** info = (ItemInfo**)lua_newuserdata(L, sizeof(ItemInfo*)); - *info = new ItemInfo((*spinfo)->getItemFromInv(slot)); - luaL_setmetatable(L, "iteminfo_mt"); - return 1; -} - -LUAAPI(simplayer_interact) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushboolean(L, (*spinfo)->interact()); - return 1; -} - -LUAAPI(simplayer_jump) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushboolean(L, (*spinfo)->jump()); - return 1; -} - -LUAAPI(simplayer_useItem) { - LUA_ARG_COUNT_CHECK_M(1) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - int delay = static_cast(luaL_checkinteger(L, 2)); - lua_settop(L, 0); - (*spinfo)->useItem(delay); - return 0; -} - -LUAAPI(simplayer_startBuild) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - (*spinfo)->startBuild(); - return 0; -} - -LUAAPI(simplayer_lookAt) { - LUA_ARG_COUNT_CHECK_M(1) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - Vec3* pos = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); - luaL_argcheck(L, pos != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - (*spinfo)->lookAt(*pos); - return 0; -} - -LUAAPI(simplayer_moveTo) { - LUA_ARG_COUNT_CHECK_M(1) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - Vec3* pos = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); - luaL_argcheck(L, pos != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - (*spinfo)->moveTo(*pos); - return 0; -} - -LUAAPI(simplayer_navigateTo) { - LUA_ARG_COUNT_CHECK_M(1) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - Vec3* pos = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); - luaL_argcheck(L, pos != nullptr, 2, "invalid userdata"); - lua_settop(L, 0); - (*spinfo)->navigateTo(*pos); - return 0; -} - -LUAAPI(simplayer_isTaskFree) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - lua_pushboolean(L, (*spinfo)->isTaskFree()); - return 1; -} - -LUAAPI(simplayer_stopAction) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck( - L, - (spinfo != nullptr) && ((*spinfo) != nullptr) && ((*spinfo)->simPlayer != nullptr), - 1, - "invalid userdata" - ); - lua_settop(L, 0); - (*spinfo)->stopAction(); - return 0; -} - -LUAAPI(simplayer_meta_gc) { - LUA_ARG_COUNT_CHECK_M(0) - SimPlayerManager::SimPlayerInfo** spinfo = (SimPlayerManager::SimPlayerInfo**)luaL_checkudata(L, 1, "simplayer_mt"); - luaL_argcheck(L, (spinfo != nullptr) && ((*spinfo) != nullptr), 1, "invalid userdata"); - lua_settop(L, 0); - delete *spinfo; - return 0; -} - -const static luaL_Reg lua_reg_simplayer_m[] = { - {"getName", lua_api_simplayer_getName }, - {"getXuid", lua_api_simplayer_getXuid }, - {"getStatus", lua_api_simplayer_getStatus }, - {"getPos", lua_api_simplayer_getPos }, - {"getFeetPos", lua_api_simplayer_getFeetPos }, - {"getStandingOn", lua_api_simplayer_getStandingOn }, - {"getRot", lua_api_simplayer_getRot }, - {"getHealth", lua_api_simplayer_getHealth }, - {"getHunger", lua_api_simplayer_getHunger }, - {"sneaking", lua_api_simplayer_sneaking }, - {"swimming", lua_api_simplayer_swimming }, - {"attack", lua_api_simplayer_attack }, - {"chat", lua_api_simplayer_chat }, - {"destroy", lua_api_simplayer_destroy }, - {"dropSelectedItem", lua_api_simplayer_dropSelectedItem }, - {"dropInv", lua_api_simplayer_dropInv }, - {"runCmd", lua_api_simplayer_runCmd }, - {"getBlockPosFromView", lua_api_simplayer_getBlockPosFromView}, - {"searchInInvWithId", lua_api_simplayer_searchInInvWithId }, - {"searchInInvWithName", lua_api_simplayer_searchInInvWithName}, - {"selectSlot", lua_api_simplayer_selectSlot }, - {"select", lua_api_simplayer_select }, - {"getItemFromInv", lua_api_simplayer_getItemFromInv }, - {"interact", lua_api_simplayer_interact }, - {"jump", lua_api_simplayer_jump }, - {"useItem", lua_api_simplayer_useItem }, - {"startBuild", lua_api_simplayer_startBuild }, - {"lookAt", lua_api_simplayer_lookAt }, - {"moveTo", lua_api_simplayer_moveTo }, - {"navigateTo", lua_api_simplayer_navigateTo }, - {"isTaskFree", lua_api_simplayer_isTaskFree }, - {"stopAction", lua_api_simplayer_stopAction }, - {"__gc", lua_api_simplayer_meta_gc }, - {NULL, NULL } -}; - -LUAAPI(open_simplayer) { - luaL_newmetatable(L, "simplayer_mt"); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - luaL_setfuncs(L, lua_reg_simplayer_m, 0); - luaL_newlib(L, lua_reg_null_c); - return 1; -} - -// userdata simplayer end - static const luaL_Reg lua_libs[] = { {"vec3", lua_api_open_vec3 }, {"blockpos", lua_api_open_blockpos }, @@ -2122,16 +40,18 @@ static const luaL_Reg lua_libs[] = { {NULL, NULL } }; -} // namespace - inline void broadcastErr(std::filesystem::path const& path, std::string const& name, std::string const& msg) { std::string data = std::format("[CFSP-Lua] ({}@{})\n{}", path.string(), name, msg); TextPacket::createRawMessage(data).sendToClients(); CFSP::getInstance().getSelf().getLogger().error(data); } -std::pair -execLuaScript(std::string const& fileName, int interval, SimPlayerManager::SimPlayerInfo& spinfo) { +std::pair execLuaScript( + std::string const& fileName, + int interval, + std::string const& luaArg, + SimPlayerManager::SimPlayerInfo& spinfo +) { auto path = CFSP::getInstance().getSelf().getDataDir() / "simplayer" / "scripts" / fileName; // new state std::shared_ptr L(luaL_newstate(), [](lua_State* L) { @@ -2190,7 +110,8 @@ execLuaScript(std::string const& fileName, int interval, SimPlayerManager::SimPl // exec Init func int fType = lua_getglobal(L.get(), "Init"); if (fType != LUA_TFUNCTION) return {"\"Init\" is not a function", false}; - ret = lua_pcall(L.get(), 0, 1, 0); + lua_pushstring(L.get(), luaArg.c_str()); + ret = lua_pcall(L.get(), 1, 1, 0); if (ret != LUA_OK) return {lua_tostring(L.get(), -1), false}; // get Init func return if (lua_isboolean(L.get(), -1)) { @@ -2219,7 +140,7 @@ execLuaScript(std::string const& fileName, int interval, SimPlayerManager::SimPl broadcastErr(path, spinfo.name, lua_tostring(L.get(), -1)); return false; } - if (lua_isboolean(L.get(), -1)) return (bool)lua_toboolean(L.get(), -1); + if (lua_isboolean(L.get(), -1)) return static_cast(lua_toboolean(L.get(), -1)); else { broadcastErr(path, spinfo.name, "function \"Tick\" did not return a boolean type value"); return false; diff --git a/src/cfsp/simplayer/luaapi/SpLuaApi.h b/src/cfsp/simplayer/luaapi/SpLuaApi.h index 014f5f4..b17d83e 100644 --- a/src/cfsp/simplayer/luaapi/SpLuaApi.h +++ b/src/cfsp/simplayer/luaapi/SpLuaApi.h @@ -9,7 +9,7 @@ namespace coral_fans::cfsp { namespace sputils::lua_api { std::pair -execLuaScript(std::string const& fileName, int interval, SimPlayerManager::SimPlayerInfo& spinfo); +execLuaScript(std::string const& fileName, int interval, std::string const&, SimPlayerManager::SimPlayerInfo& spinfo); } diff --git a/src/cfsp/simplayer/luaapi/Utils.cpp b/src/cfsp/simplayer/luaapi/Utils.cpp new file mode 100644 index 0000000..f0a1103 --- /dev/null +++ b/src/cfsp/simplayer/luaapi/Utils.cpp @@ -0,0 +1,104 @@ +#include "cfsp/simplayer/luaapi/Utils.h" +#include "cfsp/base/Macros.h" +#include "mc/nbt/ByteArrayTag.h" +#include "mc/nbt/ByteTag.h" +#include "mc/nbt/CompoundTag.h" +#include "mc/nbt/CompoundTagVariant.h" +#include "mc/nbt/FloatTag.h" +#include "mc/nbt/IntArrayTag.h" +#include "mc/nbt/IntTag.h" +#include "mc/nbt/ListTag.h" +#include "mc/nbt/ShortTag.h" +#include "mc/nbt/StringTag.h" +#include "mc/nbt/Tag.h" +#include "mc/world/level/BlockSource.h" +#include "mc/world/level/block/Block.h" +#include +#include + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +const luaL_Reg lua_reg_null_c[1] = { + {NULL, NULL} +}; + +void compoundTagToLuaTable(lua_State* L, CompoundTagVariant tag) { + if (tag.hold(Tag::Compound)) { + lua_newtable(L); + for (const auto& item : tag.get()) { + lua_pushstring(L, item.first.c_str()); + compoundTagToLuaTable(L, item.second); + lua_settable(L, -3); + } + return; + } + if (tag.hold(Tag::ByteArray)) { + int idx = 1; + lua_newtable(L); + for (const auto& item : tag.get()) { + lua_pushinteger(L, item); + lua_seti(L, -2, idx); + ++idx; + } + return; + } + if (tag.hold(Tag::IntArray)) { + int idx = 1; + lua_newtable(L); + for (const auto& item : tag.get()) { + lua_pushinteger(L, item); + lua_seti(L, -2, idx); + ++idx; + } + return; + } + if (tag.hold(Tag::List)) { + int idx = 1; + lua_newtable(L); + for (const auto& item : tag.get()) { + compoundTagToLuaTable(L, item); + lua_seti(L, -2, idx); + ++idx; + } + return; + } + if (tag.hold(Tag::Byte)) { + lua_pushinteger(L, tag.get()); + return; + } + if (tag.hold(Tag::Double)) { + lua_pushnumber(L, tag.get()); + return; + } + if (tag.hold(Tag::Float)) { + lua_pushnumber(L, tag.get()); + return; + } + if (tag.hold(Tag::Int)) { + lua_pushinteger(L, tag.get()); + return; + } + if (tag.hold(Tag::Int64)) { + lua_pushinteger(L, tag.get()); + return; + } + if (tag.hold(Tag::Short)) { + lua_pushinteger(L, tag.get()); + return; + } + if (tag.hold(Tag::String)) { + lua_pushstring(L, tag.get().c_str()); + return; + } +} + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/Utils.h b/src/cfsp/simplayer/luaapi/Utils.h new file mode 100644 index 0000000..385a592 --- /dev/null +++ b/src/cfsp/simplayer/luaapi/Utils.h @@ -0,0 +1,24 @@ +#pragma once + +#include "cfsp/base/Macros.h" +#include "mc/nbt/CompoundTag.h" +#include "mc/nbt/CompoundTagVariant.h" +#include "mc/nbt/ListTag.h" + + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +extern const luaL_Reg lua_reg_null_c[1]; + +void compoundTagToLuaTable(lua_State* L, CompoundTagVariant tag); + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/Vec2.cpp b/src/cfsp/simplayer/luaapi/Vec2.cpp new file mode 100644 index 0000000..4237add --- /dev/null +++ b/src/cfsp/simplayer/luaapi/Vec2.cpp @@ -0,0 +1,193 @@ +#include "mc/math/Vec2.h" +#include "cfsp/base/Macros.h" +#include "cfsp/simplayer/luaapi/Utils.h" +#include + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata vec2 begin + +LUAAPI(vec2_new) { + LUA_ARG_COUNT_CHECK_C(2) + float x = static_cast(luaL_checknumber(L, 1)); + float y = static_cast(luaL_checknumber(L, 2)); + lua_settop(L, 0); + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + rot->x = x; + rot->y = y; + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(vec2_newLowest) { + LUA_ARG_COUNT_CHECK_C(0) + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = Vec2::LOWEST; + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(vec2_newMax) { + LUA_ARG_COUNT_CHECK_C(0) + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = Vec2::MAX; + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(vec2_newMin) { + LUA_ARG_COUNT_CHECK_C(0) + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = Vec2::MIN; + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(vec2_newNegUnitX) { + LUA_ARG_COUNT_CHECK_C(0) + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = Vec2::NEG_UNIT_X; + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(vec2_newNegUnitY) { + LUA_ARG_COUNT_CHECK_C(0) + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = Vec2::NEG_UNIT_Y; + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(vec2_newOne) { + LUA_ARG_COUNT_CHECK_C(0) + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = Vec2::ONE; + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(vec2_newUnitX) { + LUA_ARG_COUNT_CHECK_C(0) + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = Vec2::UNIT_X; + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(vec2_newUnitY) { + LUA_ARG_COUNT_CHECK_C(0) + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = Vec2::UNIT_Y; + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(vec2_newZero) { + LUA_ARG_COUNT_CHECK_C(0) + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = Vec2::ZERO; + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +static const luaL_Reg lua_reg_vec2_c[11] = { + {"new", lua_api_vec2_new }, + {"newLowest", lua_api_vec2_newLowest }, + {"newMax", lua_api_vec2_newMax }, + {"newMin", lua_api_vec2_newMin }, + {"newNegUnitX", lua_api_vec2_newNegUnitX}, + {"newNegUnitY", lua_api_vec2_newNegUnitY}, + {"newOne", lua_api_vec2_newOne }, + {"newUnitX", lua_api_vec2_newUnitX }, + {"newUnitY", lua_api_vec2_newUnitY }, + {"newZero", lua_api_vec2_newZero }, + {NULL, NULL } +}; + +LUAAPI(vec2_get) { + LUA_ARG_COUNT_CHECK_M(0) + Vec2* rot = (Vec2*)luaL_checkudata(L, 1, "vec2_mt"); + luaL_argcheck(L, rot != nullptr, 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushnumber(L, rot->x); + lua_pushnumber(L, rot->y); + return 2; +} + +LUAAPI(vec2_meta_tostring) { + LUA_ARG_COUNT_CHECK_M(0) + Vec2* rot = (Vec2*)luaL_checkudata(L, 1, "vec2_mt"); + luaL_argcheck(L, rot != nullptr, 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushstring(L, rot->toString().c_str()); + return 1; +} + +LUAAPI(vec2_meta_add) { + LUA_ARG_COUNT_CHECK_M(1) + Vec2* rot1 = (Vec2*)luaL_checkudata(L, 1, "vec2_mt"); + luaL_argcheck(L, rot1 != nullptr, 1, "invalid userdata"); + Vec2* rot2 = (Vec2*)luaL_checkudata(L, 2, "vec2_mt"); + luaL_argcheck(L, rot2 != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = (*rot1) + (*rot2); + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(vec2_meta_sub) { + LUA_ARG_COUNT_CHECK_M(1) + Vec2* rot1 = (Vec2*)luaL_checkudata(L, 1, "vec2_mt"); + luaL_argcheck(L, rot1 != nullptr, 1, "invalid userdata"); + Vec2* rot2 = (Vec2*)luaL_checkudata(L, 2, "vec2_mt"); + luaL_argcheck(L, rot2 != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = (*rot1) - (*rot2); + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +LUAAPI(vec2_meta_eq) { + LUA_ARG_COUNT_CHECK_M(1) + Vec2* rot1 = (Vec2*)luaL_checkudata(L, 1, "vec2_mt"); + luaL_argcheck(L, rot1 != nullptr, 1, "invalid userdata"); + Vec2* rot2 = (Vec2*)luaL_checkudata(L, 2, "vec2_mt"); + luaL_argcheck(L, rot2 != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, ((*rot1) == (*rot2))); + return 1; +} + +static const luaL_Reg lua_reg_vec2_m[6] = { + {"get", lua_api_vec2_get }, + {"__tostring", lua_api_vec2_meta_tostring}, + {"__add", lua_api_vec2_meta_add }, + {"__sub", lua_api_vec2_meta_sub }, + {"__eq", lua_api_vec2_meta_eq }, + {NULL, NULL } +}; + +LUAAPI(open_vec2) { + luaL_newmetatable(L, "vec2_mt"); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + luaL_setfuncs(L, lua_reg_vec2_m, 0); + luaL_newlib(L, lua_reg_vec2_c); + return 1; +} + +// userdata vec2 end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/Vec2.h b/src/cfsp/simplayer/luaapi/Vec2.h new file mode 100644 index 0000000..27e1487 --- /dev/null +++ b/src/cfsp/simplayer/luaapi/Vec2.h @@ -0,0 +1,56 @@ +#pragma once + +#include "cfsp/base/Macros.h" + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata vec2 begin + +int lua_api_vec2_new(lua_State*); + +int lua_api_vec2_newLowest(lua_State*); + +int lua_api_vec2_newMax(lua_State*); + +int lua_api_vec2_newMin(lua_State*); + +int lua_api_vec2_newNegUnitX(lua_State*); + +int lua_api_vec2_newNegUnitY(lua_State*); + +int lua_api_vec2_newOne(lua_State*); + +int lua_api_vec2_newUnitX(lua_State*); + +int lua_api_vec2_newUnitY(lua_State*); + +int lua_api_vec2_newZero(lua_State*); + +extern const luaL_Reg lua_reg_vec2_c[11]; + +int lua_api_vec2_get(lua_State*); + +int lua_api_vec2_meta_tostring(lua_State*); + +int lua_api_vec2_meta_add(lua_State*); + +int lua_api_vec2_meta_sub(lua_State*); + +int lua_api_vec2_meta_eq(lua_State*); + +extern const luaL_Reg lua_reg_vec2_m[6]; + +int lua_api_open_vec2(lua_State*); + +// userdata vec2 end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/Vec3.cpp b/src/cfsp/simplayer/luaapi/Vec3.cpp new file mode 100644 index 0000000..7719eea --- /dev/null +++ b/src/cfsp/simplayer/luaapi/Vec3.cpp @@ -0,0 +1,225 @@ +#include "mc/math/Vec3.h" +#include "cfsp/base/Macros.h" +#include "cfsp/simplayer/luaapi/Utils.h" +#include "mc/world/level/BlockPos.h" +#include "mc/world/level/BlockSource.h" +#include + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata vec3 begin + +LUAAPI(vec3_new) { + LUA_ARG_COUNT_CHECK_C(3) + float x = static_cast(luaL_checknumber(L, 1)); + float y = static_cast(luaL_checknumber(L, 2)); + float z = static_cast(luaL_checknumber(L, 3)); + lua_settop(L, 0); + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + pos->x = x; + pos->y = y; + pos->z = z; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newHalf) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::HALF; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newMax) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::MAX; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newMin) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::MIN; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newNegUnitX) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::NEG_UNIT_X; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newNegUnitY) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::NEG_UNIT_Y; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newNegUnitZ) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::NEG_UNIT_Z; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newOne) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::ONE; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newTwo) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::TWO; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newUnitX) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::UNIT_X; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newUnitY) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::UNIT_Y; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newUnitZ) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::UNIT_Z; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_newZero) { + LUA_ARG_COUNT_CHECK_C(0) + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::ZERO; + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +const luaL_Reg lua_reg_vec3_c[14] = { + {"new", lua_api_vec3_new }, + {"newHalf", lua_api_vec3_newHalf }, + {"newMax", lua_api_vec3_newMax }, + {"newMin", lua_api_vec3_newMin }, + {"newNegUnitX", lua_api_vec3_newNegUnitX}, + {"newNegUnitY", lua_api_vec3_newNegUnitY}, + {"newNegUnitZ", lua_api_vec3_newNegUnitZ}, + {"newOne", lua_api_vec3_newOne }, + {"newTwo", lua_api_vec3_newTwo }, + {"newUnitX", lua_api_vec3_newUnitX }, + {"newUnitY", lua_api_vec3_newUnitY }, + {"newUnitZ", lua_api_vec3_newUnitZ }, + {"newZero", lua_api_vec3_newZero }, + {NULL, NULL } +}; + +LUAAPI(vec3_get) { + LUA_ARG_COUNT_CHECK_M(0) + Vec3* pos = (Vec3*)luaL_checkudata(L, 1, "vec3_mt"); + luaL_argcheck(L, pos != nullptr, 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushnumber(L, pos->x); + lua_pushnumber(L, pos->y); + lua_pushnumber(L, pos->z); + return 3; +} + +LUAAPI(vec3_meta_tostring) { + LUA_ARG_COUNT_CHECK_M(0) + Vec3* pos = (Vec3*)luaL_checkudata(L, 1, "vec3_mt"); + luaL_argcheck(L, pos != nullptr, 1, "invalid userdata"); + lua_settop(L, 0); + lua_pushstring(L, pos->toString().c_str()); + return 1; +} + +LUAAPI(vec3_meta_add) { + LUA_ARG_COUNT_CHECK_M(1) + Vec3* pos1 = (Vec3*)luaL_checkudata(L, 1, "vec3_mt"); + luaL_argcheck(L, pos1 != nullptr, 1, "invalid userdata"); + Vec3* pos2 = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); + luaL_argcheck(L, pos2 != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = (*pos1) + (*pos2); + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_meta_sub) { + LUA_ARG_COUNT_CHECK_M(1) + Vec3* pos1 = (Vec3*)luaL_checkudata(L, 1, "vec3_mt"); + luaL_argcheck(L, pos1 != nullptr, 1, "invalid userdata"); + Vec3* pos2 = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); + luaL_argcheck(L, pos2 != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = (*pos1) - (*pos2); + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +LUAAPI(vec3_meta_eq) { + LUA_ARG_COUNT_CHECK_M(1) + Vec3* pos1 = (Vec3*)luaL_checkudata(L, 1, "vec3_mt"); + luaL_argcheck(L, pos1 != nullptr, 1, "invalid userdata"); + Vec3* pos2 = (Vec3*)luaL_checkudata(L, 2, "vec3_mt"); + luaL_argcheck(L, pos2 != nullptr, 2, "invalid userdata"); + lua_settop(L, 0); + lua_pushboolean(L, ((*pos1) == (*pos2))); + return 1; +} + +const luaL_Reg lua_reg_vec3_m[6] = { + {"get", lua_api_vec3_get }, + {"__tostring", lua_api_vec3_meta_tostring}, + {"__add", lua_api_vec3_meta_add }, + {"__sub", lua_api_vec3_meta_sub }, + {"__eq", lua_api_vec3_meta_eq }, + {NULL, NULL } +}; + +LUAAPI(open_vec3) { + luaL_newmetatable(L, "vec3_mt"); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + luaL_setfuncs(L, lua_reg_vec3_m, 0); + luaL_newlib(L, lua_reg_vec3_c); + return 1; +} + +// userdata vec3 end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/src/cfsp/simplayer/luaapi/Vec3.h b/src/cfsp/simplayer/luaapi/Vec3.h new file mode 100644 index 0000000..b395f7a --- /dev/null +++ b/src/cfsp/simplayer/luaapi/Vec3.h @@ -0,0 +1,62 @@ +#pragma once + +#include "cfsp/base/Macros.h" + +extern "C" { +#include "lauxlib.h" +#include "lua.h" +} + +namespace coral_fans::cfsp { + +namespace sputils::lua_api { + +// userdata vec3 begin + +int lua_api_vec3_new(lua_State*); + +int lua_api_vec3_newHalf(lua_State*); + +int lua_api_vec3_newMax(lua_State*); + +int lua_api_vec3_newMin(lua_State*); + +int lua_api_vec3_newNegUnitX(lua_State*); + +int lua_api_vec3_newNegUnitY(lua_State*); + +int lua_api_vec3_newNegUnitZ(lua_State*); + +int lua_api_vec3_newOne(lua_State*); + +int lua_api_vec3_newTwo(lua_State*); + +int lua_api_vec3_newUnitX(lua_State*); + +int lua_api_vec3_newUnitY(lua_State*); + +int lua_api_vec3_newUnitZ(lua_State*); + +int lua_api_vec3_newZero(lua_State*); + +extern const luaL_Reg lua_reg_vec3_c[14]; + +int lua_api_vec3_get(lua_State*); + +int lua_api_vec3_meta_tostring(lua_State*); + +int lua_api_vec3_meta_add(lua_State*); + +int lua_api_vec3_meta_sub(lua_State*); + +int lua_api_vec3_meta_eq(lua_State*); + +extern const luaL_Reg lua_reg_vec3_m[6]; + +int lua_api_open_vec3(lua_State*); + +// userdata vec3 end + +} // namespace sputils::lua_api + +} // namespace coral_fans::cfsp \ No newline at end of file diff --git a/xmake.lua b/xmake.lua index e794859..576b2fc 100644 --- a/xmake.lua +++ b/xmake.lua @@ -30,6 +30,7 @@ target("CFSP") -- Change this to your mod name. "/w45204" ) add_defines("NOMINMAX", "UNICODE", "CFSPEXP") + add_defines("VERSION=\"$(shell git describe --tags --abbrev=0 --always)\"") add_defines("COMMITID=\"$(shell git rev-parse HEAD)\"") add_files("src/**.cpp") add_headerfiles("src/cfsp/simplayer/CFSP.h")