Beispiel #1
0
void CLuaMain::InitVM()
{
    assert(!m_luaVM);

    // Create a new VM
    m_luaVM = lua_open();
    lua_pushlightuserdata(m_luaVM, m_luaVM);
    lua_setfield(m_luaVM, LUA_REGISTRYINDEX, "lua.mainstate");
    m_pLuaManager->OnLuaMainOpenVM(this, m_luaVM);

    // Set the instruction count hook
    lua_sethook(m_luaVM, InstructionCountHook, LUA_MASKCOUNT, HOOK_INSTRUCTION_COUNT);

    // Load LUA libraries
    luaL_openlibs(m_luaVM);
    /*
    luaopen_base(m_luaVM);
    luaopen_math(m_luaVM);
    luaopen_string(m_luaVM);
    luaopen_table(m_luaVM);
    luaopen_debug(m_luaVM);
    luaopen_utf8(m_luaVM);
    luaopen_os(m_luaVM);
    */

    // Initialize security restrictions. Very important to prevent lua trojans and viruses!
    //InitSecurity();

    // Registering C functions
    CLuaCFunctions::RegisterFunctionsWithVM(m_luaVM);

    // Create class metatables
    InitClasses(m_luaVM);

    // Oli: Don't forget to add new ones to CLuaManager::LoadCFunctions. Thanks!

    // create global vars
    lua_pushelement(m_luaVM, g_pGame->GetMapManager()->GetRootElement());
    lua_setglobal(m_luaVM, "root");

    lua_pushresource(m_luaVM, m_pResource);
    lua_setglobal(m_luaVM, "resource");

    lua_pushelement(m_luaVM, m_pResource->GetResourceRootElement());
    lua_setglobal(m_luaVM, "resourceRoot");

    // Load pre-loaded lua scripts
    LoadScript(EmbeddedLuaCode::exports);
    LoadScript(EmbeddedLuaCode::coroutine_debug);
    LoadScript(EmbeddedLuaCode::inspect);
}
Beispiel #2
0
void CLuaMain::InitVM ( void )
{
    assert( !m_luaVM );

    // Create a new VM
    m_luaVM = lua_open ();
    m_pLuaManager->OnLuaMainOpenVM( this, m_luaVM );

    // Set the instruction count hook
    lua_sethook ( m_luaVM, InstructionCountHook, LUA_MASKCOUNT, HOOK_INSTRUCTION_COUNT );

    // Load LUA libraries
    luaopen_base ( m_luaVM );
    luaopen_math ( m_luaVM );
    luaopen_string ( m_luaVM );
    luaopen_table ( m_luaVM );
    luaopen_debug ( m_luaVM );
    luaopen_utf8 ( m_luaVM );

    // Initialize security restrictions. Very important to prevent lua trojans and viruses!
    InitSecurity ();

    // Registering C functions
    CLuaCFunctions::RegisterFunctionsWithVM ( m_luaVM );

    // Create class metatables
    InitClasses ( m_luaVM );

    // Oli: Don't forget to add new ones to CLuaManager::LoadCFunctions. Thanks!

    // create global vars
    lua_pushelement ( m_luaVM, g_pGame->GetMapManager()->GetRootElement() );
    lua_setglobal ( m_luaVM, "root" );

    lua_pushresource ( m_luaVM, m_pResource );
    lua_setglobal ( m_luaVM, "resource" );

    lua_pushelement ( m_luaVM, m_pResource->GetResourceRootElement () );
    lua_setglobal ( m_luaVM, "resourceRoot" );

    // Load pre-loaded lua code
    LoadScript ( szPreloadedScript );
}
void CRegisteredCommands::GetCommands(lua_State* luaVM)
{
    unsigned int uiIndex = 0;

    lua_newtable(luaVM);

    for (SCommand* pCommand : m_Commands)
    {
        // Create an entry table: {'command', resource}
        lua_pushinteger(luaVM, ++uiIndex);
        lua_createtable(luaVM, 0, 2);
        {
            lua_pushstring(luaVM, pCommand->strKey.c_str());
            lua_rawseti(luaVM, -2, 1);

            lua_pushresource(luaVM, pCommand->pLuaMain->GetResource());
            lua_rawseti(luaVM, -2, 2);
        }
        lua_settable(luaVM, -3);
    }
}
Beispiel #4
0
void lua_pushuserdata ( lua_State* luaVM, void* pData )
{
    if ( CClientEntity* pEntity = UserDataCast < CClientEntity > ( ( CClientEntity* ) NULL, pData, luaVM ) )
        return lua_pushelement ( luaVM, pEntity );
    else if ( CResource* pResource = UserDataCast < CResource > ( ( CResource* ) NULL, pData, luaVM ) )
        return lua_pushresource ( luaVM, pResource );
    else if ( CXMLNode* pNode = UserDataCast < CXMLNode > ( ( CXMLNode* ) NULL, pData, luaVM ) )
        return lua_pushxmlnode ( luaVM, pNode );
    else if ( CLuaTimer* pTimer = UserDataCast < CLuaTimer > ( ( CLuaTimer* ) NULL, pData, luaVM ) )
        return lua_pushtimer ( luaVM, pTimer );
    else if ( CLuaVector2D* pVector = UserDataCast < CLuaVector2D > ( (CLuaVector2D*) NULL, pData, luaVM ) )
        return lua_pushvector ( luaVM,* pVector );
    else if ( CLuaVector3D* pVector = UserDataCast < CLuaVector3D > ( (CLuaVector3D*) NULL, pData, luaVM ) )
        return lua_pushvector ( luaVM, *pVector );
    else if ( CLuaVector4D* pVector = UserDataCast < CLuaVector4D > ( (CLuaVector4D*) NULL, pData, luaVM ) )
        return lua_pushvector ( luaVM, *pVector );
    else if ( CLuaMatrix* pMatrix = UserDataCast < CLuaMatrix > ( (CLuaMatrix*) NULL, pData, luaVM ) )
        return lua_pushmatrix ( luaVM, *pMatrix );

    lua_pushobject ( luaVM, NULL, pData );
}
Beispiel #5
0
void lua_pushuserdata ( lua_State* luaVM, void* pData )
{
    if ( CElement* pEntity = UserDataCast < CElement > ( ( CElement* ) NULL, pData, NULL ) )
        return lua_pushelement ( luaVM, pEntity );
    if ( CPlayer* pEntity = UserDataCast < CPlayer > ( ( CPlayer* ) NULL, pData, NULL ) )
        return lua_pushelement ( luaVM, pEntity );
    else if ( CResource* pResource = UserDataCast < CResource > ( ( CResource* ) NULL, pData, NULL ) )
        return lua_pushresource ( luaVM, pResource );
    else if ( CXMLNode* pNode = UserDataCast < CXMLNode > ( ( CXMLNode* ) NULL, pData, NULL ) )
        return lua_pushxmlnode ( luaVM, pNode );
    else if ( CLuaTimer* pTimer = UserDataCast < CLuaTimer > ( ( CLuaTimer* ) NULL, pData, luaVM ) )
        return lua_pushtimer ( luaVM, pTimer );
    else if ( CLuaVector2D* pVector = UserDataCast < CLuaVector2D > ( (CLuaVector2D*) NULL, pData, luaVM ) )
        return lua_pushvector ( luaVM, *pVector );
    else if ( CLuaVector3D* pVector = UserDataCast < CLuaVector3D > ( (CLuaVector3D*) NULL, pData, luaVM ) )
        return lua_pushvector ( luaVM, *pVector );
    else if ( CLuaVector4D* pVector = UserDataCast < CLuaVector4D > ( (CLuaVector4D*) NULL, pData, luaVM ) )
        return lua_pushvector ( luaVM, *pVector );
    else if ( CLuaMatrix* pMatrix = UserDataCast < CLuaMatrix > ( (CLuaMatrix*) NULL, pData, luaVM ) )
        return lua_pushmatrix ( luaVM, *pMatrix );
    else if ( CAccount* pAccount = UserDataCast < CAccount > ( (CAccount*) NULL, pData, luaVM ) )
        return lua_pushaccount ( luaVM, pAccount );
    else if ( CAccessControlList* pACL = UserDataCast < CAccessControlList > ( (CAccessControlList*) NULL, pData, luaVM ) )
        return lua_pushacl ( luaVM, pACL );
    else if ( CAccessControlListGroup* pACLGroup = UserDataCast < CAccessControlListGroup > ( (CAccessControlListGroup*) NULL, pData, luaVM ) )
        return lua_pushaclgroup ( luaVM, pACLGroup );
    else if ( CBan* pBan = UserDataCast < CBan > ( (CBan*) NULL, pData, luaVM ) )
        return lua_pushban ( luaVM, pBan );
    else if ( CTextDisplay* pTextDisplay = UserDataCast < CTextDisplay > ( (CTextDisplay*) NULL, pData, luaVM ) )
        return lua_pushtextdisplay ( luaVM, pTextDisplay );
    else if ( CTextItem* pTextItem = UserDataCast < CTextItem > ( (CTextItem*) NULL, pData, luaVM ) )
        return lua_pushtextitem ( luaVM, pTextItem );
    else if ( CDbJobData* pQuery = UserDataCast < CDbJobData > ( (CDbJobData*) NULL, pData, luaVM ) )
        return lua_pushquery ( luaVM, pQuery );

    lua_pushobject ( luaVM, NULL, pData );
}
bool CMapEventManager::Call ( const char* szName, const CLuaArguments& Arguments, class CClientEntity* pSource, class CClientEntity* pThis )
{
    // Check if no events
    if ( !m_bHasEvents )
        return false;

    // Check if no events with a name match
    EventsIterPair itPair = m_EventsMap.equal_range ( szName );
    if ( itPair.first == itPair.second )
        return false;

    TIMEUS startTimeCall = GetTimeUs ();
    SString strStatus;

    // Check for multi-threading slipups
    assert ( IsMainThread () );

    // Call all the events with matching names
    bool bCalled = false;
    bool bIsAlreadyIterating = m_bIteratingList;
    m_bIteratingList = true;

    // Copy the results into a array in case m_EventsMap is modified during the call
    std::vector< CMapEvent* > matchingEvents;
    for ( EventsIter iter = itPair.first ; iter != itPair.second ; ++iter )
        matchingEvents.push_back(iter->second);

    for ( std::vector< CMapEvent* >::iterator iter = matchingEvents.begin() ; iter != matchingEvents.end() ; ++iter )
    {
        CMapEvent* pMapEvent = *iter;

        // If it's not being destroyed
        if ( !pMapEvent->IsBeingDestroyed () )
        {
            // Compare the names
            dassert ( strcmp ( pMapEvent->GetName (), szName ) == 0 );
            {
                // Call if propagated?
                if ( pSource == pThis || pMapEvent->IsPropagated () )
                {
                    // Grab the current VM
                    lua_State* pState = pMapEvent->GetVM ()->GetVM ();

                    LUA_CHECKSTACK ( pState, 1 );   // Ensure some room

                    #if MTA_DEBUG
                        int luaStackPointer = lua_gettop ( pState );
                    #endif

                    TIMEUS startTime = GetTimeUs();

                    // Aspect ratio adjustment bodges
                    if ( pMapEvent->ShouldAllowAspectRatioAdjustment() )
                    {
                        g_bAllowAspectRatioAdjustment = true;
                        if ( pMapEvent->ShouldForceAspectRatioAdjustment() )
                            g_pCore->GetGraphics()->SetAspectRatioAdjustmentEnabled( true );
                    }

                    // Record event for the crash dump writer
                    static bool bEnabled = ( g_pCore->GetDiagnosticDebug () == EDiagnosticDebug::LUA_TRACE_0000 );
                    if ( bEnabled )
                        g_pCore->LogEvent ( 0, "Lua Event", pMapEvent->GetVM ()->GetScriptName (), szName );

                    // Store the current values of the globals
                    lua_getglobal ( pState, "source" );
                    CLuaArgument OldSource ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "this" );
                    CLuaArgument OldThis ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "sourceResource" );
                    CLuaArgument OldResource ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "sourceResourceRoot" );
                    CLuaArgument OldResourceRoot ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "eventName" );
                    CLuaArgument OldEventName ( pState, -1 );
                    lua_pop( pState, 1 );

                    // Set the "source", "this", "sourceResource" and the "sourceResourceRoot" globals on that VM
                    lua_pushelement ( pState, pSource );
                    lua_setglobal ( pState, "source" );

                    lua_pushelement ( pState, pThis );
                    lua_setglobal ( pState, "this" );

                    CLuaMain* pLuaMain = g_pClientGame->GetScriptDebugging()->GetTopLuaMain();
                    CResource* pSourceResource = pLuaMain ? pLuaMain->GetResource() : NULL;
                    if ( pSourceResource )
                    {
                        lua_pushresource ( pState, pSourceResource );
                        lua_setglobal ( pState, "sourceResource" );

                        lua_pushelement ( pState, pSourceResource->GetResourceDynamicEntity() );
                        lua_setglobal ( pState, "sourceResourceRoot" );
                    }
                    else
                    {
                        lua_pushnil ( pState );
                        lua_setglobal ( pState, "sourceResource" );

                        lua_pushnil ( pState );
                        lua_setglobal ( pState, "sourceResourceRoot" );
                    }

                    lua_pushstring ( pState, szName );
                    lua_setglobal ( pState, "eventName" );
                    
                    // Call it
                    pMapEvent->Call ( Arguments );
                    bCalled = true;

                    // Reset the globals on that VM
                    OldSource.Push ( pState );
                    lua_setglobal ( pState, "source" );

                    OldThis.Push ( pState );
                    lua_setglobal ( pState, "this" );                

                    OldResource.Push ( pState );
                    lua_setglobal ( pState, "sourceResource" );

                    OldResourceRoot.Push ( pState );
                    lua_setglobal ( pState, "sourceResourceRoot" );

                    OldEventName.Push ( pState );
                    lua_setglobal ( pState, "eventName" );

                    #if MTA_DEBUG
                        assert ( lua_gettop ( pState ) == luaStackPointer );
                    #endif

                    // Aspect ratio adjustment bodges
                    if ( pMapEvent->ShouldAllowAspectRatioAdjustment() )
                    {
                        g_pCore->GetGraphics()->SetAspectRatioAdjustmentEnabled( false );
                        g_bAllowAspectRatioAdjustment = false;
                    }

                    TIMEUS deltaTimeUs = GetTimeUs() - startTime;

                    if ( deltaTimeUs > 3000 ) 
                        if ( IS_TIMING_CHECKPOINTS() )
                            strStatus += SString ( " (%s %d ms)", pMapEvent->GetVM ()->GetScriptName (), deltaTimeUs / 1000 );

                    CClientPerfStatLuaTiming::GetSingleton ()->UpdateLuaTiming ( pMapEvent->GetVM (), szName, deltaTimeUs );
                }
            }
        }
    }

    // Clean out the trash if we're no longer calling events.
    if ( !bIsAlreadyIterating )
    {
        TakeOutTheTrash ();

        // We're no longer iterating the list
        m_bIteratingList = false;
    }

    if ( IS_TIMING_CHECKPOINTS() )
    {
        TIMEUS deltaTimeUs = GetTimeUs() - startTimeCall;
        if ( deltaTimeUs > 5000 )
            TIMING_DETAIL( SString ( "CMapEventManager::Call ( %s, ... ) took %d ms ( %s )", szName, deltaTimeUs / 1000, *strStatus ) );
    }

    // Return whether we called atleast one func or not
    return bCalled;
}