Eluna rewrite file loader

This commit is contained in:
Rochet2
2014-04-19 13:58:57 +03:00
committed by Foereaper
parent 6074f5cf6f
commit 3cdc08d556
2 changed files with 52 additions and 118 deletions

View File

@@ -4,16 +4,14 @@
* Please see the included DOCS/LICENSE.md for more information * Please see the included DOCS/LICENSE.md for more information
*/ */
#include <ace/Dirent.h>
#include <ace/OS_NS_sys_stat.h>
#include "LuaEngine.h" #include "LuaEngine.h"
#ifdef MANGOS #ifdef MANGOS
INSTANTIATE_SINGLETON_1(Eluna); INSTANTIATE_SINGLETON_1(Eluna);
#endif #endif
#if PLATFORM == PLATFORM_UNIX
#include <dirent.h>
#endif
extern void RegisterFunctions(lua_State* L); extern void RegisterFunctions(lua_State* L);
extern void AddElunaScripts(); extern void AddElunaScripts();
@@ -35,7 +33,7 @@ bool StartEluna()
{ {
restart = true; restart = true;
sHookMgr->OnEngineRestart(); sHookMgr->OnEngineRestart();
TC_LOG_INFO("eluna", "[Eluna]: Restarting Lua Engine"); TC_LOG_INFO("eluna", "[Eluna]: Shutting Lua Engine");
// Unregisters and stops all timed events // Unregisters and stops all timed events
sEluna->m_EventMgr.RemoveEvents(); sEluna->m_EventMgr.RemoveEvents();
@@ -70,41 +68,15 @@ bool StartEluna()
} }
#endif #endif
sEluna->L = luaL_newstate(); TC_LOG_INFO("eluna", "[Eluna]: Starting Lua Engine");
TC_LOG_INFO("eluna", "[Eluna]: Lua Engine loaded.");
LoadedScripts loadedScripts; sEluna->L = luaL_newstate();
sEluna->LoadDirectory("lua_scripts", &loadedScripts);
luaL_openlibs(sEluna->L); luaL_openlibs(sEluna->L);
RegisterFunctions(sEluna->L); RegisterFunctions(sEluna->L);
// Randomize math.random() ScriptPaths scripts;
// The macro fails on TC for unknown reason sEluna->GetScripts("lua_scripts", scripts);
// luaL_dostring(sEluna->L, "math.randomseed( tonumber(tostring(os.time()):reverse():sub(1,6)) )"); sEluna->RunScripts(scripts);
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<std::string>::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;
}
/* /*
if (restart) if (restart)
@@ -134,104 +106,65 @@ bool StartEluna()
} }
} }
*/ */
TC_LOG_INFO("eluna", "[Eluna]: Loaded %u Lua scripts..", count);
return true; return true;
} }
// Loads lua scripts from given directory // Finds lua script files from given path (including subdirectories) and pushes them to scripts
void Eluna::LoadDirectory(char* Dirname, LoadedScripts* lscr) void Eluna::GetScripts(std::string path, ScriptPaths& scripts)
{ {
#ifdef WIN32 ACE_Dirent dir;
HANDLE hFile; if (dir.open(path.c_str()) == -1)
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)
{ {
TC_LOG_ERROR("eluna", "[Eluna]: Error No `lua_scripts` directory found! Creating a 'lua_scripts' directory."); 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; return;
} }
FindNextFile(hFile, &FindData); ACE_DIRENT *directory = 0;
while (FindNextFile(hFile, &FindData)) 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); GetScripts(fullpath, scripts);
strcat(SearchName, "\\"); continue;
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);
}
} }
// 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)) void Eluna::RunScripts(ScriptPaths& scripts)
return; {
uint32 count = 0;
struct dirent** list; for (ScriptPaths::const_iterator it = scripts.begin(); it != scripts.end(); ++it)
int fileCount = scandir(Dirname, &list, 0, 0);
if (fileCount <= 0 || !list)
return;
struct stat attributes;
bool error;
while (fileCount--)
{ {
char _path[200]; if (!luaL_loadfile(L, it->c_str()) && !lua_pcall(L, 0, 0, 0))
sprintf(_path, "%s/%s", Dirname, list[fileCount]->d_name);
if (stat(_path, &attributes) == -1)
{ {
error = true; // successfully loaded and ran file
TC_LOG_ERROR("eluna", "[Eluna]: Error opening `%s`", _path); TC_LOG_DEBUG("eluna", "[Eluna]: Successfully loaded `%s`.", it->c_str());
++count;
continue;
} }
else TC_LOG_ERROR("eluna", "[Eluna]: Error loading file `%s`.", it->c_str());
error = false; report(L);
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]);
} }
free(list); TC_LOG_INFO("eluna", "[Eluna]: Loaded %u Lua scripts..", count);
#endif
} }
void Eluna::report(lua_State* L) void Eluna::report(lua_State* L)

View File

@@ -63,7 +63,7 @@ extern "C"
#include "ArenaTeam.h" #include "ArenaTeam.h"
#endif #endif
typedef std::set<std::string> LoadedScripts; typedef std::vector<std::string> ScriptPaths;
#ifdef MANGOS #ifdef MANGOS
#undef sWorld #undef sWorld
@@ -573,7 +573,8 @@ public:
void BeginCall(int fReference); void BeginCall(int fReference);
bool ExecuteCall(int params, int res); bool ExecuteCall(int params, int res);
void EndCall(int res); void EndCall(int res);
void LoadDirectory(char* directory, LoadedScripts* scr); void GetScripts(std::string path, ScriptPaths& scripts);
void RunScripts(ScriptPaths& scripts);
// Pushes // Pushes
void Push(lua_State*); // nil void Push(lua_State*); // nil