Create wrapper around lua_pcall that properly tracks Lua execution time

A bug existed before where certain events would not update Engine's lastTick. If the sim was lagging hard, then this could cause "script is not responding" errors to appear in unintentional situations.

The starting execution time is tracked in LuaScriptInterface instead now, and set in tpt_lua_pcall
This commit is contained in:
jacob1 2023-02-17 21:58:57 -05:00
parent e5fec98d28
commit 6d4f6218a4
No known key found for this signature in database
GPG Key ID: 4E58A32D510E1995
9 changed files with 44 additions and 36 deletions

View File

@ -41,7 +41,6 @@ namespace ui
inline bool Running() { return running_; } inline bool Running() { return running_; }
inline bool Broken() { return break_; } inline bool Broken() { return break_; }
inline long unsigned int LastTick() { return lastTick; } inline long unsigned int LastTick() { return lastTick; }
inline void LastTick(long unsigned int tick) { lastTick = tick; }
void Exit(); void Exit();
void ConfirmExit(); void ConfirmExit();
void Break(); void Break();

View File

@ -260,11 +260,12 @@ int luacon_elementwrite(lua_State* l)
void luacon_hook(lua_State * l, lua_Debug * ar) void luacon_hook(lua_State * l, lua_Debug * ar)
{ {
if(ar->event == LUA_HOOKCOUNT && Platform::GetTime()-ui::Engine::Ref().LastTick() > 3000) auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
if (ar->event == LUA_HOOKCOUNT && Platform::GetTime() - luacon_ci->luaExecutionStart > 3000)
{ {
if(ConfirmPrompt::Blocking("Script not responding", "The Lua script may have stopped responding. There might be an infinite loop. Press \"Stop\" to stop it", "Stop")) if(ConfirmPrompt::Blocking("Script not responding", "The Lua script may have stopped responding. There might be an infinite loop. Press \"Stop\" to stop it", "Stop"))
luaL_error(l, "Error: Script not responding"); luaL_error(l, "Error: Script not responding");
ui::Engine::Ref().LastTick(Platform::GetTime()); luacon_ci->luaExecutionStart = Platform::GetTime();
} }
} }

View File

