From dedb414a50328bf00462409d14d8917ff24844be Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Tue, 5 Feb 2013 19:57:22 +0000 Subject: [PATCH] Added new hooks: OnChunkAvailable(), OnChunkUnloaded() and OnChunkUnloading(). Modified OnChunkGenerated() signature. http://forum.mc-server.org/showthread.php?tid=464&pid=6312#pid6312 git-svn-id: http://mc-server.googlecode.com/svn/trunk@1193 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- MCServer/Plugins/HookNotify/HookNotify.lua | 27 +++++++ source/Bindings.cpp | 63 ++++++++++++++- source/Bindings.h | 2 +- source/Chunk.cpp | 2 + source/ChunkMap.cpp | 10 ++- source/Generating/ChunkGenerator.cpp | 9 +-- source/Plugin.cpp | 44 ++++++++++- source/Plugin.h | 7 +- source/PluginManager.cpp | 73 +++++++++++++++-- source/PluginManager.h | 10 ++- source/Plugin_NewLua.cpp | 92 +++++++++++++++++++++- source/Plugin_NewLua.h | 7 +- source/Root.cpp | 5 +- source/WebAdmin.cpp | 17 ++-- 14 files changed, 337 insertions(+), 31 deletions(-) diff --git a/MCServer/Plugins/HookNotify/HookNotify.lua b/MCServer/Plugins/HookNotify/HookNotify.lua index f04dc023c..efb96fec5 100644 --- a/MCServer/Plugins/HookNotify/HookNotify.lua +++ b/MCServer/Plugins/HookNotify/HookNotify.lua @@ -15,8 +15,11 @@ function Initialize(Plugin) PluginManager = cRoot:Get():GetPluginManager() PluginManager:AddHook(Plugin, cPluginManager.HOOK_BLOCK_TO_PICKUPS); PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHAT); + PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_AVAILABLE); PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATED); PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_GENERATING); + PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_UNLOADED); + PluginManager:AddHook(Plugin, cPluginManager.HOOK_CHUNK_UNLOADING); PluginManager:AddHook(Plugin, cPluginManager.HOOK_COLLECTING_PICKUP); PluginManager:AddHook(Plugin, cPluginManager.HOOK_CRAFTING_NO_RECIPE); PluginManager:AddHook(Plugin, cPluginManager.HOOK_DISCONNECT); @@ -99,6 +102,14 @@ end +function OnChunkAvailable(...) + LogHook("OnChunkAvailable", unpack(arg)); +end + + + + + function OnChunkGenerated(...) LogHook("OnChunkGenerated", unpack(arg)); end @@ -115,6 +126,22 @@ end +function OnChunkUnloaded(...) + LogHook("OnChunkUnloaded", unpack(arg)); +end + + + + + +function OnChunkUnloading(...) + LogHook("OnChunkUnloading", unpack(arg)); +end + + + + + function OnPlayerUsingItem(...) LogHook("OnPlayerUsingItem", unpack(arg)); end diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 264c036a5..ae51e3ee8 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 02/01/13 20:11:44. +** Generated automatically by tolua++-1.0.92 on 02/05/13 19:20:01. */ #ifndef __cplusplus @@ -4246,6 +4246,34 @@ static int tolua_AllToLua_cEntity_GetClass00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: GetClassStatic of class cEntity */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetClassStatic00 +static int tolua_AllToLua_cEntity_GetClassStatic00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cEntity",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + const char* tolua_ret = (const char*) cEntity::GetClassStatic(); + tolua_pushstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetClassStatic'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetParentClass of class cEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetParentClass00 static int tolua_AllToLua_cEntity_GetParentClass00(lua_State* tolua_S) @@ -9397,6 +9425,34 @@ static int tolua_AllToLua_cServer_SendMessage00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: GetClassStatic of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetClassStatic00 +static int tolua_AllToLua_cWorld_GetClassStatic00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertable(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + { + const char* tolua_ret = (const char*) cWorld::GetClassStatic(); + tolua_pushstring(tolua_S,(const char*)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetClassStatic'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetTime of class cWorld */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_GetTime00 static int tolua_AllToLua_cWorld_GetTime00(lua_State* tolua_S) @@ -21019,6 +21075,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"IsMob",tolua_AllToLua_cEntity_IsMob00); tolua_function(tolua_S,"IsA",tolua_AllToLua_cEntity_IsA00); tolua_function(tolua_S,"GetClass",tolua_AllToLua_cEntity_GetClass00); + tolua_function(tolua_S,"GetClassStatic",tolua_AllToLua_cEntity_GetClassStatic00); tolua_function(tolua_S,"GetParentClass",tolua_AllToLua_cEntity_GetParentClass00); tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cEntity_GetWorld00); tolua_function(tolua_S,"GetPosition",tolua_AllToLua_cEntity_GetPosition00); @@ -21193,8 +21250,11 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_beginmodule(tolua_S,"cPluginManager"); tolua_constant(tolua_S,"HOOK_BLOCK_TO_PICKUPS",cPluginManager::HOOK_BLOCK_TO_PICKUPS); tolua_constant(tolua_S,"HOOK_CHAT",cPluginManager::HOOK_CHAT); + tolua_constant(tolua_S,"HOOK_CHUNK_AVAILABLE",cPluginManager::HOOK_CHUNK_AVAILABLE); tolua_constant(tolua_S,"HOOK_CHUNK_GENERATED",cPluginManager::HOOK_CHUNK_GENERATED); tolua_constant(tolua_S,"HOOK_CHUNK_GENERATING",cPluginManager::HOOK_CHUNK_GENERATING); + tolua_constant(tolua_S,"HOOK_CHUNK_UNLOADING",cPluginManager::HOOK_CHUNK_UNLOADING); + tolua_constant(tolua_S,"HOOK_CHUNK_UNLOADED",cPluginManager::HOOK_CHUNK_UNLOADED); tolua_constant(tolua_S,"HOOK_COLLECTING_PICKUP",cPluginManager::HOOK_COLLECTING_PICKUP); tolua_constant(tolua_S,"HOOK_CRAFTING_NO_RECIPE",cPluginManager::HOOK_CRAFTING_NO_RECIPE); tolua_constant(tolua_S,"HOOK_DISCONNECT",cPluginManager::HOOK_DISCONNECT); @@ -21255,6 +21315,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_endmodule(tolua_S); tolua_cclass(tolua_S,"cWorld","cWorld","",NULL); tolua_beginmodule(tolua_S,"cWorld"); + tolua_function(tolua_S,"GetClassStatic",tolua_AllToLua_cWorld_GetClassStatic00); tolua_function(tolua_S,"GetTime",tolua_AllToLua_cWorld_GetTime00); tolua_function(tolua_S,"GetWorldAge",tolua_AllToLua_cWorld_GetWorldAge00); tolua_function(tolua_S,"GetTimeOfDay",tolua_AllToLua_cWorld_GetTimeOfDay00); diff --git a/source/Bindings.h b/source/Bindings.h index 88b970a76..aea53fef4 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 02/01/13 20:11:44. +** Generated automatically by tolua++-1.0.92 on 02/05/13 19:20:02. */ /* Exported function */ diff --git a/source/Chunk.cpp b/source/Chunk.cpp index 96522d6bf..41cc0e7f6 100644 --- a/source/Chunk.cpp +++ b/source/Chunk.cpp @@ -103,6 +103,8 @@ cChunk::cChunk( cChunk::~cChunk() { + cPluginManager::Get()->CallHookChunkUnloaded(m_World, m_PosX, m_PosZ); + // LOGINFO("### delete cChunk() (%i, %i) from %p, thread 0x%x ###", m_PosX, m_PosZ, this, GetCurrentThreadId() ); for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index ede16ffa6..142a009f5 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -11,6 +11,7 @@ #include "Chunk.h" #include "Generating/Trees.h" // used in cChunkMap::ReplaceTreeBlocks() for tree block discrimination #include "BlockArea.h" +#include "PluginManager.h" #ifndef _WIN32 #include // abs @@ -711,6 +712,9 @@ void cChunkMap::SetChunkData( { Chunk->MarkDirty(); } + + // Notify plugins of the chunk becoming available + cPluginManager::Get()->CallHookChunkAvailable(m_World, a_ChunkX, a_ChunkZ); } @@ -1992,7 +1996,11 @@ void cChunkMap::cChunkLayer::UnloadUnusedChunks(void) { for (int i = 0; i < ARRAYCOUNT(m_Chunks); i++) { - if ((m_Chunks[i] != NULL) && (m_Chunks[i]->CanUnload())) + if ( + (m_Chunks[i] != NULL) && // Is valid + (m_Chunks[i]->CanUnload()) && // Can unload + !cPluginManager::Get()->CallHookChunkUnloading(m_Parent->GetWorld(), m_Chunks[i]->GetPosX(), m_Chunks[i]->GetPosZ()) // Plugins agree + ) { // The cChunk destructor calls our GetChunk() while removing its entities // so we still need to be able to return the chunk. Therefore we first delete, then NULLify diff --git a/source/Generating/ChunkGenerator.cpp b/source/Generating/ChunkGenerator.cpp index b4781fbda..70b95f0d9 100644 --- a/source/Generating/ChunkGenerator.cpp +++ b/source/Generating/ChunkGenerator.cpp @@ -273,9 +273,10 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ) cEntityList Entities; cBlockEntityList BlockEntities; - cChunkDesc LuaChunk(BlockTypes, BlockMeta, HeightMap, BiomeMap); - cRoot::Get()->GetPluginManager()->CallHookChunkGenerating(m_World, a_ChunkX, a_ChunkZ, &LuaChunk); - m_Generator->DoGenerate(a_ChunkX, a_ChunkZ, LuaChunk, Entities, BlockEntities); + cChunkDesc ChunkDesc(BlockTypes, BlockMeta, HeightMap, BiomeMap); + cRoot::Get()->GetPluginManager()->CallHookChunkGenerating(m_World, a_ChunkX, a_ChunkZ, &ChunkDesc); + m_Generator->DoGenerate(a_ChunkX, a_ChunkZ, ChunkDesc, Entities, BlockEntities); + cRoot::Get()->GetPluginManager()->CallHookChunkGenerated(m_World, a_ChunkX, a_ChunkZ, &ChunkDesc); m_World->SetChunkData( a_ChunkX, a_ChunkY, a_ChunkZ, @@ -285,8 +286,6 @@ void cChunkGenerator::DoGenerate(int a_ChunkX, int a_ChunkY, int a_ChunkZ) Entities, BlockEntities, true ); - - cRoot::Get()->GetPluginManager()->CallHookChunkGenerated(m_World, a_ChunkX, a_ChunkZ); } diff --git a/source/Plugin.cpp b/source/Plugin.cpp index 491acaa5b..736460e87 100644 --- a/source/Plugin.cpp +++ b/source/Plugin.cpp @@ -22,6 +22,7 @@ cPlugin::cPlugin( const AString & a_PluginDirectory ) cPlugin::~cPlugin() { + LOGD("Destroying plugin \"%s\".", m_Name.c_str()); } @@ -66,7 +67,7 @@ bool cPlugin::OnChat(cPlayer * a_Player, const AString & a_Message) -bool cPlugin::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +bool cPlugin::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_ChunkZ) { UNUSED(a_World); UNUSED(a_ChunkX); @@ -78,12 +79,49 @@ bool cPlugin::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ) -bool cPlugin::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_pLuaChunk) +bool cPlugin::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) +{ + UNUSED(a_World); + UNUSED(a_ChunkX); + UNUSED(a_ChunkZ); + UNUSED(a_ChunkDesc); + return false; +} + + + + + +bool cPlugin::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) +{ + UNUSED(a_World); + UNUSED(a_ChunkX); + UNUSED(a_ChunkZ); + UNUSED(a_ChunkDesc); + return false; +} + + + + + +bool cPlugin::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +{ + UNUSED(a_World); + UNUSED(a_ChunkX); + UNUSED(a_ChunkZ); + return false; +} + + + + + +bool cPlugin::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_ChunkZ) { UNUSED(a_World); UNUSED(a_ChunkX); UNUSED(a_ChunkZ); - UNUSED(a_pLuaChunk); return false; } diff --git a/source/Plugin.h b/source/Plugin.h index 51cdeab68..256e30c99 100644 --- a/source/Plugin.h +++ b/source/Plugin.h @@ -50,8 +50,11 @@ public: **/ 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); virtual bool OnChat (cPlayer * a_Player, const AString & a_Message); - virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ); - virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_pLuaChunk); + virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ); + virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc); + virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc); + virtual bool OnChunkUnloaded (cWorld * a_World, int a_ChunkX, int a_ChunkZ); + virtual bool OnChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ); virtual bool OnCollectingPickup (cPlayer * a_Player, cPickup * a_Pickup); virtual bool OnCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason); diff --git a/source/PluginManager.cpp b/source/PluginManager.cpp index f25b8ec73..8ff4f4e8f 100644 --- a/source/PluginManager.cpp +++ b/source/PluginManager.cpp @@ -233,16 +233,16 @@ bool cPluginManager::CallHookChat(cPlayer * a_Player, const AString & a_Message) -bool cPluginManager::CallHookChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +bool cPluginManager::CallHookChunkAvailable(cWorld * a_World, int a_ChunkX, int a_ChunkZ) { - HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_GENERATED); + HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_AVAILABLE); if (Plugins == m_Hooks.end()) { return false; } for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnChunkGenerated(a_World, a_ChunkX, a_ChunkZ)) + if ((*itr)->OnChunkAvailable(a_World, a_ChunkX, a_ChunkZ)) { return true; } @@ -254,7 +254,28 @@ bool cPluginManager::CallHookChunkGenerated(cWorld * a_World, int a_ChunkX, int -bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_LuaChunk) +bool cPluginManager::CallHookChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_GENERATED); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnChunkGenerated(a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc)) + { + return true; + } + } + return false; +} + + + + + +bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) { HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_GENERATING); if (Plugins == m_Hooks.end()) @@ -263,7 +284,49 @@ bool cPluginManager::CallHookChunkGenerating(cWorld * a_World, int a_ChunkX, int } for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnChunkGenerating(a_World, a_ChunkX, a_ChunkZ, a_LuaChunk)) + if ((*itr)->OnChunkGenerating(a_World, a_ChunkX, a_ChunkZ, a_ChunkDesc)) + { + return true; + } + } + return false; +} + + + + + +bool cPluginManager::CallHookChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_UNLOADED); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnChunkUnloaded(a_World, a_ChunkX, a_ChunkZ)) + { + return true; + } + } + return false; +} + + + + + +bool cPluginManager::CallHookChunkUnloading(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_CHUNK_UNLOADING); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnChunkUnloading(a_World, a_ChunkX, a_ChunkZ)) { return true; } diff --git a/source/PluginManager.h b/source/PluginManager.h index 7a52b0fc6..743d6f26a 100644 --- a/source/PluginManager.h +++ b/source/PluginManager.h @@ -41,8 +41,11 @@ public: // tolua_export { HOOK_BLOCK_TO_PICKUPS, HOOK_CHAT, + HOOK_CHUNK_AVAILABLE, HOOK_CHUNK_GENERATED, HOOK_CHUNK_GENERATING, + HOOK_CHUNK_UNLOADED, + HOOK_CHUNK_UNLOADING, HOOK_COLLECTING_PICKUP, HOOK_CRAFTING_NO_RECIPE, HOOK_DISCONNECT, @@ -101,8 +104,11 @@ public: // tolua_export bool CallHookBlockToPickups (cWorld * a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups); bool CallHookChat (cPlayer * a_Player, const AString & a_Message); - bool CallHookChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ); - bool CallHookChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_Chunk); + bool CallHookChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ); + bool CallHookChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc); + bool CallHookChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc); + bool CallHookChunkUnloaded (cWorld * a_World, int a_ChunkX, int a_ChunkZ); + bool CallHookChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ); bool CallHookCollectingPickup (cPlayer * a_Player, cPickup & a_Pickup); bool CallHookCraftingNoRecipe (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookDisconnect (cPlayer * a_Player, const AString & a_Reason); diff --git a/source/Plugin_NewLua.cpp b/source/Plugin_NewLua.cpp index ed66f1d28..d83a88f96 100644 --- a/source/Plugin_NewLua.cpp +++ b/source/Plugin_NewLua.cpp @@ -237,10 +237,10 @@ bool cPlugin_NewLua::OnChat(cPlayer * a_Player, const AString & a_Message) -bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +bool cPlugin_NewLua::OnChunkAvailable(cWorld * a_World, int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CriticalSection); - const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_GENERATED); + const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_AVAILABLE); ASSERT(FnName != NULL); if (!PushFunction(FnName)) { @@ -265,6 +265,35 @@ bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_Chun +bool cPlugin_NewLua::OnChunkGenerated(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) +{ + cCSLock Lock(m_CriticalSection); + const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_GENERATED); + ASSERT(FnName != NULL); + if (!PushFunction(FnName)) + { + return false; + } + + tolua_pushusertype(m_LuaState, a_World, "cWorld"); + tolua_pushnumber (m_LuaState, a_ChunkX); + tolua_pushnumber (m_LuaState, a_ChunkZ); + tolua_pushusertype(m_LuaState, a_ChunkDesc, "cChunkDesc"); + + if (!CallFunction(4, 1, FnName)) + { + return false; + } + + bool bRetVal = (tolua_toboolean(m_LuaState, -1, 0) > 0); + lua_pop(m_LuaState, 1); + return bRetVal; +} + + + + + bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_pLuaChunk) { cCSLock Lock(m_CriticalSection); @@ -294,6 +323,62 @@ bool cPlugin_NewLua::OnChunkGenerating(cWorld * a_World, int a_ChunkX, int a_Chu +bool cPlugin_NewLua::OnChunkUnloaded(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +{ + cCSLock Lock(m_CriticalSection); + const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_UNLOADED); + ASSERT(FnName != NULL); + if (!PushFunction(FnName)) + { + return false; + } + + tolua_pushusertype(m_LuaState, a_World, "cWorld"); + tolua_pushnumber (m_LuaState, a_ChunkX); + tolua_pushnumber (m_LuaState, a_ChunkZ); + + if (!CallFunction(3, 1, FnName)) + { + return false; + } + + bool bRetVal = (tolua_toboolean(m_LuaState, -1, 0) > 0); + lua_pop(m_LuaState, 1); + return bRetVal; +} + + + + + +bool cPlugin_NewLua::OnChunkUnloading(cWorld * a_World, int a_ChunkX, int a_ChunkZ) +{ + cCSLock Lock(m_CriticalSection); + const char * FnName = GetHookFnName(cPluginManager::HOOK_CHUNK_UNLOADING); + ASSERT(FnName != NULL); + if (!PushFunction(FnName)) + { + return false; + } + + tolua_pushusertype(m_LuaState, a_World, "cWorld"); + tolua_pushnumber (m_LuaState, a_ChunkX); + tolua_pushnumber (m_LuaState, a_ChunkZ); + + if (!CallFunction(3, 1, FnName)) + { + return false; + } + + bool bRetVal = (tolua_toboolean(m_LuaState, -1, 0) > 0); + lua_pop(m_LuaState, 1); + return bRetVal; +} + + + + + bool cPlugin_NewLua::OnCollectingPickup(cPlayer * a_Player, cPickup * a_Pickup) { cCSLock Lock(m_CriticalSection); @@ -1276,8 +1361,11 @@ const char * cPlugin_NewLua::GetHookFnName(cPluginManager::PluginHook a_Hook) { case cPluginManager::HOOK_BLOCK_TO_PICKUPS: return "OnBlockToPickups"; case cPluginManager::HOOK_CHAT: return "OnChat"; + case cPluginManager::HOOK_CHUNK_AVAILABLE: return "OnChunkAvailable"; case cPluginManager::HOOK_CHUNK_GENERATED: return "OnChunkGenerated"; case cPluginManager::HOOK_CHUNK_GENERATING: return "OnChunkGenerating"; + case cPluginManager::HOOK_CHUNK_UNLOADED: return "OnChunkUnloaded"; + case cPluginManager::HOOK_CHUNK_UNLOADING: return "OnChunkUnloading"; case cPluginManager::HOOK_COLLECTING_PICKUP: return "OnCollectingPickup"; case cPluginManager::HOOK_CRAFTING_NO_RECIPE: return "OnCraftingNoRecipe"; case cPluginManager::HOOK_DISCONNECT: return "OnDisconnect"; diff --git a/source/Plugin_NewLua.h b/source/Plugin_NewLua.h index 604bcde93..045ad9858 100644 --- a/source/Plugin_NewLua.h +++ b/source/Plugin_NewLua.h @@ -35,8 +35,11 @@ public: 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) override; virtual bool OnChat (cPlayer * a_Player, const AString & a_Message) override; - virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; - virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_pLuaChunk ) override; + virtual bool OnChunkAvailable (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; + virtual bool OnChunkGenerated (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) override; + virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cChunkDesc * a_ChunkDesc) override; + virtual bool OnChunkUnloaded (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; + virtual bool OnChunkUnloading (cWorld * a_World, int a_ChunkX, int a_ChunkZ) override; 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 (cPlayer * a_Player, const AString & a_Reason) override; diff --git a/source/Root.cpp b/source/Root.cpp index 1ec7f0e59..72003ca72 100644 --- a/source/Root.cpp +++ b/source/Root.cpp @@ -189,8 +189,6 @@ void cRoot::Start(void) StopWorlds(); LOG("Stopping authenticator..."); m_Authenticator.Stop(); - LOG("Stopping plugin manager..."); - delete m_PluginManager; m_PluginManager = 0; // This should be first #ifdef USE_SQUIRREL @@ -208,6 +206,9 @@ void cRoot::Start(void) LOG("Unloading worlds..."); UnloadWorlds(); + LOG("Stopping plugin manager..."); + delete m_PluginManager; m_PluginManager = NULL; + cItemHandler::Deinit(); cBlockHandler::Deinit(); diff --git a/source/WebAdmin.cpp b/source/WebAdmin.cpp index 2a83ac542..dd1a695ee 100644 --- a/source/WebAdmin.cpp +++ b/source/WebAdmin.cpp @@ -62,16 +62,15 @@ cWebAdmin::cWebAdmin( int a_Port /* = 8080 */ ) Init( m_Port ); } + + + + cWebAdmin::~cWebAdmin() { WebAdmin = 0; m_WebServer->Stop(); - while( m_Plugins.begin() != m_Plugins.end() ) - { - delete *m_Plugins.begin(); - //m_Plugins.remove( *m_Plugins.begin() ); - } delete m_WebServer; delete m_IniFile; @@ -79,12 +78,20 @@ cWebAdmin::~cWebAdmin() delete m_Event; } + + + + void cWebAdmin::AddPlugin( cWebPlugin * a_Plugin ) { m_Plugins.remove( a_Plugin ); m_Plugins.push_back( a_Plugin ); } + + + + void cWebAdmin::RemovePlugin( cWebPlugin * a_Plugin ) { m_Plugins.remove( a_Plugin );