예제 #1
0
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);
}
예제 #2
0
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));
}
예제 #3
0
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();
}
예제 #4
0
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));
}
예제 #5
0
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);
}
예제 #6
0
// 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;
}
예제 #7
0
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();
}