Skip to content

Commit

Permalink
Fix mod channels crash (#7481)
Browse files Browse the repository at this point in the history
  • Loading branch information
red-001 authored and SmallJoker committed Jun 27, 2018
1 parent a43a4e2 commit e36af6f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 22 deletions.
28 changes: 10 additions & 18 deletions src/script/lua_api/l_modchannels.cpp
Expand Up @@ -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);
Expand All @@ -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;

Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down
8 changes: 4 additions & 4 deletions src/script/lua_api/l_modchannels.h
Expand Up @@ -37,11 +37,11 @@ class ModApiChannels : public ModApiBase
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);
Expand All @@ -57,9 +57,9 @@ class ModChannelRef : public ModApiBase
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[];
Expand Down

0 comments on commit e36af6f

Please sign in to comment.