summaryrefslogtreecommitdiffstats
path: root/src/Bindings/PluginLua.cpp
diff options
context:
space:
mode:
authorSamuel Barney <samjbarney@gmail.com>2014-01-29 21:31:15 +0100
committerSamuel Barney <samjbarney@gmail.com>2014-01-29 21:31:15 +0100
commitb35b8d1749335527a7cebea9d1034ecdd83237a5 (patch)
tree1129ab2aa2b0a86f328183fde6e9949629656b41 /src/Bindings/PluginLua.cpp
parentAdded line endings for *nix (diff)
parentMerge pull request #599 from tonibm19/master (diff)
downloadcuberite-b35b8d1749335527a7cebea9d1034ecdd83237a5.tar
cuberite-b35b8d1749335527a7cebea9d1034ecdd83237a5.tar.gz
cuberite-b35b8d1749335527a7cebea9d1034ecdd83237a5.tar.bz2
cuberite-b35b8d1749335527a7cebea9d1034ecdd83237a5.tar.lz
cuberite-b35b8d1749335527a7cebea9d1034ecdd83237a5.tar.xz
cuberite-b35b8d1749335527a7cebea9d1034ecdd83237a5.tar.zst
cuberite-b35b8d1749335527a7cebea9d1034ecdd83237a5.zip
Diffstat (limited to 'src/Bindings/PluginLua.cpp')
-rw-r--r--src/Bindings/PluginLua.cpp170
1 files changed, 162 insertions, 8 deletions
diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp
index 0e5a66cd6..7b2362887 100644
--- a/src/Bindings/PluginLua.cpp
+++ b/src/Bindings/PluginLua.cpp
@@ -88,14 +88,37 @@ bool cPluginLua::Initialize(void)
std::string PluginPath = FILE_IO_PREFIX + GetLocalFolder() + "/";
- // Load all files for this plugin, and execute them
+ // List all Lua files for this plugin. Info.lua has a special handling - make it the last to load:
AStringVector Files = cFile::GetFolderContents(PluginPath.c_str());
- for (AStringVector::const_iterator itr = Files.begin(); itr != Files.end(); ++itr)
+ AStringVector LuaFiles;
+ bool HasInfoLua = false;
+ for (AStringVector::const_iterator itr = Files.begin(), end = Files.end(); itr != end; ++itr)
{
- if (itr->rfind(".lua") == AString::npos)
+ if (itr->rfind(".lua") != AString::npos)
{
- continue;
+ if (*itr == "Info.lua")
+ {
+ HasInfoLua = true;
+ }
+ else
+ {
+ LuaFiles.push_back(*itr);
+ }
}
+ }
+ std::sort(LuaFiles.begin(), LuaFiles.end());
+
+ // Warn if there are no Lua files in the plugin folder:
+ if (LuaFiles.empty())
+ {
+ LOGWARNING("No lua files found: plugin %s is missing.", GetName().c_str());
+ Close();
+ return false;
+ }
+
+ // Load all files in the list, including the Info.lua as last, if it exists:
+ for (AStringVector::const_iterator itr = LuaFiles.begin(), end = LuaFiles.end(); itr != end; ++itr)
+ {
AString Path = PluginPath + *itr;
if (!m_LuaState.LoadFile(Path))
{
@@ -103,8 +126,17 @@ bool cPluginLua::Initialize(void)
return false;
}
} // for itr - Files[]
+ if (HasInfoLua)
+ {
+ AString Path = PluginPath + "Info.lua";
+ if (!m_LuaState.LoadFile(Path))
+ {
+ Close();
+ return false;
+ }
+ }
- // Call intialize function
+ // Call the Initialize function:
bool res = false;
if (!m_LuaState.Call("Initialize", this, cLuaState::Return, res))
{
@@ -112,7 +144,6 @@ bool cPluginLua::Initialize(void)
Close();
return false;
}
-
if (!res)
{
LOGINFO("Plugin %s: Initialize() call failed, plugin is temporarily disabled.", GetName().c_str());
@@ -423,7 +454,7 @@ bool cPluginLua::OnExploding(cWorld & a_World, double & a_ExplosionSize, bool &
{
case esOther: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize); break;
case esPrimedTNT: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (cTNTEntity *)a_SourceData, cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize); break;
- case esCreeper: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (cCreeper *)a_SourceData, cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize); break;
+ case esMonster: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (cMonster *)a_SourceData, cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize); break;
case esBed: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (Vector3i *)a_SourceData, cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize); break;
case esEnderCrystal: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, (Vector3i *)a_SourceData, cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize); break;
case esGhastFireball: m_LuaState.Call((int)(**itr), &a_World, a_ExplosionSize, a_CanCauseFire, a_X, a_Y, a_Z, a_Source, a_SourceData, cLuaState::Return, res, a_CanCauseFire, a_ExplosionSize); break;
@@ -630,6 +661,46 @@ bool cPluginLua::OnPlayerEating(cPlayer & a_Player)
+bool cPluginLua::OnPlayerFished(cPlayer & a_Player, const cItems & a_Reward)
+{
+ cCSLock Lock(m_CriticalSection);
+ bool res = false;
+ cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_FISHED];
+ for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
+ {
+ m_LuaState.Call((int)(**itr), &a_Player, a_Reward, cLuaState::Return, res);
+ if (res)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+
+bool cPluginLua::OnPlayerFishing(cPlayer & a_Player, cItems & a_Reward)
+{
+ cCSLock Lock(m_CriticalSection);
+ bool res = false;
+ cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_FISHING];
+ for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
+ {
+ m_LuaState.Call((int)(**itr), &a_Player, a_Reward, cLuaState::Return, res);
+ if (res)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+
bool cPluginLua::OnPlayerJoined(cPlayer & a_Player)
{
cCSLock Lock(m_CriticalSection);
@@ -910,6 +981,44 @@ bool cPluginLua::OnPlayerUsingItem(cPlayer & a_Player, int a_BlockX, int a_Block
+bool cPluginLua::OnPluginMessage(cClientHandle & a_Client, const AString & a_Channel, const AString & a_Message)
+{
+ cCSLock Lock(m_CriticalSection);
+ bool res = false;
+ cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLUGIN_MESSAGE];
+ for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
+ {
+ m_LuaState.Call((int)(**itr), &a_Client, a_Channel, a_Message);
+ if (res)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+
+
+bool cPluginLua::OnPluginsLoaded(void)
+{
+ cCSLock Lock(m_CriticalSection);
+ bool res = false;
+ cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLUGINS_LOADED];
+ for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
+ {
+ bool ret = false;
+ m_LuaState.Call((int)(**itr), cLuaState::Return, ret);
+ res = res || ret;
+ }
+ return res;
+}
+
+
+
+
+
bool cPluginLua::OnPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{
cCSLock Lock(m_CriticalSection);
@@ -1324,6 +1433,8 @@ const char * cPluginLua::GetHookFnName(int a_HookType)
case cPluginManager::HOOK_PLAYER_USED_ITEM: return "OnPlayerUsedItem";
case cPluginManager::HOOK_PLAYER_USING_BLOCK: return "OnPlayerUsingBlock";
case cPluginManager::HOOK_PLAYER_USING_ITEM: return "OnPlayerUsingItem";
+ case cPluginManager::HOOK_PLUGIN_MESSAGE: return "OnPluginMessage";
+ case cPluginManager::HOOK_PLUGINS_LOADED: return "OnPluginsLoaded";
case cPluginManager::HOOK_POST_CRAFTING: return "OnPostCrafting";
case cPluginManager::HOOK_PRE_CRAFTING: return "OnPreCrafting";
case cPluginManager::HOOK_SPAWNED_ENTITY: return "OnSpawnedEntity";
@@ -1337,8 +1448,17 @@ const char * cPluginLua::GetHookFnName(int a_HookType)
case cPluginManager::HOOK_WEATHER_CHANGED: return "OnWeatherChanged";
case cPluginManager::HOOK_WEATHER_CHANGING: return "OnWeatherChanging";
case cPluginManager::HOOK_WORLD_TICK: return "OnWorldTick";
- default: return NULL;
+
+ case cPluginManager::HOOK_NUM_HOOKS:
+ {
+ // Satisfy a warning that all enum values should be used in a switch
+ // but don't want a default branch, so that we catch new hooks missing from this list.
+ break;
+ }
} // switch (a_Hook)
+ LOGWARNING("Requested name of an unknown hook type function: %d (max is %d)", a_HookType, cPluginManager::HOOK_MAX);
+ ASSERT(!"Unknown hook requested!");
+ return NULL;
}
@@ -1367,6 +1487,40 @@ bool cPluginLua::AddHookRef(int a_HookType, int a_FnRefIdx)
+int cPluginLua::CallFunctionFromForeignState(
+ const AString & a_FunctionName,
+ cLuaState & a_ForeignState,
+ int a_ParamStart,
+ int a_ParamEnd
+)
+{
+ cCSLock Lock(m_CriticalSection);
+
+ // Call the function:
+ int NumReturns = m_LuaState.CallFunctionWithForeignParams(a_FunctionName, a_ForeignState, a_ParamStart, a_ParamEnd);
+ if (NumReturns < 0)
+ {
+ // The call has failed, an error has already been output to the log, so just silently bail out with the same error
+ return NumReturns;
+ }
+
+ // Copy all the return values:
+ int Top = lua_gettop(m_LuaState);
+ int res = a_ForeignState.CopyStackFrom(m_LuaState, Top - NumReturns + 1, Top);
+
+ // Remove the return values off this stack:
+ if (NumReturns > 0)
+ {
+ lua_pop(m_LuaState, NumReturns);
+ }
+
+ return res;
+}
+
+
+
+
+
AString cPluginLua::HandleWebRequest(const HTTPRequest * a_Request )
{
cCSLock Lock(m_CriticalSection);