summaryrefslogtreecommitdiffstats
path: root/src/Bindings/LuaState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Bindings/LuaState.cpp')
-rw-r--r--src/Bindings/LuaState.cpp363
1 files changed, 101 insertions, 262 deletions
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index 25c77a652..08c7e19d7 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -19,13 +19,13 @@ extern "C"
#include "../Entities/Entity.h"
#include "../BlockEntities/BlockEntity.h"
-// fwd: SQLite/lsqlite3.c
+// fwd: "SQLite/lsqlite3.c"
extern "C"
{
int luaopen_lsqlite3(lua_State * L);
}
-// fwd: LuaExpat/lxplib.c:
+// fwd: "LuaExpat/lxplib.c":
extern "C"
{
int luaopen_lxp(lua_State * L);
@@ -107,7 +107,7 @@ void cLuaState::Create(void)
void cLuaState::RegisterAPILibs(void)
{
tolua_AllToLua_open(m_LuaState);
- ManualBindings::Bind(m_LuaState);
+ cManualBindings::Bind(m_LuaState);
DeprecatedBindings::Bind(m_LuaState);
luaopen_lsqlite3(m_LuaState);
luaopen_lxp(m_LuaState);
@@ -530,42 +530,6 @@ void cLuaState::Push(bool a_Value)
-void cLuaState::Push(cBlockEntity * a_BlockEntity)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_BlockEntity, (a_BlockEntity == nullptr) ? "cBlockEntity" : a_BlockEntity->GetClass());
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cChunkDesc * a_ChunkDesc)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_ChunkDesc, "cChunkDesc");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cClientHandle * a_Client)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_Client, "cClientHandle");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
void cLuaState::Push(cEntity * a_Entity)
{
ASSERT(IsValid());
@@ -632,42 +596,6 @@ void cLuaState::Push(cEntity * a_Entity)
-void cLuaState::Push(cHopperEntity * a_Hopper)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_Hopper, "cHopperEntity");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cItem * a_Item)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_Item, "cItem");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cItems * a_Items)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_Items, "cItems");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
void cLuaState::Push(cLuaServerHandle * a_ServerHandle)
{
ASSERT(IsValid());
@@ -704,114 +632,6 @@ void cLuaState::Push(cLuaUDPEndpoint * a_UDPEndpoint)
-void cLuaState::Push(cMonster * a_Monster)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_Monster, "cMonster");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cPickup * a_Pickup)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_Pickup, "cPickup");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cPlayer * a_Player)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_Player, "cPlayer");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cPluginLua * a_Plugin)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_Plugin, "cPluginLua");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cProjectileEntity * a_ProjectileEntity)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_ProjectileEntity, "cProjectileEntity");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cTNTEntity * a_TNTEntity)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_TNTEntity, "cTNTEntity");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cWebAdmin * a_WebAdmin)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_WebAdmin, "cWebAdmin");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cWindow * a_Window)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_Window, "cWindow");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
-void cLuaState::Push(cWorld * a_World)
-{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_World, "cWorld");
- m_NumCurrentFunctionArgs += 1;
-}
-
-
-
-
-
void cLuaState::Push(double a_Value)
{
ASSERT(IsValid());
@@ -836,11 +656,18 @@ void cLuaState::Push(int a_Value)
-void cLuaState::Push(TakeDamageInfo * a_TDI)
+void cLuaState::Push(void * a_Ptr)
{
+ UNUSED(a_Ptr);
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_TDI, "TakeDamageInfo");
+ // Investigate the cause of this - what is the callstack?
+ // One code path leading here is the OnHookExploding / OnHookExploded with exotic parameters. Need to decide what to do with them
+ LOGWARNING("Lua engine: attempting to push a plain pointer, pushing nil instead.");
+ LOGWARNING("This indicates an unimplemented part of MCS bindings");
+ LogStackTrace();
+
+ lua_pushnil(m_LuaState);
m_NumCurrentFunctionArgs += 1;
}
@@ -848,11 +675,11 @@ void cLuaState::Push(TakeDamageInfo * a_TDI)
-void cLuaState::Push(Vector3d * a_Vector)
+void cLuaState::Push(std::chrono::milliseconds a_Value)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_Vector, "Vector3<double>");
+ tolua_pushnumber(m_LuaState, static_cast<lua_Number>(a_Value.count()));
m_NumCurrentFunctionArgs += 1;
}
@@ -860,51 +687,40 @@ void cLuaState::Push(Vector3d * a_Vector)
-void cLuaState::Push(Vector3i * a_Vector)
+/*
+void cLuaState::PushUserType(void * a_Object, const char * a_Type)
{
ASSERT(IsValid());
- tolua_pushusertype(m_LuaState, a_Vector, "Vector3<int>");
+ tolua_pushusertype(m_LuaState, a_Object, a_Type);
m_NumCurrentFunctionArgs += 1;
}
+*/
-void cLuaState::Push(void * a_Ptr)
-{
- UNUSED(a_Ptr);
- ASSERT(IsValid());
-
- // Investigate the cause of this - what is the callstack?
- // One code path leading here is the OnHookExploding / OnHookExploded with exotic parameters. Need to decide what to do with them
- LOGWARNING("Lua engine: attempting to push a plain pointer, pushing nil instead.");
- LOGWARNING("This indicates an unimplemented part of MCS bindings");
- LogStackTrace();
-
- lua_pushnil(m_LuaState);
- m_NumCurrentFunctionArgs += 1;
-}
-
-void cLuaState::Push(std::chrono::milliseconds a_Value)
+void cLuaState::GetStackValue(int a_StackPos, AString & a_Value)
{
- ASSERT(IsValid());
-
- tolua_pushnumber(m_LuaState, static_cast<lua_Number>(a_Value.count()));
- m_NumCurrentFunctionArgs += 1;
+ size_t len = 0;
+ const char * data = lua_tolstring(m_LuaState, a_StackPos, &len);
+ if (data != nullptr)
+ {
+ a_Value.assign(data, len);
+ }
}
-void cLuaState::PushUserType(void * a_Object, const char * a_Type)
+void cLuaState::GetStackValue(int a_StackPos, BLOCKTYPE & a_ReturnedVal)
{
- ASSERT(IsValid());
-
- tolua_pushusertype(m_LuaState, a_Object, a_Type);
- m_NumCurrentFunctionArgs += 1;
+ if (lua_isnumber(m_LuaState, a_StackPos))
+ {
+ a_ReturnedVal = static_cast<BLOCKTYPE>(tolua_tonumber(m_LuaState, a_StackPos, a_ReturnedVal));
+ }
}
@@ -920,13 +736,11 @@ void cLuaState::GetStackValue(int a_StackPos, bool & a_ReturnedVal)
-void cLuaState::GetStackValue(int a_StackPos, AString & a_Value)
+void cLuaState::GetStackValue(int a_StackPos, cPluginManager::CommandResult & a_Result)
{
- size_t len = 0;
- const char * data = lua_tolstring(m_LuaState, a_StackPos, &len);
- if (data != nullptr)
+ if (lua_isnumber(m_LuaState, a_StackPos))
{
- a_Value.assign(data, len);
+ a_Result = static_cast<cPluginManager::CommandResult>(static_cast<int>((tolua_tonumber(m_LuaState, a_StackPos, a_Result))));
}
}
@@ -934,12 +748,9 @@ void cLuaState::GetStackValue(int a_StackPos, AString & a_Value)
-void cLuaState::GetStackValue(int a_StackPos, int & a_ReturnedVal)
+void cLuaState::GetStackValue(int a_StackPos, cRef & a_Ref)
{
- if (lua_isnumber(m_LuaState, a_StackPos))
- {
- a_ReturnedVal = (int)tolua_tonumber(m_LuaState, a_StackPos, a_ReturnedVal);
- }
+ a_Ref.RefStack(*this, a_StackPos);
}
@@ -958,11 +769,11 @@ void cLuaState::GetStackValue(int a_StackPos, double & a_ReturnedVal)
-void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal)
+void cLuaState::GetStackValue(int a_StackPos, float & a_ReturnedVal)
{
if (lua_isnumber(m_LuaState, a_StackPos))
{
- a_ReturnedVal = (eWeather)Clamp((int)tolua_tonumber(m_LuaState, a_StackPos, a_ReturnedVal), (int)wSunny, (int)wThunderstorm);
+ a_ReturnedVal = static_cast<float>(tolua_tonumber(m_LuaState, a_StackPos, a_ReturnedVal));
}
}
@@ -970,35 +781,27 @@ void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal)
-void cLuaState::GetStackValue(int a_StackPos, pBoundingBox & a_ReturnedVal)
+void cLuaState::GetStackValue(int a_StackPos, eWeather & a_ReturnedVal)
{
- if (lua_isnil(m_LuaState, a_StackPos))
+ if (!lua_isnumber(m_LuaState, a_StackPos))
{
- a_ReturnedVal = nullptr;
return;
}
- tolua_Error err;
- if (tolua_isusertype(m_LuaState, a_StackPos, "cBoundingBox", false, &err))
- {
- a_ReturnedVal = *((cBoundingBox **)lua_touserdata(m_LuaState, a_StackPos));
- }
+ a_ReturnedVal = static_cast<eWeather>(Clamp(
+ static_cast<int>(tolua_tonumber(m_LuaState, a_StackPos, a_ReturnedVal)),
+ static_cast<int>(wSunny), static_cast<int>(wThunderstorm))
+ );
}
-void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal)
+void cLuaState::GetStackValue(int a_StackPos, int & a_ReturnedVal)
{
- if (lua_isnil(m_LuaState, a_StackPos))
- {
- a_ReturnedVal = nullptr;
- return;
- }
- tolua_Error err;
- if (tolua_isusertype(m_LuaState, a_StackPos, "cWorld", false, &err))
+ if (lua_isnumber(m_LuaState, a_StackPos))
{
- a_ReturnedVal = *((cWorld **)lua_touserdata(m_LuaState, a_StackPos));
+ a_ReturnedVal = static_cast<int>(tolua_tonumber(m_LuaState, a_StackPos, a_ReturnedVal));
}
}
@@ -1006,15 +809,6 @@ void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal)
-void cLuaState::GetStackValue(int a_StackPos, cRef & a_Ref)
-{
- a_Ref.RefStack(*this, a_StackPos);
-}
-
-
-
-
-
bool cLuaState::CallFunction(int a_NumResults)
{
ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first
@@ -1133,6 +927,9 @@ bool cLuaState::CheckParamTable(int a_StartParam, int a_EndParam)
VERIFY(lua_getstack(m_LuaState, 0, &entry));
VERIFY(lua_getinfo (m_LuaState, "n", &entry));
AString ErrMsg = Printf("#ferror in function '%s'.", (entry.name != nullptr) ? entry.name : "?");
+
+ BreakIntoDebugger(m_LuaState);
+
tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err);
return false;
} // for i - Param
@@ -1280,7 +1077,7 @@ bool cLuaState::CheckParamFunctionOrNil(int a_StartParam, int a_EndParam)
bool cLuaState::CheckParamEnd(int a_Param)
{
tolua_Error tolua_err;
- if (tolua_isnoobj(m_LuaState, a_Param, &tolua_err))
+ if (tolua_isnoobj(m_LuaState, a_Param, &tolua_err) == 1)
{
return true;
}
@@ -1297,6 +1094,30 @@ bool cLuaState::CheckParamEnd(int a_Param)
+bool cLuaState::IsParamUserType(int a_Param, AString a_UserType)
+{
+ ASSERT(IsValid());
+
+ tolua_Error tolua_err;
+ return (tolua_isusertype(m_LuaState, a_Param, a_UserType.c_str(), 0, &tolua_err) == 1);
+}
+
+
+
+
+
+bool cLuaState::IsParamNumber(int a_Param)
+{
+ ASSERT(IsValid());
+
+ tolua_Error tolua_err;
+ return (tolua_isnumber(m_LuaState, a_Param, 0, &tolua_err) == 1);
+}
+
+
+
+
+
bool cLuaState::ReportErrors(int a_Status)
{
return ReportErrors(m_LuaState, a_Status);
@@ -1376,7 +1197,7 @@ int cLuaState::CallFunctionWithForeignParams(
if (!PushFunction(a_FunctionName.c_str()))
{
LOGWARNING("Function '%s' not found", a_FunctionName.c_str());
- lua_pop(m_LuaState, 2);
+ lua_settop(m_LuaState, OldTop);
return -1;
}
@@ -1384,7 +1205,7 @@ int cLuaState::CallFunctionWithForeignParams(
if (CopyStackFrom(a_SrcLuaState, a_SrcParamStart, a_SrcParamEnd) < 0)
{
// Something went wrong, fix the stack and exit
- lua_pop(m_LuaState, 2);
+ lua_settop(m_LuaState, OldTop);
m_NumCurrentFunctionArgs = -1;
m_CurrentFunctionName.clear();
return -1;
@@ -1395,13 +1216,8 @@ int cLuaState::CallFunctionWithForeignParams(
if (ReportErrors(s))
{
LOGWARN("Error while calling function '%s' in '%s'", a_FunctionName.c_str(), m_SubsystemName.c_str());
- // Fix the stack.
- // We don't know how many values have been pushed, so just get rid of any that weren't there initially
- int CurTop = lua_gettop(m_LuaState);
- if (CurTop > OldTop)
- {
- lua_pop(m_LuaState, CurTop - OldTop);
- }
+ // Reset the stack:
+ lua_settop(m_LuaState, OldTop);
// Reset the internal checking mechanisms:
m_NumCurrentFunctionArgs = -1;
@@ -1553,6 +1369,7 @@ int cLuaState::ReportFnCallErrors(lua_State * a_LuaState)
{
LOGWARNING("LUA: %s", lua_tostring(a_LuaState, -1));
LogStackTrace(a_LuaState, 1);
+ BreakIntoDebugger(a_LuaState);
return 1; // We left the error message on the stack as the return value
}
@@ -1560,6 +1377,28 @@ int cLuaState::ReportFnCallErrors(lua_State * a_LuaState)
+int cLuaState::BreakIntoDebugger(lua_State * a_LuaState)
+{
+ // Call the BreakIntoDebugger function, if available:
+ lua_getglobal(a_LuaState, "BreakIntoDebugger");
+ if (!lua_isfunction(a_LuaState, -1))
+ {
+ LOGD("LUA: BreakIntoDebugger() not found / not a function");
+ lua_pop(a_LuaState, 1);
+ return 1;
+ }
+ lua_insert(a_LuaState, -2); // Copy the string that has been passed to us
+ LOGD("Calling BreakIntoDebugger()...");
+ lua_call(a_LuaState, 1, 0);
+ LOGD("Returned from BreakIntoDebugger().");
+
+ return 0;
+}
+
+
+
+
+
////////////////////////////////////////////////////////////////////////////////
// cLuaState::cRef: