Fix mod channels crash (#7481)
authorred-001 <red-001@outlook.ie>
Wed, 27 Jun 2018 15:45:40 +0000 (16:45 +0100)
committerSmallJoker <SmallJoker@users.noreply.github.com>
Wed, 27 Jun 2018 15:45:40 +0000 (17:45 +0200)
src/script/lua_api/l_modchannels.cpp
src/script/lua_api/l_modchannels.h

index ac28e2ada01389d2574c0ff539f76a1169912d79..0485b276a4c0abc70c9c906ddd5e23a2abf7b09e 100644 (file)
@@ -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
index dbbf11a056e3463034a495681fb659963d5c80cd..9b948002b5e8ad21a7837a020a39d5390ff0657d 100644 (file)
@@ -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[];