From 13d766e1e81b229cd07f5e9d44d81ec71c44901c Mon Sep 17 00:00:00 2001 From: odorajbotoj Date: Wed, 16 Oct 2024 04:17:02 +0800 Subject: [PATCH 1/3] fix simplayer lookat --- src/cfsp/simplayer/CFSP.h | 99 ++++++++++++++++++++++++++------ src/cfsp/simplayer/SimPlayer.cpp | 13 +++-- 2 files changed, 89 insertions(+), 23 deletions(-) diff --git a/src/cfsp/simplayer/CFSP.h b/src/cfsp/simplayer/CFSP.h index 9e97a50..79e29c0 100644 --- a/src/cfsp/simplayer/CFSP.h +++ b/src/cfsp/simplayer/CFSP.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -92,16 +93,36 @@ class SimPlayerManager { 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) { + CFSP_API Vec3 getPos() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + return simPlayer->getPosition(); + } + CFSP_API Vec3 getFeetPos() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + return simPlayer->getFeetPos(); + } + CFSP_API BlockPos getStandingOn() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + return simPlayer->getBlockPosCurrentlyStandingOn(simPlayer); + } + CFSP_API Vec2 getRot() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + return simPlayer->getRotation(); + } + CFSP_API int getHealth() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + return simPlayer->getHealth(); + } + CFSP_API float getHunger() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + return simPlayer->getAttribute(SimulatedPlayer::HUNGER).getCurrentValue(); + } + CFSP_API bool sneaking(bool enable) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); return enable ? simPlayer->simulateSneaking() : simPlayer->simulateStopSneaking(); } CFSP_API void swimming(bool enable) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); if (enable) { simPlayer->startSwimming(); taskid = scheduler->add(1, [sp = this->simPlayer](unsigned long long) { @@ -117,12 +138,17 @@ class SimPlayerManager { } } CFSP_API bool attack() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); const auto& hit = simPlayer->traceRay(5.25f, true, false); if (hit) return simPlayer->simulateAttack(hit.getEntity()); else return false; } - CFSP_API inline void chat(std::string const& msg) { simPlayer->simulateChat(msg); } - CFSP_API bool destroy() { + CFSP_API void chat(std::string const& msg) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + simPlayer->simulateChat(msg); + } + CFSP_API bool destroy() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); const auto& hit = simPlayer->traceRay(5.25f, false, true); if (hit) return simPlayer->simulateDestroyBlock( @@ -131,8 +157,12 @@ class SimPlayerManager { ); else return false; } - CFSP_API inline bool dropSelectedItem() { return simPlayer->simulateDropSelectedItem(); } - CFSP_API bool dropInv() { + CFSP_API bool dropSelectedItem() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + return simPlayer->simulateDropSelectedItem(); + } + CFSP_API bool dropInv() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); bool rst = true; if (simPlayer->getSelectedItem() != ItemStack::EMPTY_ITEM) rst &= simPlayer->simulateDropSelectedItem(); int sel = simPlayer->getSelectedItemSlot(); @@ -146,6 +176,8 @@ class SimPlayerManager { return rst; } CFSP_API void swap(Player* player) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + if (!player) throw std::invalid_argument("Player is null"); // get data auto& spInv = simPlayer->getInventory(); auto& spArmor = ActorEquipment::getArmorContainer(simPlayer->getEntityContext()); @@ -185,6 +217,7 @@ class SimPlayerManager { player->refreshInventory(); } CFSP_API bool runCmd(std::string const& cmd) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); CommandContext ctx(cmd, std::make_unique(PlayerCommandOrigin(*simPlayer))); auto mc = ll::service::getMinecraft(); if (mc) { @@ -194,10 +227,12 @@ class SimPlayerManager { return false; } CFSP_API std::pair getBlockPosFromView() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); const auto& hit = simPlayer->traceRay(5.25f, false, true); return {hit.mBlockPos, hit.mType == HitResultType::Tile}; } CFSP_API int searchInInvWithId(int id, int start = 0) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); auto& inv = simPlayer->getInventory(); int size = inv.getContainerSize(); for (int i = start; i < size; ++i) @@ -205,6 +240,7 @@ class SimPlayerManager { return -1; } CFSP_API int searchInInvWithName(std::string const& itemName, int start = 0) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); auto& inv = simPlayer->getInventory(); int size = inv.getContainerSize(); for (int i = start; i < size; ++i) @@ -212,12 +248,14 @@ class SimPlayerManager { return -1; } CFSP_API bool selectSlot(int slot) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); if (slot < 0 || slot >= simPlayer->getInventory().getContainerSize()) return false; int sel = simPlayer->getSelectedItemSlot(); utils::swapItemInContainer(simPlayer, sel, slot); return true; } CFSP_API bool select(int id) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); int sel = simPlayer->getSelectedItemSlot(); int target = searchInInvWithId(id); if (target == sel) target = searchInInvWithId(id, sel + 1); @@ -226,22 +264,42 @@ class SimPlayerManager { return true; } CFSP_API const ItemStack& getItemFromInv(int slot) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); auto& inv = simPlayer->getInventory(); return inv.getItem(slot); } - CFSP_API inline bool interact() { return simPlayer->simulateInteract(); } - CFSP_API inline bool jump() { return simPlayer->simulateJump(); } - CFSP_API void useItem(int delay) { + CFSP_API bool interact() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + return simPlayer->simulateInteract(); + } + CFSP_API bool jump() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + return simPlayer->simulateJump(); + } + CFSP_API void useItem(int delay) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); simPlayer->simulateUseItemInSlot(simPlayer->getSelectedItemSlot()); taskid = scheduler->add(delay, [sp = this->simPlayer](unsigned long long) { if (sp) sp->simulateStopUsingItem(); return false; }); } - 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 void startBuild() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + simPlayer->simulateStartBuildInSlot(simPlayer->getSelectedItemSlot()); + } + CFSP_API void lookAt(Vec3 const& pos) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + simPlayer->simulateLookAt(pos, ::sim::LookDuration{2}); + } + CFSP_API void moveTo(Vec3 const& pos) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + simPlayer->simulateMoveToLocation(pos, 4.3f, true); + } + CFSP_API void navigateTo(Vec3 const& pos) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); + 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() { @@ -260,6 +318,7 @@ class SimPlayerManager { } CFSP_API inline bool isFree() { return isTaskFree() && isScriptFree(); } CFSP_API void stopAction() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); simPlayer->simulateStopBuild(); simPlayer->simulateStopDestroyingBlock(); simPlayer->simulateStopFlying(); @@ -275,6 +334,7 @@ class SimPlayerManager { scriptid = 0; } CFSP_API int getFirstEmptySlot() { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); auto& inv = simPlayer->getInventory(); int size = inv.getContainerSize(); for (int i = 0; i < size; ++i) @@ -292,6 +352,7 @@ class SimPlayerManager { NoItem = 7 }; CFSP_API ContainerOperationErrCode trySwapSlotWithContainer(int invSlot, int targetSlot) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); using errc = ContainerOperationErrCode; const auto& hit = simPlayer->traceRay(5.25f, false, true); if (!hit) return errc::NoHit; @@ -316,6 +377,7 @@ class SimPlayerManager { return errc::Success; } CFSP_API ContainerOperationErrCode tryPutIntoContainer(int invSlot) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); using errc = ContainerOperationErrCode; const auto& hit = simPlayer->traceRay(5.25f, false, true); if (!hit) return errc::NoHit; @@ -344,6 +406,7 @@ class SimPlayerManager { return errc::NoEnoughSpace; } CFSP_API ContainerOperationErrCode tryGetFromContainerWithName(std::string const& typeName) { + if (!simPlayer) throw std::invalid_argument("SimPlayer is null"); using errc = ContainerOperationErrCode; const auto& hit = simPlayer->traceRay(5.25f, false, true); if (!hit) return errc::NoHit; diff --git a/src/cfsp/simplayer/SimPlayer.cpp b/src/cfsp/simplayer/SimPlayer.cpp index 200dbb6..87bee45 100644 --- a/src/cfsp/simplayer/SimPlayer.cpp +++ b/src/cfsp/simplayer/SimPlayer.cpp @@ -374,9 +374,11 @@ SimPlayerManager::spawnSimPlayer(Player* player, std::string const& name, Vec3 c auto serverNetworkHandler = mc->getServerNetworkHandler(); if (!serverNetworkHandler) return {"translate.simplayer.error.cannotcreate"_tr(), false}; if (rejoin) { + Vec3 offlinePos{spIt->second->offlinePosX, spIt->second->offlinePosY, spIt->second->offlinePosZ}; + Vec2 offlineRot{spIt->second->offlineRotX, spIt->second->offlineRotY}; auto* simPlayer = SimulatedPlayer::create( spname, - {spIt->second->offlinePosX, spIt->second->offlinePosY, spIt->second->offlinePosZ}, + offlinePos, spIt->second->offlineDim, serverNetworkHandler, spIt->second->xuid @@ -385,10 +387,10 @@ SimPlayerManager::spawnSimPlayer(Player* player, std::string const& name, Vec3 c simPlayer->setPlayerGameType( magic_enum::enum_cast(spIt->second->offlineGameType).value_or(GameType::WorldDefault) ); - simPlayer->teleport( - {spIt->second->offlinePosX, spIt->second->offlinePosY, spIt->second->offlinePosZ}, - spIt->second->offlineDim, - {spIt->second->offlineRotX, spIt->second->offlineRotY} + simPlayer->teleport(offlinePos, spIt->second->offlineDim, offlineRot); + simPlayer->simulateLookAt( + simPlayer->getPosition() + Vec3::directionFromRotation(offlineRot), + ::sim::LookDuration{2} ); spIt->second->status = SimPlayerStatus::Alive; spIt->second->simPlayer = simPlayer; @@ -409,6 +411,7 @@ SimPlayerManager::spawnSimPlayer(Player* player, std::string const& name, Vec3 c if (!simPlayer) return {"translate.simplayer.error.cannotcreate"_tr(), false}; simPlayer->setPlayerGameType(player->getPlayerGameType()); simPlayer->teleport(pos, player->getDimensionId(), rot); + simPlayer->simulateLookAt(simPlayer->getPosition() + Vec3::directionFromRotation(rot), ::sim::LookDuration{2}); // add to map this->mNameSimPlayerMap[spname] = boost::shared_ptr(new SimPlayerInfo{ spname, From 0af013647678f6d08e74688a9472dc9a1584bfb1 Mon Sep 17 00:00:00 2001 From: odorajbotoj Date: Wed, 16 Oct 2024 04:29:31 +0800 Subject: [PATCH 2/3] new lua api vec3.newFromRotation and vec2.newFromDirection --- src/cfsp/simplayer/luaapi/Vec2.cpp | 38 ++++++++++++++++++--------- src/cfsp/simplayer/luaapi/Vec2.h | 4 ++- src/cfsp/simplayer/luaapi/Vec3.cpp | 42 +++++++++++++++++++----------- src/cfsp/simplayer/luaapi/Vec3.h | 4 ++- 4 files changed, 58 insertions(+), 30 deletions(-) diff --git a/src/cfsp/simplayer/luaapi/Vec2.cpp b/src/cfsp/simplayer/luaapi/Vec2.cpp index 4237add..59a12cd 100644 --- a/src/cfsp/simplayer/luaapi/Vec2.cpp +++ b/src/cfsp/simplayer/luaapi/Vec2.cpp @@ -1,6 +1,6 @@ #include "mc/math/Vec2.h" #include "cfsp/base/Macros.h" -#include "cfsp/simplayer/luaapi/Utils.h" +#include "mc/math/Vec3.h" #include extern "C" { @@ -98,18 +98,30 @@ LUAAPI(vec2_newZero) { 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_newFromDirection) { + LUA_ARG_COUNT_CHECK_C(1) + Vec3* pos = (Vec3*)luaL_checkudata(L, 1, "vec3_mt"); + luaL_argcheck(L, pos != nullptr, 1, "invalid userdata"); + lua_settop(L, 0); + Vec2* rot = (Vec2*)lua_newuserdata(L, sizeof(Vec2)); + *rot = Vec3::rotationFromDirection(*pos); + luaL_setmetatable(L, "vec2_mt"); + return 1; +} + +static const luaL_Reg lua_reg_vec2_c[12] = { + {"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 }, + {"newFromDirection", lua_api_vec2_newFromDirection}, + {NULL, NULL } }; LUAAPI(vec2_get) { diff --git a/src/cfsp/simplayer/luaapi/Vec2.h b/src/cfsp/simplayer/luaapi/Vec2.h index a33e8df..129232d 100644 --- a/src/cfsp/simplayer/luaapi/Vec2.h +++ b/src/cfsp/simplayer/luaapi/Vec2.h @@ -31,7 +31,9 @@ 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_newFromDirection(lua_State*); + +extern const luaL_Reg lua_reg_vec2_c[12]; int lua_api_vec2_get(lua_State*); diff --git a/src/cfsp/simplayer/luaapi/Vec3.cpp b/src/cfsp/simplayer/luaapi/Vec3.cpp index 7719eea..59f6d3b 100644 --- a/src/cfsp/simplayer/luaapi/Vec3.cpp +++ b/src/cfsp/simplayer/luaapi/Vec3.cpp @@ -126,21 +126,33 @@ LUAAPI(vec3_newZero) { 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_newFromRotation) { + LUA_ARG_COUNT_CHECK_C(1) + Vec2* rot = (Vec2*)luaL_checkudata(L, 1, "vec2_mt"); + luaL_argcheck(L, rot != nullptr, 1, "invalid userdata"); + lua_settop(L, 0); + Vec3* pos = (Vec3*)lua_newuserdata(L, sizeof(Vec3)); + *pos = Vec3::directionFromRotation(*rot); + luaL_setmetatable(L, "vec3_mt"); + return 1; +} + +const luaL_Reg lua_reg_vec3_c[15] = { + {"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 }, + {"newFromRotation", lua_api_vec3_newFromRotation}, + {NULL, NULL } }; LUAAPI(vec3_get) { diff --git a/src/cfsp/simplayer/luaapi/Vec3.h b/src/cfsp/simplayer/luaapi/Vec3.h index 07dd45b..a23f62a 100644 --- a/src/cfsp/simplayer/luaapi/Vec3.h +++ b/src/cfsp/simplayer/luaapi/Vec3.h @@ -37,7 +37,9 @@ 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_newFromRotation(lua_State*); + +extern const luaL_Reg lua_reg_vec3_c[15]; int lua_api_vec3_get(lua_State*); From 4c05ed2b2cbe542237942c1d2f8911e404c9c6fd Mon Sep 17 00:00:00 2001 From: odorajbotoj Date: Wed, 16 Oct 2024 04:38:49 +0800 Subject: [PATCH 3/3] remove useless header and ready to release 2.2.0 --- CHANGELOG.md | 17 +++++++++++++++++ src/cfsp/simplayer/luaapi/Vec3.cpp | 1 - tooth.json | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f30acf3..56ac001 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.2.0] - 2024-10-16 + +### Added + ++ Added lua api `vec3.newFromRotation` ++ Added lua api `vec2.newFromDirection` + +### Fixed + ++ Fixed simplayer lookat ++ Fixed rotation set when spawn simplayer + +### Changed + ++ SimPlayerInfo api now will throw error when ptr simPlayer is null + ## [2.1.2] - 2024-10-14 We skipped `v2.1.0` and `v2.1.1`. They have some serious bugs. @@ -39,6 +55,7 @@ We skipped `v2.1.0` and `v2.1.1`. They have some serious bugs. + Move CoralFans SimulatedPlayer System from [CoralFans](https://github.com/CoralFans-Dev/CoralFans) to here + Added Script Arg +[2.2.0]: https://github.com/CoralFans-Dev/CFSP/compare/v2.1.2...v2.2.0 [2.1.2]: https://github.com/CoralFans-Dev/CFSP/compare/v2.0.0...v2.1.2 [2.0.0]: https://github.com/CoralFans-Dev/CFSP/compare/v1.0.0...v2.0.0 [1.0.0]: https://github.com/CoralFans-Dev/CFSP/releases/tag/v1.0.0 diff --git a/src/cfsp/simplayer/luaapi/Vec3.cpp b/src/cfsp/simplayer/luaapi/Vec3.cpp index 59f6d3b..5eb0478 100644 --- a/src/cfsp/simplayer/luaapi/Vec3.cpp +++ b/src/cfsp/simplayer/luaapi/Vec3.cpp @@ -1,6 +1,5 @@ #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 diff --git a/tooth.json b/tooth.json index 046581e..0a68283 100644 --- a/tooth.json +++ b/tooth.json @@ -1,7 +1,7 @@ { "format_version": 2, "tooth": "github.com/CoralFans-Dev/CFSP", - "version": "2.1.2", + "version": "2.2.0", "info": { "name": "CFSP", "description": "CoralFans SimulatedPlayer",