From e36af6f9692993def310cc48ab5c2f65fb0f0267 Mon Sep 17 00:00:00 2001 From: red-001 Date: Wed, 27 Jun 2018 16:45:40 +0100 Subject: [PATCH] Fix mod channels crash (#7481) --- src/script/lua_api/l_modchannels.cpp | 28 ++++++++++------------------ src/script/lua_api/l_modchannels.h | 8 ++++---- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/src/script/lua_api/l_modchannels.cpp b/src/script/lua_api/l_modchannels.cpp index ac28e2ada..0485b276a 100644 --- a/src/script/lua_api/l_modchannels.cpp +++ b/src/script/lua_api/l_modchannels.cpp @@ -33,9 +33,8 @@ int ModApiChannels::l_mod_channel_join(lua_State *L) return 0; getGameDef(L)->joinModChannel(channel); - ModChannel *channelObj = getGameDef(L)->getModChannel(channel); - assert(channelObj); - ModChannelRef::create(L, channelObj); + assert(getGameDef(L)->getModChannel(channel) != nullptr); + ModChannelRef::create(L, channel); int object = lua_gettop(L); lua_pushvalue(L, object); @@ -51,29 +50,22 @@ void ModApiChannels::Initialize(lua_State *L, int top) * ModChannelRef */ -ModChannelRef::ModChannelRef(ModChannel *modchannel) : m_modchannel(modchannel) +ModChannelRef::ModChannelRef(const std::string &modchannel) : + m_modchannel_name(modchannel) { } int ModChannelRef::l_leave(lua_State *L) { ModChannelRef *ref = checkobject(L, 1); - ModChannel *channel = getobject(ref); - if (!channel) - return 0; - - getGameDef(L)->leaveModChannel(channel->getName()); - // Channel left, invalidate the channel object ptr - // This permits to invalidate every object action from Lua because core removed - // channel consuming link - ref->m_modchannel = nullptr; + getGameDef(L)->leaveModChannel(ref->m_modchannel_name); return 0; } int ModChannelRef::l_send_all(lua_State *L) { ModChannelRef *ref = checkobject(L, 1); - ModChannel *channel = getobject(ref); + ModChannel *channel = getobject(L, ref); if (!channel || !channel->canWrite()) return 0; @@ -87,7 +79,7 @@ int ModChannelRef::l_send_all(lua_State *L) int ModChannelRef::l_is_writeable(lua_State *L) { ModChannelRef *ref = checkobject(L, 1); - ModChannel *channel = getobject(ref); + ModChannel *channel = getobject(L, ref); if (!channel) return 0; @@ -119,7 +111,7 @@ void ModChannelRef::Register(lua_State *L) lua_pop(L, 1); // Drop methodtable } -void ModChannelRef::create(lua_State *L, ModChannel *channel) +void ModChannelRef::create(lua_State *L, const std::string &channel) { ModChannelRef *o = new ModChannelRef(channel); *(void **)(lua_newuserdata(L, sizeof(void *))) = o; @@ -145,9 +137,9 @@ ModChannelRef *ModChannelRef::checkobject(lua_State *L, int narg) return *(ModChannelRef **)ud; // unbox pointer } -ModChannel *ModChannelRef::getobject(ModChannelRef *ref) +ModChannel *ModChannelRef::getobject(lua_State *L, ModChannelRef *ref) { - return ref->m_modchannel; + return getGameDef(L)->getModChannel(ref->m_modchannel_name); } // clang-format off diff --git a/src/script/lua_api/l_modchannels.h b/src/script/lua_api/l_modchannels.h index dbbf11a05..9b948002b 100644 --- a/src/script/lua_api/l_modchannels.h +++ b/src/script/lua_api/l_modchannels.h @@ -37,11 +37,11 @@ public: class ModChannelRef : public ModApiBase { public: - ModChannelRef(ModChannel *modchannel); + ModChannelRef(const std::string &modchannel); ~ModChannelRef() = default; static void Register(lua_State *L); - static void create(lua_State *L, ModChannel *channel); + static void create(lua_State *L, const std::string &channel); // leave() static int l_leave(lua_State *L); @@ -57,9 +57,9 @@ private: static int gc_object(lua_State *L); static ModChannelRef *checkobject(lua_State *L, int narg); - static ModChannel *getobject(ModChannelRef *ref); + static ModChannel *getobject(lua_State *L, ModChannelRef *ref); - ModChannel *m_modchannel = nullptr; + std::string m_modchannel_name; static const char className[]; static const luaL_Reg methods[]; -- 2.25.1