@ -73,7 +73,7 @@ void LuaButton::triggerAction()
{ {
lua_rawgeti(l, LUA_REGISTRYINDEX, actionFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, actionFunction);
lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref); lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref);
if (lua_pcall(l, 1, 0, 0)) if (tpt_lua_pcall(l, 1, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }

View File

@ -72,7 +72,7 @@ void LuaCheckbox::triggerAction()
lua_rawgeti(l, LUA_REGISTRYINDEX, actionFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, actionFunction);
lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref); lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref);
lua_pushboolean(l, checkbox->GetChecked()); lua_pushboolean(l, checkbox->GetChecked());
if (lua_pcall(l, 2, 0, 0)) if (tpt_lua_pcall(l, 2, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }

View File

@ -436,8 +436,7 @@ tpt.partsdata = nil");
initLegacyProps(); initLegacyProps();
ui::Engine::Ref().LastTick(Platform::GetTime()); if (luaL_loadbuffer(l, (const char *)eventcompat_lua, eventcompat_lua_size, "@[built-in eventcompat.lua]") || tpt_lua_pcall(l, 0, 0, 0))
if (luaL_loadbuffer(l, (const char *)eventcompat_lua, eventcompat_lua_size, "@[built-in eventcompat.lua]") || lua_pcall(l, 0, 0, 0))
{ {
throw std::runtime_error(ByteString("failed to load built-in eventcompat: ") + tpt_lua_toByteString(l, -1)); throw std::runtime_error(ByteString("failed to load built-in eventcompat: ") + tpt_lua_toByteString(l, -1));
} }
@ -462,7 +461,7 @@ void LuaScriptInterface::Init()
{ {
if (Platform::FileExists("autorun.lua")) if (Platform::FileExists("autorun.lua"))
{ {
if(luaL_loadfile(l, "autorun.lua") || lua_pcall(l, 0, 0, 0)) if(luaL_loadfile(l, "autorun.lua") || tpt_lua_pcall(l, 0, 0, 0))
Log(CommandInterface::LogError, luacon_geterror()); Log(CommandInterface::LogError, luacon_geterror());
else else
Log(CommandInterface::LogWarning, "Loaded autorun.lua"); Log(CommandInterface::LogWarning, "Loaded autorun.lua");
@ -3182,7 +3181,7 @@ static int luaUpdateWrapper(UPDATE_FUNC_ARGS)
lua_pushinteger(luacon_ci->l, y); lua_pushinteger(luacon_ci->l, y);
lua_pushinteger(luacon_ci->l, surround_space); lua_pushinteger(luacon_ci->l, surround_space);
lua_pushinteger(luacon_ci->l, nt); lua_pushinteger(luacon_ci->l, nt);
callret = lua_pcall(luacon_ci->l, 5, 1, 0); callret = tpt_lua_pcall(luacon_ci->l, 5, 1, 0);
if (callret) if (callret)
luacon_ci->Log(CommandInterface::LogError, luacon_geterror()); luacon_ci->Log(CommandInterface::LogError, luacon_geterror());
if(lua_isboolean(luacon_ci->l, -1)){ if(lua_isboolean(luacon_ci->l, -1)){
@ -3218,7 +3217,7 @@ static int luaGraphicsWrapper(GRAPHICS_FUNC_ARGS)
lua_pushinteger(luacon_ci->l, *colr); lua_pushinteger(luacon_ci->l, *colr);
lua_pushinteger(luacon_ci->l, *colg); lua_pushinteger(luacon_ci->l, *colg);
lua_pushinteger(luacon_ci->l, *colb); lua_pushinteger(luacon_ci->l, *colb);
callret = lua_pcall(luacon_ci->l, 4, 10, 0); callret = tpt_lua_pcall(luacon_ci->l, 4, 10, 0);
if (callret) if (callret)
{ {
luacon_ci->Log(CommandInterface::LogError, luacon_geterror()); luacon_ci->Log(CommandInterface::LogError, luacon_geterror());
@ -3264,7 +3263,7 @@ static void luaCreateWrapper(ELEMENT_CREATE_FUNC_ARGS)
lua_pushinteger(luacon_ci->l, y); lua_pushinteger(luacon_ci->l, y);
lua_pushinteger(luacon_ci->l, t); lua_pushinteger(luacon_ci->l, t);
lua_pushinteger(luacon_ci->l, v); lua_pushinteger(luacon_ci->l, v);
if (lua_pcall(luacon_ci->l, 5, 0, 0)) if (tpt_lua_pcall(luacon_ci->l, 5, 0, 0))
{ {
luacon_ci->Log(CommandInterface::LogError, "In create func: " + luacon_geterror()); luacon_ci->Log(CommandInterface::LogError, "In create func: " + luacon_geterror());
lua_pop(luacon_ci->l, 1); lua_pop(luacon_ci->l, 1);
@ -3283,7 +3282,7 @@ static bool luaCreateAllowedWrapper(ELEMENT_CREATE_ALLOWED_FUNC_ARGS)
lua_pushinteger(luacon_ci->l, x); lua_pushinteger(luacon_ci->l, x);
lua_pushinteger(luacon_ci->l, y); lua_pushinteger(luacon_ci->l, y);
lua_pushinteger(luacon_ci->l, t); lua_pushinteger(luacon_ci->l, t);
if (lua_pcall(luacon_ci->l, 4, 1, 0)) if (tpt_lua_pcall(luacon_ci->l, 4, 1, 0))
{ {
luacon_ci->Log(CommandInterface::LogError, "In create allowed: " + luacon_geterror()); luacon_ci->Log(CommandInterface::LogError, "In create allowed: " + luacon_geterror());
lua_pop(luacon_ci->l, 1); lua_pop(luacon_ci->l, 1);
@ -3309,7 +3308,7 @@ static void luaChangeTypeWrapper(ELEMENT_CHANGETYPE_FUNC_ARGS)
lua_pushinteger(luacon_ci->l, y); lua_pushinteger(luacon_ci->l, y);
lua_pushinteger(luacon_ci->l, from); lua_pushinteger(luacon_ci->l, from);
lua_pushinteger(luacon_ci->l, to); lua_pushinteger(luacon_ci->l, to);
if (lua_pcall(luacon_ci->l, 5, 0, 0)) if (tpt_lua_pcall(luacon_ci->l, 5, 0, 0))
{ {
luacon_ci->Log(CommandInterface::LogError, "In change type: " + luacon_geterror()); luacon_ci->Log(CommandInterface::LogError, "In change type: " + luacon_geterror());
lua_pop(luacon_ci->l, 1); lua_pop(luacon_ci->l, 1);
@ -3327,7 +3326,7 @@ static bool luaCtypeDrawWrapper(CTYPEDRAW_FUNC_ARGS)
lua_pushinteger(luacon_ci->l, i); lua_pushinteger(luacon_ci->l, i);
lua_pushinteger(luacon_ci->l, t); lua_pushinteger(luacon_ci->l, t);
lua_pushinteger(luacon_ci->l, v); lua_pushinteger(luacon_ci->l, v);
if (lua_pcall(luacon_ci->l, 3, 1, 0)) if (tpt_lua_pcall(luacon_ci->l, 3, 1, 0))
{ {
luacon_ci->Log(CommandInterface::LogError, luacon_geterror()); luacon_ci->Log(CommandInterface::LogError, luacon_geterror());
lua_pop(luacon_ci->l, 1); lua_pop(luacon_ci->l, 1);
@ -4291,7 +4290,6 @@ static int PushGameControllerEvent(lua_State * l, const GameControllerEvent &eve
bool LuaScriptInterface::HandleEvent(const GameControllerEvent &event) bool LuaScriptInterface::HandleEvent(const GameControllerEvent &event)
{ {
ui::Engine::Ref().LastTick(Platform::GetTime());
bool cont = true; bool cont = true;
gameControllerEventHandlers[event.index()].Push(l); gameControllerEventHandlers[event.index()].Push(l);
int len = lua_objlen(l, -1); int len = lua_objlen(l, -1);
@ -4299,12 +4297,11 @@ bool LuaScriptInterface::HandleEvent(const GameControllerEvent &event)
{ {
lua_rawgeti(l, -1, i); lua_rawgeti(l, -1, i);
int numArgs = PushGameControllerEvent(l, event); int numArgs = PushGameControllerEvent(l, event);
int callret = lua_pcall(l, numArgs, 1, 0); int callret = tpt_lua_pcall(l, numArgs, 1, 0);
if (callret) if (callret)
{ {
if (luacon_geterror() == "Error: Script not responding") if (luacon_geterror() == "Error: Script not responding")
{ {
ui::Engine::Ref().LastTick(Platform::GetTime());
for (int j = i; j <= len - 1; j++) for (int j = i; j <= len - 1; j++)
{ {
lua_rawgeti(l, -2, j + 1); lua_rawgeti(l, -2, j + 1);
@ -4359,7 +4356,6 @@ int LuaScriptInterface::Command(String command)
lastCode += "\n"; lastCode += "\n";
lastCode += command; lastCode += command;
ByteString tmp = ("return " + lastCode).ToUtf8(); ByteString tmp = ("return " + lastCode).ToUtf8();
ui::Engine::Ref().LastTick(Platform::GetTime());
luaL_loadbuffer(l, tmp.data(), tmp.size(), "@console"); luaL_loadbuffer(l, tmp.data(), tmp.size(), "@console");
if (lua_type(l, -1) != LUA_TFUNCTION) if (lua_type(l, -1) != LUA_TFUNCTION)
{ {
@ -4379,7 +4375,7 @@ int LuaScriptInterface::Command(String command)
else else
{ {
lastCode = ""; lastCode = "";
ret = lua_pcall(l, 0, LUA_MULTRET, 0); ret = tpt_lua_pcall(l, 0, LUA_MULTRET, 0);
if (ret) if (ret)
{ {
lastError = luacon_geterror(); lastError = luacon_geterror();
@ -4714,7 +4710,7 @@ int tpt_lua_loadstring(lua_State *L, const ByteString &str)
int tpt_lua_dostring(lua_State *L, const ByteString &str) int tpt_lua_dostring(lua_State *L, const ByteString &str)
{ {
return tpt_lua_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0); return tpt_lua_loadstring(L, str) || tpt_lua_pcall(L, 0, LUA_MULTRET, 0);
} }
bool tpt_lua_equalsString(lua_State *L, int index, const char *data, size_t size) bool tpt_lua_equalsString(lua_State *L, int index, const char *data, size_t size)
@ -4722,7 +4718,15 @@ bool tpt_lua_equalsString(lua_State *L, int index, const char *data, size_t size
return lua_isstring(L, index) && lua_objlen(L, index) == size && !memcmp(lua_tostring(L, index), data, size); return lua_isstring(L, index) && lua_objlen(L, index) == size && !memcmp(lua_tostring(L, index), data, size);
} }
int tpt_lua_pcall(lua_State *L, int numArgs, int numResults, int errorFunc)
{
auto *luacon_ci = static_cast<LuaScriptInterface *>(commandInterface);
luacon_ci->luaExecutionStart = Platform::GetTime();
return lua_pcall(L, numArgs, numResults, errorFunc);
}
CommandInterface *CommandInterface::Create(GameController * c, GameModel * m) CommandInterface *CommandInterface::Create(GameController * c, GameModel * m)
{ {
return new LuaScriptInterface(c, m); return new LuaScriptInterface(c, m);
} }

View File

@ -198,6 +198,7 @@ public:
ui::Window * Window; ui::Window * Window;
lua_State *l; lua_State *l;
long unsigned int luaExecutionStart = 0;
std::map<LuaComponent *, LuaSmartRef> grabbed_components; std::map<LuaComponent *, LuaSmartRef> grabbed_components;
LuaScriptInterface(GameController * c, GameModel * m); LuaScriptInterface(GameController * c, GameModel * m);
@ -239,3 +240,6 @@ bool tpt_lua_equalsLiteral(lua_State *L, int index, const char (&lit)[N])
{ {
return tpt_lua_equalsString(L, index, lit, N - 1U); return tpt_lua_equalsString(L, index, lit, N - 1U);
} }
int tpt_lua_pcall(lua_State *L, int numArgs, int numResults, int errorFunc);

View File

@ -72,7 +72,7 @@ void LuaSlider::triggerOnValueChanged()
lua_rawgeti(l, LUA_REGISTRYINDEX, onValueChangedFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, onValueChangedFunction);
lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref); lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref);
lua_pushinteger(l, slider->GetValue()); lua_pushinteger(l, slider->GetValue());
if (lua_pcall(l, 2, 0, 0)) if (tpt_lua_pcall(l, 2, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }

View File

@ -60,7 +60,7 @@ void LuaTextbox::triggerOnTextChanged()
{ {
lua_rawgeti(l, LUA_REGISTRYINDEX, onTextChangedFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, onTextChangedFunction);
lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref); lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref);
if (lua_pcall(l, 1, 0, 0)) if (tpt_lua_pcall(l, 1, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_optString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_optString(l, -1));
} }

View File

@ -224,7 +224,7 @@ void LuaWindow::triggerOnInitialized()
if(onInitializedFunction) if(onInitializedFunction)
{ {
lua_rawgeti(l, LUA_REGISTRYINDEX, onInitializedFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, onInitializedFunction);
if(lua_pcall(l, 0, 0, 0)) if(tpt_lua_pcall(l, 0, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -236,7 +236,7 @@ void LuaWindow::triggerOnExit()
if(onExitFunction) if(onExitFunction)
{ {
lua_rawgeti(l, LUA_REGISTRYINDEX, onExitFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, onExitFunction);
if(lua_pcall(l, 0, 0, 0)) if(tpt_lua_pcall(l, 0, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -249,7 +249,7 @@ void LuaWindow::triggerOnTick(float dt)
{ {
lua_rawgeti(l, LUA_REGISTRYINDEX, onTickFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, onTickFunction);
lua_pushnumber(l, dt); lua_pushnumber(l, dt);
if(lua_pcall(l, 1, 0, 0)) if(tpt_lua_pcall(l, 1, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -261,7 +261,7 @@ void LuaWindow::triggerOnDraw()
if(onDrawFunction) if(onDrawFunction)
{ {
lua_rawgeti(l, LUA_REGISTRYINDEX, onDrawFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, onDrawFunction);
if(lua_pcall(l, 0, 0, 0)) if(tpt_lua_pcall(l, 0, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -273,7 +273,7 @@ void LuaWindow::triggerOnFocus()
if(onFocusFunction) if(onFocusFunction)
{ {
lua_rawgeti(l, LUA_REGISTRYINDEX, onFocusFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, onFocusFunction);
if(lua_pcall(l, 0, 0, 0)) if(tpt_lua_pcall(l, 0, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -285,7 +285,7 @@ void LuaWindow::triggerOnBlur()
if(onBlurFunction) if(onBlurFunction)
{ {
lua_rawgeti(l, LUA_REGISTRYINDEX, onBlurFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, onBlurFunction);
if(lua_pcall(l, 0, 0, 0)) if(tpt_lua_pcall(l, 0, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -297,7 +297,7 @@ void LuaWindow::triggerOnTryExit()
if(onTryExitFunction) if(onTryExitFunction)
{ {
lua_rawgeti(l, LUA_REGISTRYINDEX, onTryExitFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, onTryExitFunction);
if(lua_pcall(l, 0, 0, 0)) if(tpt_lua_pcall(l, 0, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -309,7 +309,7 @@ void LuaWindow::triggerOnTryOkay()
if(onTryOkayFunction) if(onTryOkayFunction)
{ {
lua_rawgeti(l, LUA_REGISTRYINDEX, onTryOkayFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, onTryOkayFunction);
if(lua_pcall(l, 0, 0, 0)) if(tpt_lua_pcall(l, 0, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -325,7 +325,7 @@ void LuaWindow::triggerOnMouseMove(int x, int y, int dx, int dy)
lua_pushinteger(l, y); lua_pushinteger(l, y);
lua_pushinteger(l, dx); lua_pushinteger(l, dx);
lua_pushinteger(l, dy); lua_pushinteger(l, dy);
if(lua_pcall(l, 4, 0, 0)) if(tpt_lua_pcall(l, 4, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -340,7 +340,7 @@ void LuaWindow::triggerOnMouseDown(int x, int y, unsigned button)
lua_pushinteger(l, x); lua_pushinteger(l, x);
lua_pushinteger(l, y); lua_pushinteger(l, y);
lua_pushinteger(l, button); lua_pushinteger(l, button);
if(lua_pcall(l, 3, 0, 0)) if(tpt_lua_pcall(l, 3, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -355,7 +355,7 @@ void LuaWindow::triggerOnMouseUp(int x, int y, unsigned button)
lua_pushinteger(l, x); lua_pushinteger(l, x);
lua_pushinteger(l, y); lua_pushinteger(l, y);
lua_pushinteger(l, button); lua_pushinteger(l, button);
if(lua_pcall(l, 3, 0, 0)) if(tpt_lua_pcall(l, 3, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -370,7 +370,7 @@ void LuaWindow::triggerOnMouseWheel(int x, int y, int d)
lua_pushinteger(l, x); lua_pushinteger(l, x);
lua_pushinteger(l, y); lua_pushinteger(l, y);
lua_pushinteger(l, d); lua_pushinteger(l, d);
if(lua_pcall(l, 3, 0, 0)) if(tpt_lua_pcall(l, 3, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -387,7 +387,7 @@ void LuaWindow::triggerOnKeyPress(int key, int scan, bool repeat, bool shift, bo
lua_pushboolean(l, shift); lua_pushboolean(l, shift);
lua_pushboolean(l, ctrl); lua_pushboolean(l, ctrl);
lua_pushboolean(l, alt); lua_pushboolean(l, alt);
if(lua_pcall(l, 5, 0, 0)) if(tpt_lua_pcall(l, 5, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }
@ -404,7 +404,7 @@ void LuaWindow::triggerOnKeyRelease(int key, int scan, bool repeat, bool shift,
lua_pushboolean(l, shift); lua_pushboolean(l, shift);
lua_pushboolean(l, ctrl); lua_pushboolean(l, ctrl);
lua_pushboolean(l, alt); lua_pushboolean(l, alt);
if(lua_pcall(l, 5, 0, 0)) if(tpt_lua_pcall(l, 5, 0, 0))
{ {
ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1));
} }