From 3cdc08d55623f472e0f69b18f1cda56043267dc2 Mon Sep 17 00:00:00 2001 From: Rochet2 Date: Sat, 19 Apr 2014 13:58:57 +0300 Subject: [PATCH] Eluna rewrite file loader --- LuaEngine.cpp | 165 +++++++++++++++----------------------------------- LuaEngine.h | 5 +- 2 files changed, 52 insertions(+), 118 deletions(-) diff --git a/LuaEngine.cpp b/LuaEngine.cpp index 2476655..7ff04fd 100644 --- a/LuaEngine.cpp +++ b/LuaEngine.cpp @@ -4,16 +4,14 @@ * Please see the included DOCS/LICENSE.md for more information */ +#include +#include #include "LuaEngine.h" #ifdef MANGOS INSTANTIATE_SINGLETON_1(Eluna); #endif -#if PLATFORM == PLATFORM_UNIX -#include -#endif - extern void RegisterFunctions(lua_State* L); extern void AddElunaScripts(); @@ -35,7 +33,7 @@ bool StartEluna() { restart = true; sHookMgr->OnEngineRestart(); - TC_LOG_INFO("eluna", "[Eluna]: Restarting Lua Engine"); + TC_LOG_INFO("eluna", "[Eluna]: Shutting Lua Engine"); // Unregisters and stops all timed events sEluna->m_EventMgr.RemoveEvents(); @@ -70,41 +68,15 @@ bool StartEluna() } #endif - sEluna->L = luaL_newstate(); - TC_LOG_INFO("eluna", "[Eluna]: Lua Engine loaded."); + TC_LOG_INFO("eluna", "[Eluna]: Starting Lua Engine"); - LoadedScripts loadedScripts; - sEluna->LoadDirectory("lua_scripts", &loadedScripts); + sEluna->L = luaL_newstate(); luaL_openlibs(sEluna->L); RegisterFunctions(sEluna->L); - // Randomize math.random() - // The macro fails on TC for unknown reason - // luaL_dostring(sEluna->L, "math.randomseed( tonumber(tostring(os.time()):reverse():sub(1,6)) )"); - if (!luaL_loadstring(sEluna->L, "math.randomseed( tonumber(tostring(os.time()):reverse():sub(1,6)) )")) - lua_pcall(sEluna->L, 0, LUA_MULTRET, 0); - - uint32 count = 0; - char filename[200]; - for (std::set::const_iterator itr = loadedScripts.begin(); itr != loadedScripts.end(); ++itr) - { - strcpy(filename, itr->c_str()); - if (luaL_loadfile(sEluna->L, filename) != 0) - { - TC_LOG_ERROR("eluna", "[Eluna]: Error loading file `%s`.", itr->c_str()); - sEluna->report(sEluna->L); - } - else - { - int err = lua_pcall(sEluna->L, 0, 0, 0); - if (err != 0 && err == LUA_ERRRUN) - { - TC_LOG_ERROR("eluna", "[Eluna]: Error loading file `%s`.", itr->c_str()); - sEluna->report(sEluna->L); - } - } - ++count; - } + ScriptPaths scripts; + sEluna->GetScripts("lua_scripts", scripts); + sEluna->RunScripts(scripts); /* if (restart) @@ -134,104 +106,65 @@ bool StartEluna() } } */ - - TC_LOG_INFO("eluna", "[Eluna]: Loaded %u Lua scripts..", count); return true; } -// Loads lua scripts from given directory -void Eluna::LoadDirectory(char* Dirname, LoadedScripts* lscr) +// Finds lua script files from given path (including subdirectories) and pushes them to scripts +void Eluna::GetScripts(std::string path, ScriptPaths& scripts) { -#ifdef WIN32 - HANDLE hFile; - WIN32_FIND_DATA FindData; - memset(&FindData, 0, sizeof(FindData)); - char SearchName[MAX_PATH]; - - strcpy(SearchName, Dirname); - strcat(SearchName, "\\*.*"); - - hFile = FindFirstFile(SearchName, &FindData); - if (hFile == INVALID_HANDLE_VALUE) + ACE_Dirent dir; + if (dir.open(path.c_str()) == -1) { TC_LOG_ERROR("eluna", "[Eluna]: Error No `lua_scripts` directory found! Creating a 'lua_scripts' directory."); - CreateDirectory("lua_scripts", NULL); + ACE_OS::mkdir("lua_scripts"); return; } - FindNextFile(hFile, &FindData); - while (FindNextFile(hFile, &FindData)) + ACE_DIRENT *directory = 0; + while (directory = dir.read()) { - if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + // Skip the ".." and "." files. + if (ACE::isdotdir(directory->d_name)) + continue; + + std::string fullpath = path + "\\" + directory->d_name; + + ACE_stat stat_buf; + if (ACE_OS::lstat(fullpath.c_str(), &stat_buf) == -1) + continue; + + // load subfolder + if ((stat_buf.st_mode & S_IFMT) == (S_IFDIR)) { - strcpy(SearchName, Dirname); - strcat(SearchName, "\\"); - strcat(SearchName, FindData.cFileName); - LoadDirectory(SearchName, lscr); - } - else - { - std::string fname = Dirname; - fname += "\\"; - fname += FindData.cFileName; - size_t len = strlen(fname.c_str()); - int i = 0; - char ext[MAX_PATH]; - while (len > 0) - { - ext[i++] = fname[--len]; - if (fname[len] == '.') - break; - } - ext[i++] = '\0'; - if (!_stricmp(ext, "aul.")) - { - TC_LOG_DEBUG("eluna", "[Eluna]: Load File: %s", fname.c_str()); - lscr->insert(fname); - } + GetScripts(fullpath, scripts); + continue; } + + // was file, check extension + if (fullpath.substr(fullpath.length() - 4, 4) != ".lua") + continue; + + // was correct, add path to scripts to load + scripts.push_back(fullpath); } - FindClose(hFile); -#else - char* dir = strrchr(Dirname, '/'); - if (strcmp(Dirname, "..") == 0 || strcmp(Dirname, ".") == 0) - return; +} - if (dir && (strcmp(dir, "/..") == 0 || strcmp(dir, "/.") == 0 || strcmp(dir, "/.svn") == 0)) - return; - - struct dirent** list; - int fileCount = scandir(Dirname, &list, 0, 0); - - if (fileCount <= 0 || !list) - return; - - struct stat attributes; - bool error; - while (fileCount--) +void Eluna::RunScripts(ScriptPaths& scripts) +{ + uint32 count = 0; + for (ScriptPaths::const_iterator it = scripts.begin(); it != scripts.end(); ++it) { - char _path[200]; - sprintf(_path, "%s/%s", Dirname, list[fileCount]->d_name); - if (stat(_path, &attributes) == -1) + if (!luaL_loadfile(L, it->c_str()) && !lua_pcall(L, 0, 0, 0)) { - error = true; - TC_LOG_ERROR("eluna", "[Eluna]: Error opening `%s`", _path); + // successfully loaded and ran file + TC_LOG_DEBUG("eluna", "[Eluna]: Successfully loaded `%s`.", it->c_str()); + ++count; + continue; } - else - error = false; - - if (!error && S_ISDIR(attributes.st_mode)) - LoadDirectory((char*)_path, lscr); - else - { - char* ext = strrchr(list[fileCount]->d_name, '.'); - if (ext && !strcmp(ext, ".lua")) - lscr->insert(_path); - } - free(list[fileCount]); + TC_LOG_ERROR("eluna", "[Eluna]: Error loading file `%s`.", it->c_str()); + report(L); } - free(list); -#endif + TC_LOG_INFO("eluna", "[Eluna]: Loaded %u Lua scripts..", count); } void Eluna::report(lua_State* L) diff --git a/LuaEngine.h b/LuaEngine.h index 8191de3..277849c 100644 --- a/LuaEngine.h +++ b/LuaEngine.h @@ -63,7 +63,7 @@ extern "C" #include "ArenaTeam.h" #endif -typedef std::set LoadedScripts; +typedef std::vector ScriptPaths; #ifdef MANGOS #undef sWorld @@ -573,7 +573,8 @@ public: void BeginCall(int fReference); bool ExecuteCall(int params, int res); void EndCall(int res); - void LoadDirectory(char* directory, LoadedScripts* scr); + void GetScripts(std::string path, ScriptPaths& scripts); + void RunScripts(ScriptPaths& scripts); // Pushes void Push(lua_State*); // nil