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
*/
#include <ace/Dirent.h>
#include <ace/OS_NS_sys_stat.h>
#include "LuaEngine.h"
#ifdef MANGOS
INSTANTIATE_SINGLETON_1(Eluna);
#endif
#if PLATFORM == PLATFORM_UNIX
#include <dirent.h>
#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<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;
}
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)

View File

@@ -63,7 +63,7 @@ extern "C"
#include "ArenaTeam.h"
#endif
typedef std::set<std::string> LoadedScripts;
typedef std::vector<std::string> 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