diff options
author | Tiger Wang <ziwei.tiger@hotmail.co.uk> | 2014-07-18 21:10:51 +0200 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@hotmail.co.uk> | 2014-07-18 21:10:51 +0200 |
commit | 37140ae57835680d2c4fb3aa365082622d3a150e (patch) | |
tree | 89a636c74375b3c9f0fe77b20ecbadc693bd0989 /src/Bindings | |
parent | Merge branch 'master' of https://github.com/mc-server/MCServer into portals (diff) | |
parent | Monster fixes (diff) | |
download | cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar.gz cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar.bz2 cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar.lz cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar.xz cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar.zst cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.zip |
Diffstat (limited to '')
-rw-r--r-- | src/Bindings/.gitignore | 1 | ||||
-rw-r--r-- | src/Bindings/AllToLua.pkg | 2 | ||||
-rw-r--r-- | src/Bindings/DeprecatedBindings.cpp | 18 | ||||
-rw-r--r-- | src/Bindings/LuaChunkStay.cpp | 2 | ||||
-rw-r--r-- | src/Bindings/LuaState.cpp | 16 | ||||
-rw-r--r-- | src/Bindings/LuaState.h | 636 | ||||
-rw-r--r-- | src/Bindings/LuaWindow.cpp | 4 | ||||
-rw-r--r-- | src/Bindings/ManualBindings.cpp | 42 | ||||
-rw-r--r-- | src/Bindings/Plugin.h | 11 | ||||
-rw-r--r-- | src/Bindings/PluginLua.cpp | 70 | ||||
-rw-r--r-- | src/Bindings/PluginLua.h | 6 | ||||
-rw-r--r-- | src/Bindings/PluginManager.cpp | 113 | ||||
-rw-r--r-- | src/Bindings/PluginManager.h | 58 | ||||
-rw-r--r-- | src/Bindings/WebPlugin.cpp | 20 | ||||
-rw-r--r-- | src/Bindings/WebPlugin.h | 2 | ||||
-rw-r--r-- | src/Bindings/gen_LuaState_Call.lua | 196 | ||||
-rw-r--r-- | src/Bindings/virtual_method_hooks.lua | 14 |
17 files changed, 474 insertions, 737 deletions
diff --git a/src/Bindings/.gitignore b/src/Bindings/.gitignore index af8aa76fa..0d00dd578 100644 --- a/src/Bindings/.gitignore +++ b/src/Bindings/.gitignore @@ -1 +1,2 @@ lua51.dll +LuaState_Call.inc diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg index 4fe86e1c5..1e5dfd2fe 100644 --- a/src/Bindings/AllToLua.pkg +++ b/src/Bindings/AllToLua.pkg @@ -40,7 +40,7 @@ $cfile "../Entities/Painting.h" $cfile "../Entities/Pickup.h" $cfile "../Entities/ProjectileEntity.h" $cfile "../Entities/TNTEntity.h" -$cfile "../Entities/Effects.h" +$cfile "../Entities/EntityEffect.h" $cfile "../Server.h" $cfile "../World.h" $cfile "../Inventory.h" diff --git a/src/Bindings/DeprecatedBindings.cpp b/src/Bindings/DeprecatedBindings.cpp index d51ba2da3..d2e60945d 100644 --- a/src/Bindings/DeprecatedBindings.cpp +++ b/src/Bindings/DeprecatedBindings.cpp @@ -39,7 +39,7 @@ static int tolua_get_AllToLua_g_BlockLightValue(lua_State* tolua_S) tolua_pushnumber(tolua_S,(lua_Number)cBlockInfo::GetLightValue((BLOCKTYPE)BlockType)); return 1; } -#endif //#ifndef TOLUA_DISABLE +#endif // #ifndef TOLUA_DISABLE @@ -65,7 +65,7 @@ static int tolua_get_AllToLua_g_BlockSpreadLightFalloff(lua_State* tolua_S) tolua_pushnumber(tolua_S, (lua_Number)cBlockInfo::GetSpreadLightFalloff((BLOCKTYPE)BlockType)); return 1; } -#endif //#ifndef TOLUA_DISABLE +#endif // #ifndef TOLUA_DISABLE @@ -91,7 +91,7 @@ static int tolua_get_AllToLua_g_BlockTransparent(lua_State* tolua_S) tolua_pushboolean(tolua_S, cBlockInfo::IsTransparent((BLOCKTYPE)BlockType)); return 1; } -#endif //#ifndef TOLUA_DISABLE +#endif // #ifndef TOLUA_DISABLE @@ -117,7 +117,7 @@ static int tolua_get_AllToLua_g_BlockOneHitDig(lua_State* tolua_S) tolua_pushboolean(tolua_S, cBlockInfo::IsOneHitDig((BLOCKTYPE)BlockType)); return 1; } -#endif //#ifndef TOLUA_DISABLE +#endif // #ifndef TOLUA_DISABLE @@ -143,7 +143,7 @@ static int tolua_get_AllToLua_g_BlockPistonBreakable(lua_State* tolua_S) tolua_pushboolean(tolua_S, cBlockInfo::IsPistonBreakable((BLOCKTYPE)BlockType)); return 1; } -#endif //#ifndef TOLUA_DISABLE +#endif // #ifndef TOLUA_DISABLE @@ -169,7 +169,7 @@ static int tolua_get_AllToLua_g_BlockIsSnowable(lua_State* tolua_S) tolua_pushboolean(tolua_S, cBlockInfo::IsSnowable((BLOCKTYPE)BlockType)); return 1; } -#endif //#ifndef TOLUA_DISABLE +#endif // #ifndef TOLUA_DISABLE @@ -195,7 +195,7 @@ static int tolua_get_AllToLua_g_BlockRequiresSpecialTool(lua_State* tolua_S) tolua_pushboolean(tolua_S, cBlockInfo::RequiresSpecialTool((BLOCKTYPE)BlockType)); return 1; } -#endif //#ifndef TOLUA_DISABLE +#endif // #ifndef TOLUA_DISABLE @@ -221,7 +221,7 @@ static int tolua_get_AllToLua_g_BlockIsSolid(lua_State* tolua_S) tolua_pushboolean(tolua_S, (bool)cBlockInfo::IsSolid((BLOCKTYPE)BlockType)); return 1; } -#endif //#ifndef TOLUA_DISABLE +#endif // #ifndef TOLUA_DISABLE @@ -247,7 +247,7 @@ static int tolua_get_AllToLua_g_BlockFullyOccupiesVoxel(lua_State* tolua_S) tolua_pushboolean(tolua_S, (bool)cBlockInfo::FullyOccupiesVoxel((BLOCKTYPE)BlockType)); return 1; } -#endif //#ifndef TOLUA_DISABLE +#endif // #ifndef TOLUA_DISABLE diff --git a/src/Bindings/LuaChunkStay.cpp b/src/Bindings/LuaChunkStay.cpp index 985a18a95..59b02d8f7 100644 --- a/src/Bindings/LuaChunkStay.cpp +++ b/src/Bindings/LuaChunkStay.cpp @@ -76,7 +76,7 @@ bool cLuaChunkStay::AddChunks(int a_ChunkCoordTableStackPos) -void cLuaChunkStay::AddChunkCoord(cLuaState & L, int a_Index) +void cLuaChunkStay::AddChunkCoord(cLuaState & L, int a_Index) { // Check that the element has 2 coords: int NumCoords = luaL_getn(L, -1); diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 7a5ed1425..7d918cf2b 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -40,7 +40,7 @@ const cLuaState::cRet cLuaState::Return = {}; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cLuaState: cLuaState::cLuaState(const AString & a_SubsystemName) : @@ -811,6 +811,18 @@ void cLuaState::GetStackValue(int a_StackPos, double & a_ReturnedVal) +void cLuaState::GetStackValue(int a_StackPos, eWeather & 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); + } +} + + + + + bool cLuaState::CallFunction(int a_NumResults) { ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first @@ -1359,7 +1371,7 @@ int cLuaState::ReportFnCallErrors(lua_State * a_LuaState) -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cLuaState::cRef: cLuaState::cRef::cRef(void) : diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 066390e39..afac77ce8 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -9,10 +9,11 @@ Owned lua_State is created by calling Create() and the cLuaState automatically c Or, lua_State can be attached by calling Attach(), the cLuaState doesn't close such a state Attaching a state will automatically close an owned state. -Calling a Lua function is done by pushing the function, either by PushFunction() or PushFunctionFromRegistry(), -then pushing the arguments (PushString(), PushNumber(), PushUserData() etc.) and finally -executing CallFunction(). cLuaState automatically keeps track of the number of arguments and the name of the -function (for logging purposes), which makes the call less error-prone. +Calling a Lua function is done internally by pushing the function using PushFunction(), then pushing the +arguments and finally executing CallFunction(). cLuaState automatically keeps track of the number of +arguments and the name of the function (for logging purposes). After the call the return values are read from +the stack using GetStackValue(). All of this is wrapped in a templated function overloads cLuaState::Call(), +which is generated automatically by gen_LuaState_Call.lua script file into the LuaState_Call.inc file. Reference management is provided by the cLuaState::cRef class. This is used when you need to hold a reference to any Lua object across several function calls; usually this is used for callbacks. The class is RAII-like, with @@ -30,6 +31,7 @@ extern "C" } #include "../Vector3.h" +#include "../Defines.h" @@ -126,7 +128,7 @@ public: /** Creates a new instance. The LuaState is not initialized. - a_SubsystemName is used for reporting problems in the console, it is "plugin %s" for plugins, + a_SubsystemName is used for reporting problems in the console, it is "plugin %s" for plugins, or "LuaScript" for the cLuaScript template */ cLuaState(const AString & a_SubsystemName); @@ -222,625 +224,13 @@ public: /** Retrieve value at a_StackPos, if it is a valid number. If not, a_Value is unchanged */ void GetStackValue(int a_StackPos, double & a_Value); + /** Retrieve value at a_StackPos, if it is a valid number, converting and clamping it to eWeather. + If not, a_Value is unchanged. */ + void GetStackValue(int a_StackPos, eWeather & a_Value); + - /** Call any 0-param 0-return Lua function in a single line: */ - template <typename FnT> - bool Call(FnT a_FnName) - { - if (!PushFunction(a_FnName)) - { - return false; - } - return CallFunction(0); - } - - /** Call any 1-param 0-return Lua function in a single line: */ - template< - typename FnT, - typename ArgT1 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1) - { - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - return CallFunction(0); - } - - /** Call any 2-param 0-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2) - { - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - return CallFunction(0); - } - - /** Call any 3-param 0-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3) - { - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - return CallFunction(0); - } - - /** Call any 0-param 1-return Lua function in a single line: */ - template< - typename FnT, typename RetT1 - > - bool Call(FnT a_FnName, const cRet & a_Mark, RetT1 & a_Ret1) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; - } - - /** Call any 1-param 1-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename RetT1 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, const cRet & a_Mark, RetT1 & a_Ret1) - { - int InitialTop = lua_gettop(m_LuaState); - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - ASSERT(InitialTop == lua_gettop(m_LuaState)); - return true; - } - - /** Call any 2-param 1-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename RetT1 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, const cRet & a_Mark, RetT1 & a_Ret1) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; - } - - /** Call any 3-param 1-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename RetT1 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, const cRet & a_Mark, RetT1 & a_Ret1) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; - } - - /** Call any 4-param 1-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename RetT1 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, const cRet & a_Mark, RetT1 & a_Ret1) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; - } - - /** Call any 5-param 1-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename RetT1 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, const cRet & a_Mark, RetT1 & a_Ret1) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; - } - - /** Call any 6-param 1-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6, - typename RetT1 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, const cRet & a_Mark, RetT1 & a_Ret1) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - Push(a_Arg6); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; - } - - /** Call any 7-param 1-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6, - typename ArgT7, typename RetT1 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - Push(a_Arg6); - Push(a_Arg7); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; - } - - /** Call any 8-param 1-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6, - typename ArgT7, typename ArgT8, typename RetT1 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, const cRet & a_Mark, RetT1 & a_Ret1) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - Push(a_Arg6); - Push(a_Arg7); - Push(a_Arg8); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; - } - - /** Call any 9-param 1-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6, - typename ArgT7, typename ArgT8, typename ArgT9, typename RetT1 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, const cRet & a_Mark, RetT1 & a_Ret1) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - Push(a_Arg6); - Push(a_Arg7); - Push(a_Arg8); - Push(a_Arg9); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; - } - - /** Call any 10-param 1-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6, - typename ArgT7, typename ArgT8, typename ArgT9, typename ArgT10, typename RetT1 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, ArgT10 a_Arg10, const cRet & a_Mark, RetT1 & a_Ret1) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - Push(a_Arg6); - Push(a_Arg7); - Push(a_Arg8); - Push(a_Arg9); - Push(a_Arg10); - if (!CallFunction(1)) - { - return false; - } - GetStackValue(-1, a_Ret1); - lua_pop(m_LuaState, 1); - return true; - } - - /** Call any 1-param 2-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename RetT1, typename RetT2 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; - } - - /** Call any 2-param 2-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename RetT1, typename RetT2 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; - } - - /** Call any 3-param 2-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, - typename RetT1, typename RetT2 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; - } - - /** Call any 4-param 2-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, - typename RetT1, typename RetT2 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; - } - - /** Call any 5-param 2-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, - typename RetT1, typename RetT2 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; - } - - /** Call any 6-param 2-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, - typename ArgT6, - typename RetT1, typename RetT2 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - Push(a_Arg6); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; - } - - /** Call any 7-param 2-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, - typename ArgT6, typename ArgT7, - typename RetT1, typename RetT2 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - Push(a_Arg6); - Push(a_Arg7); - if (!CallFunction(2)) - { - return false; - } - GetStackValue(-2, a_Ret1); - GetStackValue(-1, a_Ret2); - lua_pop(m_LuaState, 2); - return true; - } - - /** Call any 7-param 3-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, - typename ArgT6, typename ArgT7, - typename RetT1, typename RetT2, typename RetT3 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - Push(a_Arg6); - Push(a_Arg7); - if (!CallFunction(3)) - { - return false; - } - GetStackValue(-3, a_Ret1); - GetStackValue(-2, a_Ret2); - GetStackValue(-1, a_Ret3); - lua_pop(m_LuaState, 3); - return true; - } - - /** Call any 8-param 3-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, - typename ArgT6, typename ArgT7, typename ArgT8, - typename RetT1, typename RetT2, typename RetT3 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - Push(a_Arg6); - Push(a_Arg7); - Push(a_Arg8); - if (!CallFunction(3)) - { - return false; - } - GetStackValue(-3, a_Ret1); - GetStackValue(-2, a_Ret2); - GetStackValue(-1, a_Ret3); - lua_pop(m_LuaState, 3); - return true; - } - - /** Call any 9-param 5-return Lua function in a single line: */ - template< - typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, - typename ArgT6, typename ArgT7, typename ArgT8, typename ArgT9, - typename RetT1, typename RetT2, typename RetT3, typename RetT4, typename RetT5 - > - bool Call(FnT a_FnName, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_Arg3, ArgT4 a_Arg4, ArgT5 a_Arg5, ArgT6 a_Arg6, ArgT7 a_Arg7, ArgT8 a_Arg8, ArgT9 a_Arg9, const cRet & a_Mark, RetT1 & a_Ret1, RetT2 & a_Ret2, RetT3 & a_Ret3, RetT4 & a_Ret4, RetT5 & a_Ret5) - { - UNUSED(a_Mark); - if (!PushFunction(a_FnName)) - { - return false; - } - Push(a_Arg1); - Push(a_Arg2); - Push(a_Arg3); - Push(a_Arg4); - Push(a_Arg5); - Push(a_Arg6); - Push(a_Arg7); - Push(a_Arg8); - Push(a_Arg9); - if (!CallFunction(5)) - { - return false; - } - GetStackValue(-5, a_Ret1); - GetStackValue(-4, a_Ret2); - GetStackValue(-3, a_Ret3); - GetStackValue(-2, a_Ret4); - GetStackValue(-1, a_Ret5); - lua_pop(m_LuaState, 5); - return true; - } + // Include the cLuaState::Call() overload implementation that is generated by the gen_LuaState_Call.lua script: + #include "LuaState_Call.inc" /** Returns true if the specified parameters on the stack are of the specified usertable type; also logs warning if not. Used for static functions */ diff --git a/src/Bindings/LuaWindow.cpp b/src/Bindings/LuaWindow.cpp index 733304eb2..1a2582ab0 100644 --- a/src/Bindings/LuaWindow.cpp +++ b/src/Bindings/LuaWindow.cpp @@ -7,13 +7,13 @@ #include "../UI/SlotArea.h" #include "PluginLua.h" #include "../Entities/Player.h" -#include "lua/src/lauxlib.h" // Needed for LUA_REFNIL +#include "lua/src/lauxlib.h" // Needed for LUA_REFNIL -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cLuaWindow: cLuaWindow::cLuaWindow(cWindow::WindowType a_WindowType, int a_SlotsX, int a_SlotsY, const AString & a_Title) : diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index f52d970bf..530101d47 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -4,7 +4,7 @@ #include "ManualBindings.h" #undef TOLUA_TEMPLATE_BIND #include "tolua++/include/tolua++.h" - +#include "polarssl/md5.h" #include "Plugin.h" #include "PluginLua.h" #include "PluginManager.h" @@ -25,7 +25,6 @@ #include "../BlockEntities/NoteEntity.h" #include "../BlockEntities/MobHeadEntity.h" #include "../BlockEntities/FlowerPotEntity.h" -#include "md5/md5.h" #include "../LineBlockTracer.h" #include "../WorldStorage/SchematicFileSerializer.h" #include "../CompositeChat.h" @@ -34,9 +33,7 @@ -/**************************** - * Better error reporting for Lua - **/ +// Better error reporting for Lua static int tolua_do_error(lua_State* L, const char * a_pMsg, tolua_Error * a_pToLuaError) { // Retrieve current function name @@ -82,10 +79,7 @@ static int lua_do_error(lua_State* L, const char * a_pFormat, ...) -/**************************** - * Lua bound functions with special return types - **/ - +// Lua bound functions with special return types static int tolua_StringSplit(lua_State * tolua_S) { cLuaState LuaState(tolua_S); @@ -558,10 +552,12 @@ static int tolua_DoWithXYZ(lua_State* tolua_S) -template< class Ty1, - class Ty2, - bool (Ty1::*Func1)(int, int, cItemCallback<Ty2> &) > -static int tolua_ForEachInChunk(lua_State* tolua_S) +template< + class Ty1, + class Ty2, + bool (Ty1::*Func1)(int, int, cItemCallback<Ty2> &) +> +static int tolua_ForEachInChunk(lua_State * tolua_S) { int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ if ((NumArgs != 3) && (NumArgs != 4)) @@ -652,9 +648,11 @@ static int tolua_ForEachInChunk(lua_State* tolua_S) -template< class Ty1, - class Ty2, - bool (Ty1::*Func1)(cItemCallback<Ty2> &) > +template< + class Ty1, + class Ty2, + bool (Ty1::*Func1)(cItemCallback<Ty2> &) +> static int tolua_ForEach(lua_State * tolua_S) { int NumArgs = lua_gettop(tolua_S) - 1; /* This includes 'self' */ @@ -2001,9 +1999,11 @@ static int tolua_cPlugin_Call(lua_State * tolua_S) static int tolua_md5(lua_State* tolua_S) { - std::string SourceString = tolua_tostring(tolua_S, 1, 0); - std::string CryptedString = md5( SourceString ); - tolua_pushstring( tolua_S, CryptedString.c_str() ); + unsigned char Output[16]; + size_t len = 0; + const unsigned char * SourceString = (const unsigned char *)lua_tolstring(tolua_S, 1, &len); + md5(SourceString, len, Output); + lua_pushlstring(tolua_S, (const char *)Output, ARRAYCOUNT(Output)); return 1; } @@ -2064,7 +2064,7 @@ static int tolua_get_HTTPRequest_FormData(lua_State* tolua_S) { lua_pushstring(tolua_S, it->first.c_str() ); tolua_pushusertype(tolua_S, &(it->second), "HTTPFormData" ); - //lua_pushlstring(tolua_S, it->second.Value.c_str(), it->second.Value.size() ); // Might contain binary data + // lua_pushlstring(tolua_S, it->second.Value.c_str(), it->second.Value.size() ); // Might contain binary data lua_settable(tolua_S, top); } @@ -2113,7 +2113,7 @@ static int tolua_cWebPlugin_GetTabNames(lua_State * tolua_S) { const AString & FancyName = iter->first; const AString & WebName = iter->second; - tolua_pushstring( tolua_S, WebName.c_str() ); // Because the WebName is supposed to be unique, use it as key + tolua_pushstring( tolua_S, WebName.c_str() ); // Because the WebName is supposed to be unique, use it as key tolua_pushstring( tolua_S, FancyName.c_str() ); // lua_rawset(tolua_S, -3); diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index c6461c861..fc8aa1cdb 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -42,10 +42,7 @@ public: // Called each tick virtual void Tick(float a_Dt) = 0; - /** - * On all these functions, return true if you want to override default behavior and not call other plugins on that callback. - * You can also return false, so default behavior is used. - **/ + /** Calls the specified hook with the params given. Returns the bool that the hook callback returns.*/ virtual bool OnBlockSpread (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0; virtual bool OnBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; virtual bool OnChat (cPlayer * a_Player, AString & a_Message) = 0; @@ -57,13 +54,14 @@ public: virtual bool OnCollectingPickup (cPlayer * a_Player, cPickup * a_Pickup) = 0; virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0; + virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) = 0; virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) = 0; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0; virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username) = 0; virtual bool OnHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum) = 0; virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) = 0; - virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer) = 0; + virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) = 0; virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) = 0; virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) = 0; virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; @@ -72,6 +70,7 @@ public: virtual bool OnPlayerEating (cPlayer & a_Player) = 0; virtual bool OnPlayerFished (cPlayer & a_Player, const cItems & a_Reward) = 0; virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) = 0; + virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) = 0; virtual bool OnPlayerJoined (cPlayer & a_Player) = 0; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) = 0; virtual bool OnPlayerMoved (cPlayer & a_Player) = 0; @@ -150,7 +149,7 @@ private: int m_Version; AString m_Directory; -}; // tolua_export +}; // tolua_export diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 96c5ccde7..5fa8adc66 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -25,7 +25,7 @@ extern "C" -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cPluginLua: cPluginLua::cPluginLua(const AString & a_PluginDirectory) : @@ -78,7 +78,7 @@ bool cPluginLua::Initialize(void) { cCSLock Lock(m_CriticalSection); if (!m_LuaState.IsValid()) - { + { m_LuaState.Create(); m_LuaState.RegisterAPILibs(); @@ -420,6 +420,26 @@ bool cPluginLua::OnDisconnect(cClientHandle & a_Client, const AString & a_Reason +bool cPluginLua::OnEntityAddEffect(cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_ENTITY_ADD_EFFECT]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), &a_Entity, a_EffectType, a_EffectDurationTicks, a_EffectIntensity, a_DistanceModifier, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split) { cCSLock Lock(m_CriticalSection); @@ -575,14 +595,14 @@ bool cPluginLua::OnHopperPushingItem(cWorld & a_World, cHopperEntity & a_Hopper, -bool cPluginLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer) +bool cPluginLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_KILLING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), &a_Victim, a_Killer, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Victim, a_Killer, &a_TDI, cLuaState::Return, res); if (res) { return true; @@ -715,6 +735,26 @@ bool cPluginLua::OnPlayerEating(cPlayer & a_Player) +bool cPluginLua::OnPlayerFoodLevelChange(cPlayer & a_Player, int a_NewFoodLevel) +{ + cCSLock Lock(m_CriticalSection); + bool res = false; + cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_FOOD_LEVEL_CHANGE]; + for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) + { + m_LuaState.Call((int)(**itr), &a_Player, a_NewFoodLevel, cLuaState::Return, res); + if (res) + { + return true; + } + } + return false; +} + + + + + bool cPluginLua::OnPlayerFished(cPlayer & a_Player, const cItems & a_Reward) { cCSLock Lock(m_CriticalSection); @@ -975,7 +1015,7 @@ bool cPluginLua::OnPlayerUsedBlock(cPlayer & a_Player, int a_BlockX, int a_Block -bool cPluginLua::OnPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) +bool cPluginLua::OnPlayerUsedItem(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { cCSLock Lock(m_CriticalSection); bool res = false; @@ -1254,8 +1294,8 @@ bool cPluginLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI) bool cPluginLua::OnUpdatedSign( - cWorld * a_World, - int a_BlockX, int a_BlockY, int a_BlockZ, + cWorld * a_World, + int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player ) @@ -1279,8 +1319,8 @@ bool cPluginLua::OnUpdatedSign( bool cPluginLua::OnUpdatingSign( - cWorld * a_World, - int a_BlockX, int a_BlockY, int a_BlockZ, + cWorld * a_World, + int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player ) @@ -1327,18 +1367,15 @@ bool cPluginLua::OnWeatherChanging(cWorld & a_World, eWeather & a_NewWeather) { cCSLock Lock(m_CriticalSection); bool res = false; - int NewWeather = a_NewWeather; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_WEATHER_CHANGING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), &a_World, NewWeather, cLuaState::Return, res, NewWeather); + m_LuaState.Call((int)(**itr), &a_World, a_NewWeather, cLuaState::Return, res, a_NewWeather); if (res) { - a_NewWeather = (eWeather)NewWeather; return true; } } - a_NewWeather = (eWeather)NewWeather; return false; } @@ -1480,7 +1517,7 @@ bool cPluginLua::CanAddOldStyleHook(int a_HookType) return true; } - LOGWARNING("Plugin %s wants to add a hook (%d), but it doesn't provide the callback function \"%s\" for it. The plugin need not work properly.", + LOGWARNING("Plugin %s wants to add a hook (%d), but it doesn't provide the callback function \"%s\" for it. The plugin need not work properly.", GetName().c_str(), a_HookType, FnName ); m_LuaState.LogStackTrace(); @@ -1507,6 +1544,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType) case cPluginManager::HOOK_CRAFTING_NO_RECIPE: return "OnCraftingNoRecipe"; case cPluginManager::HOOK_DISCONNECT: return "OnDisconnect"; case cPluginManager::HOOK_PLAYER_ANIMATION: return "OnPlayerAnimation"; + case cPluginManager::HOOK_ENTITY_ADD_EFFECT: return "OnEntityAddEffect"; case cPluginManager::HOOK_EXECUTE_COMMAND: return "OnExecuteCommand"; case cPluginManager::HOOK_HANDSHAKE: return "OnHandshake"; case cPluginManager::HOOK_KILLING: return "OnKilling"; @@ -1632,7 +1670,7 @@ AString cPluginLua::HandleWebRequest(const HTTPRequest * a_Request ) sWebPluginTab * Tab = 0; for (TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr) { - if ((*itr)->SafeTitle.compare(SafeTabName) == 0) // This is the one! Rawr + if ((*itr)->SafeTitle.compare(SafeTabName) == 0) // This is the one! Rawr { Tab = *itr; break; @@ -1714,7 +1752,7 @@ bool cPluginLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer ASSERT(a_FnRef != LUA_REFNIL); cCSLock Lock(m_CriticalSection); - bool res; + bool res = false; m_LuaState.Call(a_FnRef, &a_Window, &a_Player, a_CanRefuse, cLuaState::Return, res); return res; } diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 598e031c0..b2979a210 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -80,13 +80,14 @@ public: virtual bool OnCollectingPickup (cPlayer * a_Player, cPickup * a_Pickup) override; virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override; + virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override; virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) override; virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; virtual bool OnExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override; virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username) override; virtual bool OnHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum) override; virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) override; - virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer) override; + virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) override; virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override; virtual bool OnPlayerAnimation (cPlayer & a_Player, int a_Animation) override; virtual bool OnPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; @@ -95,6 +96,7 @@ public: virtual bool OnPlayerEating (cPlayer & a_Player) override; virtual bool OnPlayerFished (cPlayer & a_Player, const cItems & a_Reward) override; virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) override; + virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) override; virtual bool OnPlayerJoined (cPlayer & a_Player) override; virtual bool OnPlayerMoved (cPlayer & a_Player) override; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override; @@ -143,7 +145,7 @@ public: // cWebPlugin and WebAdmin stuff virtual AString HandleWebRequest(const HTTPRequest * a_Request ) override; - bool AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference); // >> EXPORTED IN MANUALBINDINGS << + bool AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference); // >> EXPORTED IN MANUALBINDINGS << /** Binds the command to call the function specified by a Lua function reference. Simply adds to CommandMap. */ void BindCommand(const AString & a_Command, int a_FnRef); diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index c50100d6f..2c0ce701b 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -257,18 +257,44 @@ bool cPluginManager::CallHookBlockToPickups( bool cPluginManager::CallHookChat(cPlayer * a_Player, AString & a_Message) { - bool WasCommandForbidden = false; - if (HandleCommand(a_Player, a_Message, true, WasCommandForbidden)) // We use HandleCommand as opposed to ExecuteCommand to accomodate the need to the WasCommandForbidden bool + // Check if the message contains a command, execute it: + switch (HandleCommand(a_Player, a_Message, true)) { - return true; // Chat message was handled as command - } - else if (WasCommandForbidden) // Couldn't be handled as command, was it because of insufficient permissions? - { - return true; // Yes - message was sent in HandleCommand, abort + case crExecuted: + { + // The command has executed successfully + return true; + } + + case crBlocked: + { + // The command was blocked by a plugin using HOOK_EXECUTE_COMMAND + // The plugin has most likely sent a message to the player already + return true; + } + + case crError: + { + // An error in the plugin has prevented the command from executing. Report the error to the player: + a_Player->SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", a_Message.c_str())); + return true; + } + + case crNoPermission: + { + // The player is not allowed to execute this command + a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", a_Message.c_str())); + return true; + } + + case crUnknownCommand: + { + // This was not a known command, keep processing as a message + break; + } } - // Check if it was a standard command (starts with a slash) - // If it was, we know that it was completely unrecognised (WasCommandForbidden == false) + // Check if the message is a command (starts with a slash). If it is, we know that it wasn't recognised: if (!a_Message.empty() && (a_Message[0] == '/')) { AStringVector Split(StringSplit(a_Message, " ")); @@ -448,6 +474,27 @@ bool cPluginManager::CallHookDisconnect(cClientHandle & a_Client, const AString +bool cPluginManager::CallHookEntityAddEffect(cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_ENTITY_ADD_EFFECT); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnEntityAddEffect(a_Entity, a_EffectType, a_EffectDurationTicks, a_EffectIntensity, a_DistanceModifier)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookExecuteCommand(cPlayer * a_Player, const AStringVector & a_Split) { FIND_HOOK(HOOK_EXECUTE_COMMAND); @@ -562,14 +609,14 @@ bool cPluginManager::CallHookHopperPushingItem(cWorld & a_World, cHopperEntity & -bool cPluginManager::CallHookKilling(cEntity & a_Victim, cEntity * a_Killer) +bool cPluginManager::CallHookKilling(cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) { FIND_HOOK(HOOK_KILLING); VERIFY_HOOK; for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnKilling(a_Victim, a_Killer)) + if ((*itr)->OnKilling(a_Victim, a_Killer, a_TDI)) { return true; } @@ -695,6 +742,25 @@ bool cPluginManager::CallHookPlayerEating(cPlayer & a_Player) +bool cPluginManager::CallHookPlayerFoodLevelChange(cPlayer & a_Player, int a_NewFoodLevel) +{ + FIND_HOOK(HOOK_PLAYER_FOOD_LEVEL_CHANGE); + VERIFY_HOOK; + + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnPlayerFoodLevelChange(a_Player, a_NewFoodLevel)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookPlayerFished(cPlayer & a_Player, const cItems a_Reward) { FIND_HOOK(HOOK_PLAYER_FISHED); @@ -1318,28 +1384,28 @@ bool cPluginManager::CallHookWorldTick(cWorld & a_World, float a_Dt, int a_LastT -bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden) +cPluginManager::CommandResult cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) { ASSERT(a_Player != NULL); AStringVector Split(StringSplit(a_Command, " ")); if (Split.empty()) { - return false; + return crUnknownCommand; } CommandMap::iterator cmd = m_Commands.find(Split[0]); if (cmd == m_Commands.end()) { // Command not found - return false; + return crUnknownCommand; } // Ask plugins first if a command is okay to execute the command: if (CallHookExecuteCommand(a_Player, Split)) { LOGINFO("Player %s tried executing command \"%s\" that was stopped by the HOOK_EXECUTE_COMMAND hook", a_Player->GetName().c_str(), Split[0].c_str()); - return false; + return crBlocked; } if ( @@ -1348,15 +1414,18 @@ bool cPluginManager::HandleCommand(cPlayer * a_Player, const AString & a_Command !a_Player->HasPermission(cmd->second.m_Permission) ) { - a_Player->SendMessageFailure(Printf("Forbidden command; insufficient privileges: \"%s\"", Split[0].c_str())); LOGINFO("Player %s tried to execute forbidden command: \"%s\"", a_Player->GetName().c_str(), Split[0].c_str()); - a_WasCommandForbidden = true; - return false; + return crNoPermission; } ASSERT(cmd->second.m_Plugin != NULL); - return cmd->second.m_Plugin->HandleCommand(Split, a_Player); + if (!cmd->second.m_Plugin->HandleCommand(Split, a_Player)) + { + return crError; + } + + return crExecuted; } @@ -1417,7 +1486,7 @@ bool cPluginManager::DisablePlugin(const AString & a_PluginName) if (itr->first.compare(a_PluginName) == 0) // _X 2013_02_01: wtf? Isn't this supposed to be what find() does? { m_DisablePluginList.push_back(itr->second); - itr->second = NULL; // Get rid of this thing right away + itr->second = NULL; // Get rid of this thing right away return true; } return false; @@ -1554,7 +1623,7 @@ AString cPluginManager::GetCommandPermission(const AString & a_Command) -bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command) +cPluginManager::CommandResult cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Command) { return HandleCommand(a_Player, a_Command, true); } @@ -1563,7 +1632,7 @@ bool cPluginManager::ExecuteCommand(cPlayer * a_Player, const AString & a_Comman -bool cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command) +cPluginManager::CommandResult cPluginManager::ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command) { return HandleCommand(a_Player, a_Command, false); } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index be40bd2f7..cffd8d04b 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -51,14 +51,25 @@ class cBlockEntityWithItems; -class cPluginManager // tolua_export -{ // tolua_export -public: // tolua_export - +// tolua_begin +class cPluginManager +{ +public: + // tolua_end + // Called each tick virtual void Tick(float a_Dt); - + // tolua_begin + enum CommandResult + { + crExecuted, + crUnknownCommand, + crError, + crBlocked, + crNoPermission, + } ; + enum PluginHook { HOOK_BLOCK_SPREAD, @@ -73,6 +84,7 @@ public: // tolua_export HOOK_CRAFTING_NO_RECIPE, HOOK_DISCONNECT, HOOK_PLAYER_ANIMATION, + HOOK_ENTITY_ADD_EFFECT, HOOK_EXECUTE_COMMAND, HOOK_EXPLODED, HOOK_EXPLODING, @@ -87,6 +99,7 @@ public: // tolua_export HOOK_PLAYER_EATING, HOOK_PLAYER_FISHED, HOOK_PLAYER_FISHING, + HOOK_PLAYER_FOOD_LEVEL_CHANGE, HOOK_PLAYER_JOINED, HOOK_PLAYER_LEFT_CLICK, HOOK_PLAYER_MOVING, @@ -146,15 +159,17 @@ public: // tolua_export /** Returns the instance of the Plugin Manager (there is only ever one) */ - static cPluginManager * Get(void); // tolua_export + static cPluginManager * Get(void); // tolua_export typedef std::map< AString, cPlugin * > PluginMap; typedef std::list< cPlugin * > PluginList; - cPlugin * GetPlugin( const AString & a_Plugin ) const; // tolua_export - const PluginMap & GetAllPlugins() const; // >> EXPORTED IN MANUALBINDINGS << + cPlugin * GetPlugin( const AString & a_Plugin ) const; // tolua_export + const PluginMap & GetAllPlugins() const; // >> EXPORTED IN MANUALBINDINGS << - void FindPlugins(); // tolua_export - void ReloadPlugins(); // tolua_export + // tolua_begin + void FindPlugins(); + void ReloadPlugins(); + // tolua_end /** Adds the plugin to the list of plugins called for the specified hook type. Handles multiple adds as a single add */ void AddHook(cPlugin * a_Plugin, int a_HookType); @@ -173,13 +188,14 @@ public: // tolua_export bool CallHookCollectingPickup (cPlayer * a_Player, cPickup & a_Pickup); bool CallHookCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason); + bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier); bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split); // If a_Player == NULL, it is a console cmd bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookExploding (cWorld & a_World, double & a_ExplosionSize, bool & a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData); bool CallHookHandshake (cClientHandle * a_ClientHandle, const AString & a_Username); bool CallHookHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum); bool CallHookHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum); - bool CallHookKilling (cEntity & a_Victim, cEntity * a_Killer); + bool CallHookKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI); bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username); bool CallHookPlayerAnimation (cPlayer & a_Player, int a_Animation); bool CallHookPlayerBreakingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); @@ -188,6 +204,7 @@ public: // tolua_export bool CallHookPlayerEating (cPlayer & a_Player); bool CallHookPlayerFished (cPlayer & a_Player, const cItems a_Reward); bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward); + bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel); bool CallHookPlayerJoined (cPlayer & a_Player); bool CallHookPlayerMoving (cPlayer & a_Player); bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status); @@ -244,11 +261,11 @@ public: // tolua_export /** Returns the permission needed for the specified command; empty string if command not found */ AString GetCommandPermission(const AString & a_Command); // tolua_export - /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns true if executed. */ - bool ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export + /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns crExecuted if executed. */ + CommandResult ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export - /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns true if executed (false if not found) */ - bool ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export + /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns crExecuted if executed. */ + CommandResult ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export /** Removes all console command bindings that the specified plugin has made */ void RemovePluginConsoleCommands(cPlugin * a_Plugin); @@ -321,14 +338,9 @@ private: /** Adds the plugin into the internal list of plugins and initializes it. If initialization fails, the plugin is removed again. */ bool AddPlugin(cPlugin * a_Plugin); - /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns true if the command is handled. */ - bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden); - bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions) - { - bool DummyBoolean = false; - return HandleCommand(a_Player, a_Command, a_ShouldCheckPermissions, DummyBoolean); - } -} ; // tolua_export + /** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns crExecuted if the command is executed. */ + cPluginManager::CommandResult HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions); +} ; // tolua_export diff --git a/src/Bindings/WebPlugin.cpp b/src/Bindings/WebPlugin.cpp index bf45405ba..57ed9f6a4 100644 --- a/src/Bindings/WebPlugin.cpp +++ b/src/Bindings/WebPlugin.cpp @@ -64,27 +64,27 @@ std::pair< AString, AString > cWebPlugin::GetTabNameForRequest(const HTTPRequest std::pair< AString, AString > Names; AStringVector Split = StringSplit(a_Request->Path, "/"); - if( Split.size() > 1 ) + if (Split.size() > 1) { - sWebPluginTab* Tab = 0; - if( Split.size() > 2 ) // If we got the tab name, show that page + sWebPluginTab * Tab = NULL; + if (Split.size() > 2) // If we got the tab name, show that page { for( TabList::iterator itr = GetTabs().begin(); itr != GetTabs().end(); ++itr ) { - if( (*itr)->SafeTitle.compare( Split[2] ) == 0 ) // This is the one! Rawr + if ((*itr)->SafeTitle.compare(Split[2]) == 0) // This is the one! { Tab = *itr; break; } } } - else // Otherwise show the first tab + else // Otherwise show the first tab { if( GetTabs().size() > 0 ) Tab = *GetTabs().begin(); } - if( Tab ) + if (Tab != NULL) { Names.first = Tab->Title; Names.second = Tab->SafeTitle; @@ -97,13 +97,13 @@ std::pair< AString, AString > cWebPlugin::GetTabNameForRequest(const HTTPRequest -AString cWebPlugin::SafeString( const AString & a_String ) +AString cWebPlugin::SafeString(const AString & a_String) { AString RetVal; for( unsigned int i = 0; i < a_String.size(); ++i ) { char c = a_String[i]; - if( c == ' ' ) + if( c == ' ' ) { c = '_'; } @@ -111,3 +111,7 @@ AString cWebPlugin::SafeString( const AString & a_String ) } return RetVal; } + + + + diff --git a/src/Bindings/WebPlugin.h b/src/Bindings/WebPlugin.h index 22587b892..3587ac637 100644 --- a/src/Bindings/WebPlugin.h +++ b/src/Bindings/WebPlugin.h @@ -36,7 +36,7 @@ public: TabList & GetTabs() { return m_Tabs; } typedef std::list< std::pair<AString, AString> > TabNameList; - TabNameList GetTabNames(); // >> EXPORTED IN MANUALBINDINGS << + TabNameList GetTabNames(); // >> EXPORTED IN MANUALBINDINGS << std::pair< AString, AString > GetTabNameForRequest(const HTTPRequest* a_Request ); private: diff --git a/src/Bindings/gen_LuaState_Call.lua b/src/Bindings/gen_LuaState_Call.lua new file mode 100644 index 000000000..fb1797dc0 --- /dev/null +++ b/src/Bindings/gen_LuaState_Call.lua @@ -0,0 +1,196 @@ + +-- gen_LuaState_Call.lua + +-- Generates the cLuaState::Call() function templates that are included from LuaState.h + +--[[ +The cLuaState::Call() family of functions provides a template-based system for calling any Lua function +either by name or by reference with almost any number of parameters and return values. This is done by +providing a number of overloads of the same name with variable number of template-type parameters. To +separate the arguments from the return values, a special type of cLuaState::cRet is used. +--]] + + + + +print("Generating LuaState_Call.inc...") + + + + +-- List of combinations (# params, # returns) to generate: +local Combinations = +{ + -- no return values: + {0, 0}, + {1, 0}, + {2, 0}, + {3, 0}, + {4, 0}, + + -- 1 return value: + {0, 1}, + {1, 1}, + {2, 1}, + {3, 1}, + {4, 1}, + {5, 1}, + {6, 1}, + {7, 1}, + {8, 1}, + {9, 1}, + {10, 1}, + + -- 2 return values: + {0, 2}, + {1, 2}, + {2, 2}, + {3, 2}, + {4, 2}, + {5, 2}, + {6, 2}, + {7, 2}, + {8, 2}, + {9, 2}, + + -- Special combinations: + {7, 3}, + {8, 3}, + {9, 5}, +} + + + + +--- Writes a single overloaded function definition for the specified number of params and returns into f +--[[ +The format for the generated function is this: +/** Call the specified 3-param 2-return Lua function: +Returns true if call succeeded, false if there was an error. */ +template <typename FnT, typename ParamT1, typename ParamT2, typename ParamT3, typename RetT1, typename RetT2> +bool Call(FnT a_Function, ParamT1 a_Param1, ParamT2 a_Param2, ParamT3 a_Param3, const cLuaState::cRet & a_RetMark, RetT1 & a_Ret1, RetT2 & a_Ret2) +{ + UNUSED(a_RetMark); + if (!PushFunction(a_Function)) + { + return false; + } + Push(a_Param1); + Push(a_Param2); + Push(a_Param3); + if (!CallFunction(2)) + { + return false; + } + GetStackValue(-2, a_Ret1); + GetStackValue(-1, a_Ret2); + lua_pop(m_LuaState, 2); + return true; +} +Note especially the negative numbers in GetStackValue() calls. +--]] +local function WriteOverload(f, a_NumParams, a_NumReturns) + -- Write the function doxy-comments: + f:write("/** Call the specified ", a_NumParams, "-param ", a_NumReturns, "-return Lua function:\n") + f:write("Returns true if call succeeded, false if there was an error. */\n") + + -- Write the template <...> line: + f:write("template <typename FnT") + for i = 1, a_NumParams do + f:write(", typename ParamT", i) + end + if (a_NumReturns > 0) then + for i = 1, a_NumReturns do + f:write(", typename RetT", i) + end + end + f:write(">\n") + + -- Write the function signature: + f:write("bool Call(") + f:write("FnT a_Function") + for i = 1, a_NumParams do + f:write(", ParamT", i, " a_Param", i) + end + if (a_NumReturns > 0) then + f:write(", const cLuaState::cRet & a_RetMark") + for i = 1, a_NumReturns do + f:write(", RetT", i, " & a_Ret", i) + end + end + f:write(")\n") + + -- Common code: + f:write("{\n") + if (a_NumReturns > 0) then + f:write("\tUNUSED(a_RetMark);\n") + end + f:write("\tif (!PushFunction(a_Function))\n") + f:write("\t{\n") + f:write("\t\treturn false;\n") + f:write("\t}\n") + + -- Push the params: + for i = 1, a_NumParams do + f:write("\tPush(a_Param", i, ");\n") + end + + -- Call the function: + f:write("\tif (!CallFunction(", a_NumReturns, "))\n") + f:write("\t{\n") + f:write("\t\treturn false;\n") + f:write("\t}\n") + + -- Get the return values: + for i = 1, a_NumReturns do + f:write("\tGetStackValue(", -1 - a_NumReturns + i, ", a_Ret", i, ");\n") + end + + -- Pop the returns off the stack, if needed: + if (a_NumReturns > 0) then + f:write("\tlua_pop(m_LuaState, ", a_NumReturns, ");\n") + end + + -- Everything ok: + f:write("\treturn true;\n") + f:write("}\n") + + -- Separate from the next function: + f:write("\n\n\n\n\n") +end + + + + + +local f = assert(io.open("LuaState_Call.inc", "w")) + +-- Write file header: +f:write([[ +// LuaState_Call.inc + +// This file is auto-generated by gen_LuaState_Call.lua +// Make changes to the generator instead of to this file! + +// This file contains the various overloads for the cLuaState::Call() function +// Each overload handles a different number of parameters / return values +]]) +f:write("\n\n\n\n\n") + +-- Write out a template function for each overload: +for _, combination in ipairs(Combinations) do + WriteOverload(f, combination[1], combination[2]) +end + +-- Close the generated file +f:close() + + + + + +print("LuaState_Call.inc generated") + + + + diff --git a/src/Bindings/virtual_method_hooks.lua b/src/Bindings/virtual_method_hooks.lua index c610d424f..8ad30bf78 100644 --- a/src/Bindings/virtual_method_hooks.lua +++ b/src/Bindings/virtual_method_hooks.lua @@ -3,6 +3,20 @@ local disable_virtual_hooks = true local enable_pure_virtual = true local default_private_access = false + + + + +-- Code generators used by the build +-- Note that these are not exactly needed for the bindings, but rather we +-- misuse tolua's Lua engine to process files for us +dofile("gen_LuaState_Call.lua") + + + + + + local access = {public = 0, protected = 1, private = 2} function preparse_hook(p) |