mirror of
https://github.com/minetest/minetest.git
synced 2024-12-24 23:22:24 +01:00
Fix mod channels crash (#7481)
This commit is contained in:
parent
a43a4e2d97
commit
e36af6f969
@ -33,9 +33,8 @@ int ModApiChannels::l_mod_channel_join(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
getGameDef(L)->joinModChannel(channel);
|
getGameDef(L)->joinModChannel(channel);
|
||||||
ModChannel *channelObj = getGameDef(L)->getModChannel(channel);
|
assert(getGameDef(L)->getModChannel(channel) != nullptr);
|
||||||
assert(channelObj);
|
ModChannelRef::create(L, channel);
|
||||||
ModChannelRef::create(L, channelObj);
|
|
||||||
|
|
||||||
int object = lua_gettop(L);
|
int object = lua_gettop(L);
|
||||||
lua_pushvalue(L, object);
|
lua_pushvalue(L, object);
|
||||||
@ -51,29 +50,22 @@ void ModApiChannels::Initialize(lua_State *L, int top)
|
|||||||
* ModChannelRef
|
* 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)
|
int ModChannelRef::l_leave(lua_State *L)
|
||||||
{
|
{
|
||||||
ModChannelRef *ref = checkobject(L, 1);
|
ModChannelRef *ref = checkobject(L, 1);
|
||||||
ModChannel *channel = getobject(ref);
|
getGameDef(L)->leaveModChannel(ref->m_modchannel_name);
|
||||||
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;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModChannelRef::l_send_all(lua_State *L)
|
int ModChannelRef::l_send_all(lua_State *L)
|
||||||
{
|
{
|
||||||
ModChannelRef *ref = checkobject(L, 1);
|
ModChannelRef *ref = checkobject(L, 1);
|
||||||
ModChannel *channel = getobject(ref);
|
ModChannel *channel = getobject(L, ref);
|
||||||
if (!channel || !channel->canWrite())
|
if (!channel || !channel->canWrite())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -87,7 +79,7 @@ int ModChannelRef::l_send_all(lua_State *L)
|
|||||||
int ModChannelRef::l_is_writeable(lua_State *L)
|
int ModChannelRef::l_is_writeable(lua_State *L)
|
||||||
{
|
{
|
||||||
ModChannelRef *ref = checkobject(L, 1);
|
ModChannelRef *ref = checkobject(L, 1);
|
||||||
ModChannel *channel = getobject(ref);
|
ModChannel *channel = getobject(L, ref);
|
||||||
if (!channel)
|
if (!channel)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -119,7 +111,7 @@ void ModChannelRef::Register(lua_State *L)
|
|||||||
lua_pop(L, 1); // Drop methodtable
|
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);
|
ModChannelRef *o = new ModChannelRef(channel);
|
||||||
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||||
@ -145,9 +137,9 @@ ModChannelRef *ModChannelRef::checkobject(lua_State *L, int narg)
|
|||||||
return *(ModChannelRef **)ud; // unbox pointer
|
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
|
// clang-format off
|
||||||
|
@ -37,11 +37,11 @@ public:
|
|||||||
class ModChannelRef : public ModApiBase
|
class ModChannelRef : public ModApiBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ModChannelRef(ModChannel *modchannel);
|
ModChannelRef(const std::string &modchannel);
|
||||||
~ModChannelRef() = default;
|
~ModChannelRef() = default;
|
||||||
|
|
||||||
static void Register(lua_State *L);
|
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()
|
// leave()
|
||||||
static int l_leave(lua_State *L);
|
static int l_leave(lua_State *L);
|
||||||
@ -57,9 +57,9 @@ private:
|
|||||||
static int gc_object(lua_State *L);
|
static int gc_object(lua_State *L);
|
||||||
|
|
||||||
static ModChannelRef *checkobject(lua_State *L, int narg);
|
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 char className[];
|
||||||
static const luaL_Reg methods[];
|
static const luaL_Reg methods[];
|
||||||
|
Loading…
Reference in New Issue
Block a user