mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-08-06 16:36:32 +02:00
Make properties and callbacks of non-custom tools read-only
Non-custom here means any built-in tool but also the ElementTool associated with elements, including custom ones. So, describing the tools this commit affects as "built-in tools" wouldn't quite be correct. It was even possible to cause crashes by freeing such tools. Also fix crashes when attempting to access non-custom tools as if they were custom tools. The incorrect assumption was that GameModel::GetToolIndex succeeding means that LuaScriptInterface::customTools has an entry for the tool, but this is only guaranteed for custom tools.
This commit is contained in:
@@ -60,6 +60,7 @@ struct CustomElement
|
|||||||
|
|
||||||
struct CustomTool
|
struct CustomTool
|
||||||
{
|
{
|
||||||
|
bool valid = false;
|
||||||
LuaSmartRef perform;
|
LuaSmartRef perform;
|
||||||
LuaSmartRef click;
|
LuaSmartRef click;
|
||||||
LuaSmartRef drag;
|
LuaSmartRef drag;
|
||||||
|
@@ -32,13 +32,15 @@ static int allocate(lua_State *L)
|
|||||||
lsi->gameModel->BuildMenus();
|
lsi->gameModel->BuildMenus();
|
||||||
auto index = *lsi->gameModel->GetToolIndex(lsi->gameModel->GetToolFromIdentifier(identifier));
|
auto index = *lsi->gameModel->GetToolIndex(lsi->gameModel->GetToolFromIdentifier(identifier));
|
||||||
lsi->customTools.resize(std::max(int(lsi->customTools.size()), index + 1));
|
lsi->customTools.resize(std::max(int(lsi->customTools.size()), index + 1));
|
||||||
|
lsi->customTools[index].valid = true;
|
||||||
lua_pushinteger(L, index);
|
lua_pushinteger(L, index);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsDefault(Tool *tool)
|
static bool IsCustom(int index)
|
||||||
{
|
{
|
||||||
return tool->Identifier.BeginsWith("DEFAULT_");
|
auto *lsi = GetLSI();
|
||||||
|
return index >= 0 && index < int(lsi->customTools.size()) && lsi->customTools[index].valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ffree(lua_State *L)
|
static int ffree(lua_State *L)
|
||||||
@@ -50,9 +52,9 @@ static int ffree(lua_State *L)
|
|||||||
{
|
{
|
||||||
return luaL_error(L, "Invalid tool");
|
return luaL_error(L, "Invalid tool");
|
||||||
}
|
}
|
||||||
if (IsDefault(tool))
|
if (!IsCustom(index))
|
||||||
{
|
{
|
||||||
return luaL_error(L, "Cannot free default tools");
|
return luaL_error(L, "Can only free custom tools");
|
||||||
}
|
}
|
||||||
lsi->customTools[index] = {};
|
lsi->customTools[index] = {};
|
||||||
lsi->gameModel->FreeTool(tool);
|
lsi->gameModel->FreeTool(tool);
|
||||||
@@ -285,6 +287,10 @@ static int property(lua_State *L)
|
|||||||
{
|
{
|
||||||
return luaL_error(L, "Invalid tool");
|
return luaL_error(L, "Invalid tool");
|
||||||
}
|
}
|
||||||
|
if (lua_gettop(L) > 2 && !IsCustom(index))
|
||||||
|
{
|
||||||
|
return luaL_error(L, "Can only change properties of custom tools");
|
||||||
|
}
|
||||||
ByteString propertyName = tpt_lua_checkByteString(L, 2);
|
ByteString propertyName = tpt_lua_checkByteString(L, 2);
|
||||||
auto handleCallback = [lsi, L, index, tool, &propertyName](
|
auto handleCallback = [lsi, L, index, tool, &propertyName](
|
||||||
auto customToolMember,
|
auto customToolMember,
|
||||||
@@ -296,10 +302,6 @@ static int property(lua_State *L)
|
|||||||
{
|
{
|
||||||
if (lua_gettop(L) > 2)
|
if (lua_gettop(L) > 2)
|
||||||
{
|
{
|
||||||
if (IsDefault(tool))
|
|
||||||
{
|
|
||||||
luaL_error(L, "Cannot change callbacks of default tools");
|
|
||||||
}
|
|
||||||
if (lua_type(L, 3) == LUA_TFUNCTION)
|
if (lua_type(L, 3) == LUA_TFUNCTION)
|
||||||
{
|
{
|
||||||
(lsi->customTools[index].*customToolMember).Assign(L, 3);
|
(lsi->customTools[index].*customToolMember).Assign(L, 3);
|
||||||
@@ -383,6 +385,19 @@ static int exists(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int isCustom(lua_State *L)
|
||||||
|
{
|
||||||
|
auto *lsi = GetLSI();
|
||||||
|
int index = luaL_checkinteger(L, 1);
|
||||||
|
auto *tool = lsi->gameModel->GetToolByIndex(index);
|
||||||
|
if (!tool)
|
||||||
|
{
|
||||||
|
return luaL_error(L, "Invalid tool");
|
||||||
|
}
|
||||||
|
lua_pushboolean(L, IsCustom(index));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void LuaTools::Open(lua_State *L)
|
void LuaTools::Open(lua_State *L)
|
||||||
{
|
{
|
||||||
auto *lsi = GetLSI();
|
auto *lsi = GetLSI();
|
||||||
@@ -391,6 +406,7 @@ void LuaTools::Open(lua_State *L)
|
|||||||
LFUNC(allocate),
|
LFUNC(allocate),
|
||||||
LFUNC(property),
|
LFUNC(property),
|
||||||
LFUNC(exists),
|
LFUNC(exists),
|
||||||
|
LFUNC(isCustom),
|
||||||
#undef LFUNC
|
#undef LFUNC
|
||||||
{ "free", ffree },
|
{ "free", ffree },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
|
Reference in New Issue
Block a user