From cb85f7b7c9a7e3191ac3c2f2ac504d38fc10aa8c Mon Sep 17 00:00:00 2001 From: CPunch Date: Sat, 17 Apr 2021 02:55:11 -0500 Subject: [PATCH] Added Player.onChat event & Player:kick() --- scripts/test.lua | 7 ++++ src/Chat.cpp | 4 +++ src/Player.hpp | 10 ++++++ src/lua/PlayerWrapper.cpp | 71 +++++++++++++++++++++++++++++++-------- 4 files changed, 78 insertions(+), 14 deletions(-) diff --git a/scripts/test.lua b/scripts/test.lua index 607fc2d..edfd67e 100644 --- a/scripts/test.lua +++ b/scripts/test.lua @@ -2,6 +2,13 @@ print("Hello world!") World.onPlayerAdded:listen(function(plr) print(plr.type .. " " .. plr.name .. " joined from LUA!!") + plr.onChat:listen(function(msg) + print(plr.name .. " said : " .. msg) + + if msg == "kickme" then + plr:kick() + end + end) end) wait(2) diff --git a/src/Chat.cpp b/src/Chat.cpp index 61b9803..585daf0 100644 --- a/src/Chat.cpp +++ b/src/Chat.cpp @@ -19,6 +19,10 @@ static void chatHandler(CNSocket* sock, CNPacketData* data) { return; } + // if the player has an onChat Lua event registered, call it + if (plr->onChat != nullptr) + plr->onChat->call(fullChat.c_str()); + if (plr->iSpecialState & CN_SPECIAL_STATE_FLAG__MUTE_FREECHAT) return; diff --git a/src/Player.hpp b/src/Player.hpp index c486012..c6d27d4 100644 --- a/src/Player.hpp +++ b/src/Player.hpp @@ -7,6 +7,8 @@ #include "Chunking.hpp" #include "Entities.hpp" +#include "lua/LuaWrapper.hpp" + #define ACTIVE_MISSION_COUNT 6 #define PC_MAXHEALTH(level) (925 + 75 * (level)) @@ -87,7 +89,15 @@ struct Player : public Entity { time_t lastShot = 0; std::vector buyback = {}; + // lua events + lEvent *onChat = nullptr; + Player() { type = EntityType::PLAYER; } + ~Player() { + // if an event was registered, free it + if (onChat != nullptr) + delete onChat; + } virtual void enterIntoViewOf(CNSocket *sock) override; virtual void disappearFromViewOf(CNSocket *sock) override; diff --git a/src/lua/PlayerWrapper.cpp b/src/lua/PlayerWrapper.cpp index 3c55c91..72e3f02 100644 --- a/src/lua/PlayerWrapper.cpp +++ b/src/lua/PlayerWrapper.cpp @@ -1,4 +1,5 @@ #include "lua/EntityWrapper.hpp" +#include "lua/EventWrapper.hpp" #include "lua/PlayerWrapper.hpp" #include "core/CNProtocol.hpp" @@ -11,7 +12,7 @@ #define SETTERTBL "__plrSETTERS" #define METHODTBL "__plrMETHODS" -static Player* grabPlayer(lua_State *state, int indx) { +static EntityRef* grabEntityRef(lua_State *state, int indx) { // first, make sure its a userdata luaL_checktype(state, indx, LUA_TUSERDATA); @@ -28,25 +29,23 @@ static Player* grabPlayer(lua_State *state, int indx) { return NULL; } + return ref; +} + +static Player* grabPlayer(lua_State *state, int indx) { + EntityRef *ref = grabEntityRef(state, indx); + + if (ref == NULL) + return NULL; + return (Player*)ref->getEntity(); } static CNSocket* grabSock(lua_State *state, int indx) { - // first, make sure its a userdata - luaL_checktype(state, indx, LUA_TUSERDATA); + EntityRef *ref = grabEntityRef(state, indx); - // now, check and make sure its our library's metatable attached to this userdata - EntityRef *ref = (EntityRef*)luaL_checkudata(state, indx, LIBNAME); - if (ref == NULL) { - luaL_typerror(state, indx, LIBNAME); + if (ref == NULL) return NULL; - } - - // check if the player exists still & return NULL if it doesn't - if (!ref->isValid()) { - luaL_argerror(state, indx, PLRGONESTR); - return NULL; - } return ref->sock; } @@ -63,8 +62,24 @@ static int plr_getName(lua_State *state) { return 1; } +static int plr_getChatted(lua_State *state) { + Player *plr = grabPlayer(state, 1); + + if (plr == NULL) + return 0; + + // the Player* entity doesn't actually have an lEvent setup until a lua script asks for it, so + // if Player->onChat is nullptr, create the lEvent and then push it :D + if (plr->onChat == nullptr) + plr->onChat = new lEvent(); + + LuaManager::Event::push(state, plr->onChat); + return 1; +} + static const luaL_Reg plr_getters[] = { {"name", plr_getName}, + {"onChat", plr_getChatted}, {0, 0} }; @@ -76,7 +91,35 @@ static const luaL_Reg plr_setters[] = { // =============================================== [[ METHODS ]] =============================================== +static int plr_kick(lua_State *state) { + EntityRef *ref = grabEntityRef(state, 1); + Player *plr; + CNSocket *sock; + + // sanity check + if (ref == NULL) + return 0; + + plr = (Player*)ref->getEntity(); + sock = ref->sock; + + // construct packet + INITSTRUCT(sP_FE2CL_REP_PC_EXIT_SUCC, response); + + response.iID = plr->iID; + response.iExitCode = 3; // "a GM has terminated your connection" + + // send to target player + sock->sendPacket(response, P_FE2CL_REP_PC_EXIT_SUCC); + + // ensure that the connection has terminated + sock->kill(); + + return 0; +} + static const luaL_Reg plr_methods[] = { + {"kick", plr_kick}, {0, 0} };