Beispiel #1
0
void lua_classfunction ( lua_State* luaVM, const char* szFunction, const char* fn )
{
    CLuaCFunction* pFunction = CLuaCFunctions::GetFunction ( fn );
    if ( pFunction )
    {
        lua_classfunction ( luaVM, szFunction, pFunction->GetFunctionAddress () );
    }
}
void lua_classfunction ( lua_State* luaVM, const char* szFunction, const char* fn )
{
    CLuaCFunction* pFunction = CLuaCFunctions::GetFunction ( fn );
    if ( pFunction )
    {
        lua_classfunction ( luaVM, szFunction, pFunction->GetFunctionAddress () );
    }
    else
        dassert ( "lua_classfunction function does not exist" && 0 );
}
Beispiel #3
0
int CLuaDefs::CanUseFunction ( lua_CFunction f, lua_State* luaVM )
{
    // Grab the function name we're calling. If it's one of our functions, see if we can use it.
    std::string strFunction;
    CLuaCFunction* pFunction = CLuaCFunctions::GetFunction ( f );
    if ( pFunction )
    {
        return static_cast < bool > ( CLuaDefs::CanUseFunction (
            pFunction->GetName ().c_str (), luaVM, pFunction->IsRestricted () ) );
    }

    // It's one of lua's functions, allow this
    return true;
}
Beispiel #4
0
void lua_classfunction ( lua_State* luaVM, const char* szFunction, const char* szOriginal )
{
    CLuaCFunction* pFunction = CLuaCFunctions::GetFunction ( szOriginal );
    if ( pFunction )
    {
        lua_pushstring ( luaVM, "__class" );
        lua_rawget ( luaVM, -2 );

        lua_pushstring ( luaVM, szFunction );
        lua_pushstring ( luaVM, szFunction );
        lua_pushcclosure ( luaVM, pFunction->GetAddress (), 1 );
        lua_rawset ( luaVM, -3 );

        lua_pop ( luaVM, 1 );
    }
}
Beispiel #5
0
void lua_classvariable ( lua_State* luaVM, const char* szVariable, const char* set, const char* get )
{
    // Set
    lua_pushstring ( luaVM, "__set" );
    lua_rawget ( luaVM, -2 );

    CLuaCFunction* pSet = NULL;
    CLuaCFunction* pGet = NULL;

    if ( ( !set ) || ! ( pSet = CLuaCFunctions::GetFunction ( set ) ) )
    {
        lua_pushstring ( luaVM, szVariable );
        lua_pushstring ( luaVM, szVariable );
        lua_pushcclosure ( luaVM, CLuaClassDefs::ReadOnly, 1 );
        lua_rawset ( luaVM, -3 );
    }
    else
    {
        lua_pushstring ( luaVM, szVariable );
        lua_pushstring ( luaVM, szVariable );
        lua_pushcclosure ( luaVM, pSet->GetAddress (), 1 );
        lua_rawset ( luaVM, -3 );
    }
    lua_pop ( luaVM, 1 );

    // Get
    lua_pushstring ( luaVM, "__get" );
    lua_rawget ( luaVM, -2 );

    if ( ( !get ) || ! ( pGet = CLuaCFunctions::GetFunction ( get ) ) )
    {
        lua_pushstring ( luaVM, szVariable );
        lua_pushstring ( luaVM, szVariable );
        lua_pushcclosure ( luaVM, CLuaClassDefs::WriteOnly, 1 );
        lua_rawset ( luaVM, -3 );
    }
    else
    {
        lua_pushstring ( luaVM, szVariable );
        lua_pushstring ( luaVM, szVariable );
        lua_pushcclosure ( luaVM, pGet->GetAddress (), 1 );
        lua_rawset ( luaVM, -3 );
    }
    lua_pop ( luaVM, 1 );
}
Beispiel #6
0
//
// Called after a Lua function if post call hook has been installed
//
void CLuaDefs::DidUseFunction ( lua_CFunction f, lua_State* luaVM )
{
    // Quick cull of unknown pointer range - Deals with calls from client dll (when the server has been loaded into the same process)
    if ( CLuaCFunctions::IsNotFunction( f ) )
        return;

    if ( !ms_TimingFunctionStack.empty () )
    {
        // Check if the function used was being timed
        const STimingFunction& info = ms_TimingFunctionStack.back ();
        if ( info.f == f )
        {
            // Finish the timing
            TIMEUS elapsedTime = GetTimeUs() - info.startTime;
            uint uiDeltaBytes = g_uiNetSentByteCounter - info.uiStartByteCount;
            // Record timing over a threshold
            if ( elapsedTime >= CPerfStatFunctionTiming::ms_PeakUsThresh || uiDeltaBytes > 1000 )
            {
                CLuaCFunction* pFunction = CLuaCFunctions::GetFunction ( info.f );
                if ( pFunction )
                {
                    CResource* pResource = g_pGame->GetResourceManager ()->GetResourceFromLuaState ( info.luaVM );
                    SString strResourceName = pResource ? pResource->GetName() : "unknown";
                    CPerfStatFunctionTiming::GetSingleton ()->UpdateTiming ( strResourceName, pFunction->GetName ().c_str (), elapsedTime, uiDeltaBytes );
                }
            }

            ms_TimingFunctionStack.pop_back ();
        }
    }

    // Check if we should remove the hook
    if ( !g_pStats->bFunctionTimingActive && !g_pGame->GetDebugHookManager()->HasPostFunctionHooks() )
    {
        ms_TimingFunctionStack.clear ();
        OutputDebugLine ( "[Lua] Removing PostCallHook" );
        assert ( ms_bRegisterdPostCallHook );
        ms_bRegisterdPostCallHook = false;
        lua_registerPostCallHook ( NULL );
    }

    g_pGame->GetDebugHookManager()->OnPostFunction( f, luaVM );
}
Beispiel #7
0
int CLuaDefs::CanUseFunction ( lua_CFunction f, lua_State* luaVM )
{
    // Quick cull of unknown pointer range
    if ( CLuaCFunctions::IsNotFunction( f ) )
        return true;

    // Get associated resource
    CResource* pResource = m_pResourceManager->GetResourceFromLuaState( luaVM );
    if ( !pResource )
        return true;

    // Update execution time check
    pResource->GetVirtualMachine()->CheckExecutionTime();

    // Check function right cache in resource
    bool bAllowed;
    if ( pResource->CheckFunctionRightCache( f, &bAllowed ) )
    {
        // If in cache, and not allowed, do warning here
        if ( !bAllowed )
            m_pScriptDebugging->LogBadAccess ( luaVM );
    }
    else
    {
        // If not in cache, do full check
        bAllowed = true;

        // Grab the function name we're calling. If it's one of our functions, see if we can use it.
        CLuaCFunction* pFunction = CLuaCFunctions::GetFunction ( f );
        dassert( pFunction );
        if ( pFunction )
        {
            // If it's not one of lua's functions, see if we allow it
            bAllowed = CLuaDefs::CanUseFunction ( pFunction->GetName ().c_str (), luaVM/*, pResource*/, pFunction->IsRestricted () );
        }

        // Update cache in resource
        pResource->UpdateFunctionRightCache( f, bAllowed );
    }

    g_pGame->GetDebugHookManager()->OnPreFunction( f, luaVM, bAllowed );

    // If not allowed, do no more
    if ( !bAllowed )
        return false;

    // Check if function timing is active
    if ( g_pStats->bFunctionTimingActive || g_pGame->GetDebugHookManager()->HasPostFunctionHooks() )
    {
        // Check if hook needs applying
        if ( !ms_bRegisterdPostCallHook )
        {
            OutputDebugLine ( "[Lua] Registering PostCallHook" );
            ms_bRegisterdPostCallHook = true;
            lua_registerPostCallHook ( CLuaDefs::DidUseFunction );
        }
        // Start to time the function
        ms_TimingFunctionStack.push_back ( STimingFunction( luaVM, f, GetTimeUs(), g_uiNetSentByteCounter ) );
    }
    return true;
}
Beispiel #8
0
int CLuaDefs::CanUseFunction ( lua_CFunction f, lua_State* luaVM )
{
    // Quick cull of unknown pointer range
    if ( CLuaCFunctions::IsNotFunction( f ) )
        return true;

    // these are for OOP and establish the function to call, at which point the function is called normally so we get this called like so:
    // Call 1: f = CLuaClassDefs::NewIndex
    // Call 2: f = setElementHealth
    // ignore new index as it isn't registered as an LuaCFunction and just throws an assert in debug/causes issues.
    if ( f == (lua_CFunction)&CLuaClassDefs::NewIndex || 
        f == (lua_CFunction)&CLuaClassDefs::StaticNewIndex ||
        f == (lua_CFunction)&CLuaClassDefs::Index ||
        f == (lua_CFunction)&CLuaClassDefs::Call || 
        f == (lua_CFunction)&CLuaClassDefs::ToString || 
        f == (lua_CFunction)&CLuaClassDefs::ReadOnly ||
        f == (lua_CFunction)&CLuaClassDefs::WriteOnly )
    {
        return true;
    }

    // Get associated resource
    CResource* pResource = m_pResourceManager->GetResourceFromLuaState( luaVM );
    if ( !pResource )
        return true;

    // Update execution time check
    pResource->GetVirtualMachine()->CheckExecutionTime();

    // Check function right cache in resource
    bool bAllowed;

    // Check cached ACL rights
    if ( pResource->CheckFunctionRightCache( f, &bAllowed ) )
    {
        // If in cache, and not allowed, do warning here
        if ( !bAllowed )
            m_pScriptDebugging->LogBadAccess ( luaVM );
    }
    // Not cached yet
    else
    {
        // If not in cache, do full check
        bAllowed = true;

        // Grab the function name we're calling. If it's one of our functions, see if we can use it.
        CLuaCFunction* pFunction = CLuaCFunctions::GetFunction ( f );

        // works for anything registered for Lua VM
        // e.g. setElementHealth, setElementFrozen
        if ( pFunction )
        {
            // If it's not one of lua's functions, see if we allow it
            bAllowed = CLuaDefs::CanUseFunction ( pFunction->GetName ().c_str (), luaVM, pFunction->IsRestricted () );
        }
        // works for custom ACL functions e.g.
        // Element.position and other custom oop definitions not registered by string.
        else
        {
            // get the 2nd upvalue (ACL Name)
            const char* szName = lua_tostring ( luaVM, lua_upvalueindex ( 2 ) );

            // if it has no name do nothing
            if ( szName != NULL && strcmp ( szName , "" ) != 0 )
            {
                // get the function by name
                CLuaCFunction* pFunction = CLuaCFunctions::GetFunction ( szName );
                if ( pFunction )
                {
                    // check the resource cache for the Lua name we looked up
                    bAllowed = CLuaDefs::CanUseFunction ( szName, luaVM, pFunction->IsRestricted () );
                }
            }
        }
        // Update cache in resource
        pResource->UpdateFunctionRightCache( f, bAllowed );
    }

    g_pGame->GetDebugHookManager()->OnPreFunction( f, luaVM, bAllowed );

    // If not allowed, do no more
    if ( !bAllowed )
        return false;

    // Check if function timing is active
    if ( g_pStats->bFunctionTimingActive || g_pGame->GetDebugHookManager()->HasPostFunctionHooks() )
    {
        // Check if hook needs applying
        if ( !ms_bRegisterdPostCallHook )
        {
            OutputDebugLine ( "[Lua] Registering PostCallHook" );
            ms_bRegisterdPostCallHook = true;
            lua_registerPostCallHook ( CLuaDefs::DidUseFunction );
        }
        // Start to time the function
        ms_TimingFunctionStack.push_back ( STimingFunction( luaVM, f, GetTimeUs(), g_uiNetSentByteCounter ) );
    }
    return true;
}