void Eluna::RunScripts(ScriptPaths& scripts) { uint32 count = 0; // load last first to load extensions first for (ScriptPaths::const_reverse_iterator it = scripts.rbegin(); it != scripts.rend(); ++it) { if (!luaL_loadfile(L, it->c_str()) && !lua_pcall(L, 0, 0, 0)) { // successfully loaded and ran file ELUNA_LOG_DEBUG("[Eluna]: Successfully loaded `%s`", it->c_str()); ++count; continue; } ELUNA_LOG_ERROR("[Eluna]: Error loading file `%s`", it->c_str()); report(L); } ELUNA_LOG_INFO("[Eluna]: Loaded %u Lua scripts", count); }
void Eluna::RunScripts() { uint32 oldMSTime = GetCurrTime(); uint32 count = 0; ScriptList scripts; scripts.insert(scripts.end(), lua_extensions.begin(), lua_extensions.end()); scripts.insert(scripts.end(), lua_scripts.begin(), lua_scripts.end()); lua_getglobal(L, "package"); luaL_getsubtable(L, -1, "loaded"); int modules = lua_gettop(L); for (ScriptList::const_iterator it = scripts.begin(); it != scripts.end(); ++it) { lua_getfield(L, modules, it->modulepath.c_str()); if (!lua_isnoneornil(L, -1)) { lua_pop(L, 1); ELUNA_LOG_DEBUG("[Eluna]: Extension was already loaded or required `%s`", it->filepath.c_str()); continue; } lua_pop(L, 1); if (!luaL_loadfile(L, it->filepath.c_str()) && !lua_pcall(L, 0, 1, 0)) { if (!lua_toboolean(L, -1)) { lua_pop(L, 1); Push(L, true); } lua_setfield(L, modules, it->modulepath.c_str()); // successfully loaded and ran file ELUNA_LOG_DEBUG("[Eluna]: Successfully loaded `%s`", it->filepath.c_str()); ++count; continue; } ELUNA_LOG_ERROR("[Eluna]: Error loading extension `%s`", it->filepath.c_str()); report(L); } lua_pop(L, 2); ELUNA_LOG_INFO("[Eluna]: Executed %u Lua scripts in %u ms", count, GetTimeDiff(oldMSTime)); }
void Eluna::Initialize() { uint32 oldMSTime = GetCurrTime(); lua_scripts.clear(); lua_extensions.clear(); lua_folderpath = eConfigMgr->GetStringDefault("Eluna.ScriptPath", "lua_scripts"); #if PLATFORM == PLATFORM_UNIX || PLATFORM == PLATFORM_APPLE if (lua_folderpath[0] == '~') if (const char* home = getenv("HOME")) lua_folderpath.replace(0, 1, home); #endif ELUNA_LOG_INFO("[Eluna]: Searching scripts from `%s`", lua_folderpath.c_str()); GetScripts(lua_folderpath + "/extensions", lua_extensions); GetScripts(lua_folderpath, lua_scripts); ELUNA_LOG_DEBUG("[Eluna]: Loaded %u scripts in %u ms", uint32(lua_scripts.size()), GetTimeDiff(oldMSTime)); // Create global eluna new Eluna(); }
void Eluna::LoadScriptPaths() { uint32 oldMSTime = ElunaUtil::GetCurrTime(); lua_scripts.clear(); lua_extensions.clear(); lua_folderpath = eConfigMgr->GetStringDefault("Eluna.ScriptPath", "lua_scripts"); #if PLATFORM == PLATFORM_UNIX || PLATFORM == PLATFORM_APPLE if (lua_folderpath[0] == '~') if (const char* home = getenv("HOME")) lua_folderpath.replace(0, 1, home); #endif ELUNA_LOG_INFO("[Eluna]: Searching scripts from `%s`", lua_folderpath.c_str()); lua_requirepath.clear(); GetScripts(lua_folderpath); // Erase last ; if (!lua_requirepath.empty()) lua_requirepath.erase(lua_requirepath.end() - 1); ELUNA_LOG_DEBUG("[Eluna]: Loaded %u scripts in %u ms", uint32(lua_scripts.size() + lua_extensions.size()), ElunaUtil::GetTimeDiff(oldMSTime)); }
void Eluna::OpenLua() { enabled = eConfigMgr->GetBoolDefault("Eluna.Enabled", true); if (!IsEnabled()) { ELUNA_LOG_INFO("[Eluna]: Eluna is disabled in config"); return; } L = luaL_newstate(); CreateBindStores(); // open base lua libraries luaL_openlibs(L); // open additional lua libraries // Register methods and functions RegisterFunctions(this); // Create hidden table with weak values lua_newtable(L); lua_newtable(L); lua_pushstring(L, "v"); lua_setfield(L, -2, "__mode"); lua_setmetatable(L, -2); lua_setfield(L, LUA_REGISTRYINDEX, ELUNA_OBJECT_STORE); // Set lua require folder paths (scripts folder structure) lua_getglobal(L, "package"); lua_pushstring(L, lua_requirepath.c_str()); lua_setfield(L, -2, "path"); lua_pushstring(L, ""); // erase cpath lua_setfield(L, -2, "cpath"); lua_pop(L, 1); }
// Start or restart eluna. Returns true if started bool StartEluna() { #ifndef ELUNA #ifndef MANGOS { ELUNA_LOG_ERROR("[Eluna]: LuaEngine is Disabled. (If you want to use it please enable in cmake)"); return false; } #endif #endif ELUNA_GUARD(); bool restart = false; if (sEluna->L) { restart = true; sHookMgr->OnEngineRestart(); ELUNA_LOG_INFO("[Eluna]: Stopping Lua Engine"); // Unregisters and stops all timed events sEluna->m_EventMgr.RemoveEvents(); // Remove bindings sEluna->PacketEventBindings.Clear(); sEluna->ServerEventBindings.Clear(); sEluna->PlayerEventBindings.Clear(); sEluna->GuildEventBindings.Clear(); sEluna->GroupEventBindings.Clear(); sEluna->CreatureEventBindings.Clear(); sEluna->CreatureGossipBindings.Clear(); sEluna->GameObjectEventBindings.Clear(); sEluna->GameObjectGossipBindings.Clear(); sEluna->ItemEventBindings.Clear(); sEluna->ItemGossipBindings.Clear(); sEluna->playerGossipBindings.Clear(); sEluna->VehicleEventBindings.Clear(); lua_close(sEluna->L); } else AddElunaScripts(); #ifdef MANGOS // Check config file for eluna is enabled or disabled if (!sWorld->getConfig(CONFIG_BOOL_ELUNA_ENABLED)) { ELUNA_LOG_ERROR("[Eluna]: LuaEngine is Disabled. (If you want to use it please set config in 'mangosd.conf')"); return false; } #endif ELUNA_LOG_INFO("[Eluna]: Starting Lua Engine"); sEluna->L = luaL_newstate(); luaL_openlibs(sEluna->L); RegisterFunctions(sEluna->L); // Create hidden table with weak values lua_newtable(sEluna->L); lua_newtable(sEluna->L); lua_pushstring(sEluna->L, "v"); lua_setfield(sEluna->L, -2, "__mode"); lua_setmetatable(sEluna->L, -2); sHookMgr->userdata_table = luaL_ref(sEluna->L, LUA_REGISTRYINDEX); ScriptPaths scripts; std::string folderpath = sConfigMgr->GetStringDefault("Eluna.ScriptPath", "lua_scripts"); #if PLATFORM == PLATFORM_UNIX || PLATFORM == PLATFORM_APPLE if (folderpath[0] == '~') if (const char* home = getenv("HOME")) folderpath.replace(0, 1, home); #endif ELUNA_LOG_INFO("[Eluna]: Searching scripts from `%s`", folderpath.c_str()); sEluna->GetScripts(folderpath, scripts); sEluna->GetScripts(folderpath + "/extensions", scripts); sEluna->RunScripts(scripts); /* if (restart) { //! Iterate over every supported source type (creature and gameobject) //! Not entirely sure how this will affect units in non-loaded grids. { HashMapHolder<Creature>::ReadGuard g(HashMapHolder<Creature>::GetLock()); HashMapHolder<Creature>::MapType& m = HashMapHolder<Creature>::GetContainer(); for (HashMapHolder<Creature>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) { if (itr->second->IsInWorld()) // must check? // if(sEluna->CreatureEventBindings->GetBindMap(iter->second->GetEntry())) // update all AI or just Eluna? itr->second->AIM_Initialize(); } } { HashMapHolder<GameObject>::ReadGuard g(HashMapHolder<GameObject>::GetLock()); HashMapHolder<GameObject>::MapType& m = HashMapHolder<GameObject>::GetContainer(); for (HashMapHolder<GameObject>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) { if (itr->second->IsInWorld()) // must check? // if(sEluna->GameObjectEventBindings->GetBindMap(iter->second->GetEntry())) // update all AI or just Eluna? itr->second->AIM_Initialize(); } } } */ return true; }
void Eluna::RunScripts() { LOCK_ELUNA; if (!IsEnabled()) return; uint32 oldMSTime = ElunaUtil::GetCurrTime(); uint32 count = 0; ScriptList scripts; lua_extensions.sort(ScriptPathComparator); lua_scripts.sort(ScriptPathComparator); scripts.insert(scripts.end(), lua_extensions.begin(), lua_extensions.end()); scripts.insert(scripts.end(), lua_scripts.begin(), lua_scripts.end()); std::unordered_map<std::string, std::string> loaded; // filename, path lua_getglobal(L, "package"); // Stack: package luaL_getsubtable(L, -1, "loaded"); // Stack: package, modules int modules = lua_gettop(L); for (ScriptList::const_iterator it = scripts.begin(); it != scripts.end(); ++it) { // Check that no duplicate names exist if (loaded.find(it->filename) != loaded.end()) { ELUNA_LOG_ERROR("[Eluna]: Error loading `%s`. File with same name already loaded from `%s`, rename either file", it->filepath.c_str(), loaded[it->filename].c_str()); continue; } loaded[it->filename] = it->filepath; lua_getfield(L, modules, it->filename.c_str()); // Stack: package, modules, module if (!lua_isnoneornil(L, -1)) { lua_pop(L, 1); ELUNA_LOG_DEBUG("[Eluna]: `%s` was already loaded or required", it->filepath.c_str()); continue; } lua_pop(L, 1); // Stack: package, modules if (luaL_loadfile(L, it->filepath.c_str())) { // Stack: package, modules, errmsg ELUNA_LOG_ERROR("[Eluna]: Error loading `%s`", it->filepath.c_str()); Report(L); // Stack: package, modules continue; } // Stack: package, modules, filefunc if (ExecuteCall(0, 1)) { // Stack: package, modules, result if (lua_isnoneornil(L, -1) || (lua_isboolean(L, -1) && !lua_toboolean(L, -1))) { // if result evaluates to false, change it to true lua_pop(L, 1); Push(L, true); } lua_setfield(L, modules, it->filename.c_str()); // Stack: package, modules // successfully loaded and ran file ELUNA_LOG_DEBUG("[Eluna]: Successfully loaded `%s`", it->filepath.c_str()); ++count; continue; } } // Stack: package, modules lua_pop(L, 2); ELUNA_LOG_INFO("[Eluna]: Executed %u Lua scripts in %u ms", count, ElunaUtil::GetTimeDiff(oldMSTime)); OnLuaStateOpen(); }