mirror of
https://github.com/azerothcore/mod-ale
synced 2025-11-29 15:38:17 +08:00
Eluna rewrite file loader
This commit is contained in:
163
LuaEngine.cpp
163
LuaEngine.cpp
@@ -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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
FindClose(hFile);
|
||||
#else
|
||||
char* dir = strrchr(Dirname, '/');
|
||||
if (strcmp(Dirname, "..") == 0 || strcmp(Dirname, ".") == 0)
|
||||
return;
|
||||
// Skip the ".." and "." files.
|
||||
if (ACE::isdotdir(directory->d_name))
|
||||
continue;
|
||||
|
||||
if (dir && (strcmp(dir, "/..") == 0 || strcmp(dir, "/.") == 0 || strcmp(dir, "/.svn") == 0))
|
||||
return;
|
||||
std::string fullpath = path + "\\" + directory->d_name;
|
||||
|
||||
struct dirent** list;
|
||||
int fileCount = scandir(Dirname, &list, 0, 0);
|
||||
ACE_stat stat_buf;
|
||||
if (ACE_OS::lstat(fullpath.c_str(), &stat_buf) == -1)
|
||||
continue;
|
||||
|
||||
if (fileCount <= 0 || !list)
|
||||
return;
|
||||
|
||||
struct stat attributes;
|
||||
bool error;
|
||||
while (fileCount--)
|
||||
// load subfolder
|
||||
if ((stat_buf.st_mode & S_IFMT) == (S_IFDIR))
|
||||
{
|
||||
char _path[200];
|
||||
sprintf(_path, "%s/%s", Dirname, list[fileCount]->d_name);
|
||||
if (stat(_path, &attributes) == -1)
|
||||
{
|
||||
error = true;
|
||||
TC_LOG_ERROR("eluna", "[Eluna]: Error opening `%s`", _path);
|
||||
GetScripts(fullpath, scripts);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
error = false;
|
||||
|
||||
if (!error && S_ISDIR(attributes.st_mode))
|
||||
LoadDirectory((char*)_path, lscr);
|
||||
else
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
void Eluna::RunScripts(ScriptPaths& scripts)
|
||||
{
|
||||
char* ext = strrchr(list[fileCount]->d_name, '.');
|
||||
if (ext && !strcmp(ext, ".lua"))
|
||||
lscr->insert(_path);
|
||||
uint32 count = 0;
|
||||
for (ScriptPaths::const_iterator it = scripts.begin(); it != scripts.end(); ++it)
|
||||
{
|
||||
if (!luaL_loadfile(L, it->c_str()) && !lua_pcall(L, 0, 0, 0))
|
||||
{
|
||||
// successfully loaded and ran file
|
||||
TC_LOG_DEBUG("eluna", "[Eluna]: Successfully loaded `%s`.", it->c_str());
|
||||
++count;
|
||||
continue;
|
||||
}
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user