int CLuaFunctionDefs::toJSON ( lua_State* luaVM )
{
    // Got a string argument?
    if ( lua_type ( luaVM, 1 ) > LUA_TNIL )
    {
        // Read the argument
        CLuaArguments JSON;
        JSON.ReadArgument ( luaVM, 1 );

        // Convert it to a JSON string
        std::string strJSON;
        if ( JSON.WriteToJSONString ( strJSON ) )
        {
            // Return the JSON string
            lua_pushstring ( luaVM, strJSON.c_str () );
            return 1;
        }
    }

    // Failed
    lua_pushnil ( luaVM );
    return 1;
}
示例#2
0
CLuaTimer* CLuaTimerManager::AddTimer ( lua_State* luaVM )
{
    if ( luaVM )
    {
        int iArgument2 = lua_type ( luaVM, 2 );
        int iArgument3 = lua_type ( luaVM, 3 );
        if ( lua_type ( luaVM, 1 ) &&
             (( iArgument2 == LUA_TNUMBER || iArgument2 == LUA_TSTRING ) ||
              ( iArgument3 == LUA_TNUMBER || iArgument3 == LUA_TSTRING ) ))
        {
            // Grab the string argument, start-time, delay and repeats
            unsigned long ulTimeDelay = static_cast < unsigned long > ( lua_tonumber ( luaVM, 2 ) );
            unsigned int uiRepeats = static_cast < unsigned int > ( lua_tonumber ( luaVM, 3 ) );

            // Check for the minimum interval
            if ( ulTimeDelay < LUA_TIMER_MIN_INTERVAL ) return NULL;

            // Grab the arguments from argument 4 and up
            CLuaArguments Arguments;
            Arguments.ReadArguments ( luaVM, 4 );

            int iLuaFunction = luaM_toref ( luaVM, 1 );

            if ( iLuaFunction != LUA_REFNIL )
            {
                // Add the timer
                CLuaTimer* pLuaTimer = new CLuaTimer ( iLuaFunction, Arguments );
                pLuaTimer->SetStartTime ( GetTime () );
                pLuaTimer->SetDelay ( ulTimeDelay );
                pLuaTimer->SetRepeats ( uiRepeats );
                m_TimerList.push_back ( pLuaTimer );
                return pLuaTimer;
            }
        }
    }
    return false;
}
示例#3
0
void CElement::ReadCustomData ( CLuaMain* pLuaMain, CEvents* pEvents )
{
    assert ( pLuaMain );
    assert ( pEvents );

    // Got an XML node?
    if ( m_pXMLNode )
    {
        // Iterate the attributes of our XML node
        CXMLAttributes* pAttributes = &(m_pXMLNode->GetAttributes ());
        unsigned int uiAttributeCount = pAttributes->Count ();
        for ( unsigned int uiIndex = 0; uiIndex < uiAttributeCount; uiIndex++ )
        {
            // Grab the node (we can assume it exists here)
            CXMLAttribute* pAttribute = pAttributes->Get ( uiIndex );

            // Make a lua argument from it and set the content
            CLuaArguments args;
            if ( !args.ReadFromJSONString ( pAttribute->GetValue ().c_str() ) )
                args.PushString ( pAttribute->GetValue ().c_str () );
            SetCustomData ( pAttribute->GetName ().c_str (), *args[0], pLuaMain );
        }
    }
}
示例#4
0
bool CResource::CallExportedFunction ( const char * szFunctionName, CLuaArguments& args, CLuaArguments& returns, CResource& caller )
{
    list < CExportedFunction* > ::iterator iter =  m_exportedFunctions.begin ();
    for ( ; iter != m_exportedFunctions.end (); iter++ )
    {
        if ( strcmp ( (*iter)->GetFunctionName(), szFunctionName ) == 0 )
        {
            if ( args.CallGlobal ( m_pLuaVM, szFunctionName, &returns ) )
            {
                return true;
            }
        }
    }
    return false;
}
int CLuaFunctionDefs::fromJSON ( lua_State* luaVM )
{
    SString strJSON;

    CScriptArgReader argStream ( luaVM );
    argStream.ReadString ( strJSON );

    if ( !argStream.HasErrors () )
    {
        // Read it into lua arguments
        CLuaArguments Converted;
        if ( Converted.ReadFromJSONString ( strJSON ) )
        {
            // Return it as data
            Converted.PushArguments ( luaVM );
            return Converted.Count ();
        }
    }
    else
        m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () );

    lua_pushnil ( luaVM );
    return 1;
}
示例#6
0
//
// Handle the changing state of collision between one colshape and one entity
//
void CClientColManager::HandleHitDetectionResult ( bool bHit, CClientColShape* pShape, CClientEntity* pEntity )
{
    if ( bHit )
    {              
        // If they havn't collided yet
        if ( !pEntity->CollisionExists ( pShape ) )
        {    
            // Add the collision and the collider
            pShape->AddCollider ( pEntity );
            pEntity->AddCollision ( pShape );

            // Can we call the event?
            if ( pShape->GetAutoCallEvent () )
            {
                // Call the event
                CLuaArguments Arguments;
                Arguments.PushElement ( pEntity );
                Arguments.PushBoolean ( ( pShape->GetDimension () == pEntity->GetDimension () ) );
                pShape->CallEvent ( "onClientColShapeHit", Arguments, true );

                CLuaArguments Arguments2;
                Arguments2.PushElement ( pShape );
                Arguments2.PushBoolean ( ( pShape->GetDimension () == pEntity->GetDimension () ) );
                pEntity->CallEvent ( "onClientElementColShapeHit", Arguments2, true );
            }

            // Run whatever callback the collision item might have attached
            pShape->CallHitCallback ( *pEntity );
        }
    }
    else
    {
        // If they collided before
        if ( pEntity->CollisionExists ( pShape ) )
        {
            // Remove the collision and the collider
            pShape->RemoveCollider ( pEntity );
            pEntity->RemoveCollision ( pShape );

            // Call the event
            CLuaArguments Arguments;
            Arguments.PushElement ( pEntity );
            Arguments.PushBoolean ( ( pShape->GetDimension () == pEntity->GetDimension () ) );
            pShape->CallEvent ( "onClientColShapeLeave", Arguments, true );

            CLuaArguments Arguments2;
            Arguments2.PushElement ( pShape );
            Arguments2.PushBoolean ( ( pShape->GetDimension () == pEntity->GetDimension () ) );
            pEntity->CallEvent ( "onClientElementColShapeLeave", Arguments2, true );

            pShape->CallLeaveCallback ( *pEntity );
        }
    }
}
void CScriptDebugging::LogError ( SString strFile, int iLine, SString strMsg )
{
    SString strText = SString ( "ERROR: %s:%d: %s", strFile.c_str (), iLine, strMsg.c_str () );

    if ( !m_bTriggeringOnDebugMessage )
    {
        m_bTriggeringOnDebugMessage = true;

        // Prepare onDebugMessage
        CLuaArguments Arguments;
        Arguments.PushString ( strMsg.c_str ( ) );
        Arguments.PushNumber ( 1 );

        // Push the file name (if any)
        if ( strFile.length ( ) > 0 )
            Arguments.PushString ( strFile.c_str ( ) );
        else
            Arguments.PushNil ( );

        // Push the line (if any)
        if ( iLine > -1 )
            Arguments.PushNumber ( iLine );
        else
            Arguments.PushNil ( );
        
        // Call onDebugMessage
        g_pGame->GetMapManager ( )->GetRootElement ( )->CallEvent ( "onDebugMessage", Arguments );

        m_bTriggeringOnDebugMessage = false;
    }

    // Log it to the file if enough level
    if ( m_uiLogFileLevel >= 1 )
    {
        PrintLog ( strText );
    }

    // Log to console
    CLogger::LogPrintf( "%s\n", strText.c_str () );

    // Tell the players
    Broadcast ( CDebugEchoPacket ( strText, 1, 255, 255, 255 ), 1 );
}
示例#8
0
void CScriptDebugging::LogString ( const char* szPrePend, const SLuaDebugInfo& luaDebugInfo, const char* szMessage, unsigned int uiMinimumDebugLevel, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue )
{
    SString strText = ComposeErrorMessage( szPrePend, luaDebugInfo, szMessage );

    // Create a different message if type is "INFO"
    if ( uiMinimumDebugLevel > 2 )
        strText = SString ( "%s%s", szPrePend, szMessage );

    // Check whether onDebugMessage is currently being triggered
    if ( !m_bTriggeringOnDebugMessage )
    {
        // Make sure the state of onDebugMessage being triggered can be retrieved later
        m_bTriggeringOnDebugMessage = true;

        // Prepare onDebugMessage
        CLuaArguments Arguments;
        Arguments.PushString ( szMessage );
        Arguments.PushNumber ( uiMinimumDebugLevel );

        // Push the file name (if any)
        if ( !luaDebugInfo.strFile.empty() )
            Arguments.PushString ( luaDebugInfo.strFile );
        else
            Arguments.PushNil ( );

        // Push the line (if any)
        if ( luaDebugInfo.iLine != INVALID_LINE_NUMBER )
            Arguments.PushNumber ( luaDebugInfo.iLine );
        else
            Arguments.PushNil ( );
        
        // Call onDebugMessage
        g_pGame->GetMapManager ( )->GetRootElement ( )->CallEvent ( "onDebugMessage", Arguments );

        // Reset trigger state, so onDebugMessage can be called again at a later moment
        m_bTriggeringOnDebugMessage = false;
    }

    m_DuplicateLineFilter.AddLine( { strText, uiMinimumDebugLevel, ucRed, ucGreen, ucBlue } );
    if ( g_pGame->GetConfig()->GetFilterDuplicateLogLinesEnabled() == false )
        m_DuplicateLineFilter.Flush();
    UpdateLogOutput();
}
void CSocket::TriggerEvent(const string eventName, const string arg1)
{
    CLuaArguments args;
    args.PushString(eventName.c_str());

    lua_getglobal(m_pLuaVM, "root");
    CLuaArgument RootElement(m_pLuaVM, -1);

    args.PushUserData(RootElement.GetLightUserData());
    args.PushUserData(m_pUserdata);

    if (arg1.length() > 0)
        args.PushString(arg1.c_str());

    args.Call(m_pLuaVM, "triggerEvent");
}
void CScriptDebugging::LogError ( SString strFile, int iLine, SString strMsg )
{
    SString strText = SString ( "ERROR: %s:%d: %s", strFile.c_str (), iLine, strMsg.c_str () );

    if ( !m_bTriggeringOnClientDebugMessage )
    {
        m_bTriggeringOnClientDebugMessage = true;

        // Prepare onDebugMessage
        CLuaArguments Arguments;
        Arguments.PushString ( strMsg.c_str ( ) );
        Arguments.PushNumber ( 1 );

        // Push the file name (if any)
        if ( strFile.length ( ) > 0 )
            Arguments.PushString ( strFile.c_str ( ) );
        else
            Arguments.PushNil ( );

        // Push the line (if any)
        if ( iLine > -1 )
            Arguments.PushNumber ( iLine );
        else
            Arguments.PushNil ( );

        // Call onDebugMessage
        g_pClientGame->GetRootEntity ( )->CallEvent ( "onClientDebugMessage", Arguments, false );

        m_bTriggeringOnClientDebugMessage = false;
    }

    // Log it to the file if enough level
    if ( m_uiLogFileLevel >= 1 )
    {
        PrintLog ( strText );
    }

    // Log to console
    g_pCore->DebugEchoColor ( strText, 255, 0, 0 );
}
示例#11
0
void CKeyBinds::Call ( CKeyBind* pKeyBind )
{
    if ( pKeyBind && !pKeyBind->IsBeingDeleted () )
    {
        switch ( pKeyBind->GetType () )
        {
            case KEY_BIND_FUNCTION:
            {
                CKeyFunctionBind* pBind = static_cast < CKeyFunctionBind* > ( pKeyBind );
                if ( pBind->luaMain && VERIFY_FUNCTION ( pBind->m_iLuaFunction ) )
                {
                    CLuaArguments Arguments;
                    Arguments.PushElement ( m_pPlayer );
                    Arguments.PushString ( pBind->boundKey->szKey );
                    Arguments.PushString ( ( pBind->bHitState ) ? "down" : "up" );
                    Arguments.PushArguments ( pBind->m_Arguments );
                    Arguments.Call ( pBind->luaMain, pBind->m_iLuaFunction );
                }
                break;
            }
            case KEY_BIND_CONTROL_FUNCTION:
            {
                CControlFunctionBind* pBind = static_cast < CControlFunctionBind* > ( pKeyBind );
                if ( pBind->luaMain && VERIFY_FUNCTION ( pBind->m_iLuaFunction ) )
                {
                    CLuaArguments Arguments;
                    Arguments.PushElement ( m_pPlayer );
                    Arguments.PushString ( pBind->boundControl->szControl );
                    Arguments.PushString ( ( pBind->bHitState ) ? "down" : "up" );
                    Arguments.PushArguments ( pBind->m_Arguments );
                    Arguments.Call ( pBind->luaMain, pBind->m_iLuaFunction );
                }
                break;
            }
            default:
                break;
        }
    }
}
示例#12
0
void CResource::Load ( CClientEntity *pRootEntity )
{
    m_pRootEntity = pRootEntity;
    if ( m_pRootEntity )
    {
        // Set the GUI parent to the resource root entity
        m_pResourceCOLRoot->SetParent ( m_pResourceEntity );
        m_pResourceDFFEntity->SetParent ( m_pResourceEntity );
        m_pResourceGUIEntity->SetParent ( m_pResourceEntity );
        m_pResourceTXDRoot->SetParent ( m_pResourceEntity );
    }

    CLogger::LogPrintf ( "> Starting resource '%s'", m_szResourceName );

    char szBuffer [ MAX_PATH ] = { 0 };
    list < CResourceConfigItem* >::iterator iterc = m_ConfigFiles.begin ();
    for ( ; iterc != m_ConfigFiles.end (); iterc++ )
    {
        if ( !(*iterc)->Start() )
        {
            CLogger::LogPrintf ( "Failed to start resource item %s in %s\n", (*iterc)->GetName(), m_szResourceName );
        }
    }

    // Load the files that are queued in the list "to be loaded"
    list < CResourceFile* > ::iterator iter = m_ResourceFiles.begin ();
    for ( ; iter != m_ResourceFiles.end (); iter++ )
    {
        CResourceFile* pResourceFile = *iter;
        // Only load the resource file if it is a client script
        if ( pResourceFile->GetResourceType () == CDownloadableResource::RESOURCE_FILE_TYPE_CLIENT_SCRIPT )
        {
            // Load the file
            std::vector < char > buffer;
            FileLoad ( pResourceFile->GetName (), buffer );

            // Check the contents
            if ( buffer.size () > 0 && CChecksum::GenerateChecksumFromBuffer ( &buffer.at ( 0 ), buffer.size () ).CompareWithLegacy ( pResourceFile->GetServerChecksum () ) )
            {
                // Load the resource text
                m_pLuaVM->LoadScriptFromBuffer ( &buffer.at ( 0 ), buffer.size (), pResourceFile->GetName () );
            }
            else
            {
                SString strBuffer ( "ERROR: File '%s' in resource '%s' - CRC mismatch.", pResourceFile->GetShortName (), m_szResourceName );
                g_pCore->ChatEchoColor ( strBuffer, 255, 0, 0 );
            }
        }
        else
        if ( CheckFileForCorruption ( pResourceFile->GetName () ) )
        {
            SString strBuffer ( "WARNING: File '%s' in resource '%s' is invalid.", pResourceFile->GetShortName (), m_szResourceName );
            g_pCore->DebugEchoColor ( strBuffer, 255, 0, 0 );
        }
    }

    // Set active flag
    m_bActive = true;

    // Did we get a resource root entity?
    if ( m_pResourceEntity )
    {
        // Call the Lua "onClientResourceStart" event
        CLuaArguments Arguments;
        Arguments.PushUserData ( this );
        m_pResourceEntity->CallEvent ( "onClientResourceStart", Arguments, true );
    }
    else
        assert ( 0 );
}
示例#13
0
void CClientWebBrowser::Events_OnInputFocusChanged ( bool bGainedFocus )
{
    CLuaArguments Arguments;
    Arguments.PushBoolean ( bGainedFocus );
    CallEvent ( "onClientBrowserInputFocusChanged", Arguments, false );
}
示例#14
0
void CClientWebBrowser::Events_OnChangeCursor ( unsigned char ucCursor )
{
    CLuaArguments Arguments;
    Arguments.PushNumber ( ucCursor );
    CallEvent ( "onClientBrowserCursorChange", Arguments, false );
}
示例#15
0
void CClientWebBrowser::Events_OnTooltip ( const SString& strTooltip )
{
    CLuaArguments Arguments;
    Arguments.PushString ( strTooltip );
    CallEvent ( "onClientBrowserTooltip", Arguments, false );
}
int CLuaFunctionDefs::Call ( lua_State* luaVM )
{
    CResource * pResource = NULL;
    SString strFunctionName = "";
    CScriptArgReader argStream ( luaVM );
    argStream.ReadUserData ( pResource );
    argStream.ReadString ( strFunctionName );
    if ( !argStream.HasErrors ( ) )
    {
        // Grab our VM
        CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM );
        if ( pLuaMain )
        {
            // Grab this resource
            CResource* pThisResource = pLuaMain->GetResource ();
            if ( pThisResource )
            {
                if ( pResource )
                {
                    //Get the target Lua VM
                    lua_State* targetLuaVM = pResource->GetVM()->GetVM();

                    // Read out the vargs
                    CLuaArguments args;
                    args.ReadArguments ( luaVM, 3 );
                    CLuaArguments returns;

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

                    //Lets grab the original hidden variables so we can restore them later
                    lua_getglobal ( targetLuaVM, "sourceResource" );
                    CLuaArgument OldResource ( luaVM, -1 );
                    lua_pop( targetLuaVM, 1 );

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

                    //Set the new values for the current sourceResource, and sourceResourceRoot
                    lua_pushresource ( targetLuaVM, pThisResource );
                    lua_setglobal ( targetLuaVM, "sourceResource" );

                    lua_pushelement ( targetLuaVM, pThisResource->GetResourceEntity() );
                    lua_setglobal ( targetLuaVM, "sourceResourceRoot" );

                    // Call the exported function with the given name and the args
                    if ( pResource->CallExportedFunction ( strFunctionName, args, returns, *pThisResource ) )
                    {
                        // Push return arguments
                        returns.PushArguments ( luaVM );
                        //Restore the old variables
                        OldResource.Push ( targetLuaVM );
                        lua_setglobal ( targetLuaVM, "sourceResource" );

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

                        return returns.Count ();
                    }
                    else
                    {
                        //Restore the old variables
                        OldResource.Push ( targetLuaVM );
                        lua_setglobal ( targetLuaVM, "sourceResource" );

                        OldResourceRoot.Push ( targetLuaVM );
                        lua_setglobal ( targetLuaVM, "sourceResourceRoot" );
                        m_pScriptDebugging->LogError ( luaVM, "call: failed to call '%s:%s'", pResource->GetName (), *strFunctionName );
                    }
                }
                else
                {
                    m_pScriptDebugging->LogBadType ( luaVM );
                }
            }
        }
    }
    else
        m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage() );


    // Failed
    lua_pushboolean ( luaVM, false );
    return 1;
}
示例#17
0
void CRPCFunctions::CursorEvent ( NetBitStreamInterface & bitStream )
{
    SMouseButtonSync button;
    unsigned char ucButton;

    CVector2D vecCursorPosition;
    unsigned short usX;
    unsigned short usY;

    SPositionSync position ( false );
    CVector vecPosition;

    bool bHasCollisionElement;
    ElementID elementID;

    if ( bitStream.Read ( &button ) &&
            bitStream.ReadCompressed ( usX ) &&
            bitStream.ReadCompressed ( usY ) &&
            bitStream.Read ( &position ) &&
            bitStream.ReadBit ( bHasCollisionElement ) &&
            ( !bHasCollisionElement || bitStream.ReadCompressed ( elementID ) ) )
    {
        ucButton = button.data.ucButton;
        vecCursorPosition.fX = static_cast < float > ( usX );
        vecCursorPosition.fY = static_cast < float > ( usY );
        vecPosition = position.data.vecPosition;
        if ( !bHasCollisionElement )
            elementID = INVALID_ELEMENT_ID;
    }
    else
        return;

    if ( m_pSourcePlayer->IsJoined () )
    {
        // Get the button and state
        const char* szButton = NULL;
        const char* szState = NULL;
        switch ( ucButton )
        {
        case 0:
            szButton = "left";
            szState = "down";
            break;
        case 1:
            szButton = "left";
            szState = "up";
            break;
        case 2:
            szButton = "middle";
            szState = "down";
            break;
        case 3:
            szButton = "middle";
            szState = "up";
            break;
        case 4:
            szButton = "right";
            szState = "down";
            break;
        case 5:
            szButton = "right";
            szState = "up";
            break;
        }
        if ( szButton && szState )
        {
            CElement* pElement = CElementIDs::GetElement ( elementID );
            if ( pElement )
            {
                // Call the onElementClicked event
                CLuaArguments Arguments;
                Arguments.PushString ( szButton );
                Arguments.PushString ( szState );
                Arguments.PushElement ( m_pSourcePlayer );
                Arguments.PushNumber ( vecPosition.fX );
                Arguments.PushNumber ( vecPosition.fY );
                Arguments.PushNumber ( vecPosition.fZ );
                pElement->CallEvent ( "onElementClicked", Arguments );
            }
            // Call the onPlayerClick event
            CLuaArguments Arguments;
            Arguments.PushString ( szButton );
            Arguments.PushString ( szState );
            if ( pElement )
                Arguments.PushElement ( pElement );
            else
                Arguments.PushNil ();
            Arguments.PushNumber ( vecPosition.fX );
            Arguments.PushNumber ( vecPosition.fY );
            Arguments.PushNumber ( vecPosition.fZ );
            Arguments.PushNumber ( vecCursorPosition.fX );
            Arguments.PushNumber ( vecCursorPosition.fY );
            m_pSourcePlayer->CallEvent ( "onPlayerClick", Arguments );

            // TODO: iterate server-side element managers for the click events, eg: colshapes
        }
    }
}
示例#18
0
////////////////////////////////////////////////////////////
//
// CClientSound::Process3D
//
// Update position and velocity and pass on the BASS for processing.
// m_pAudio->DoPulse needs to be called for non-3D sounds also.
//
////////////////////////////////////////////////////////////
void CClientSound::Process3D ( const CVector& vecPlayerPosition, const CVector& vecCameraPosition, const CVector& vecLookAt )
{
    // Update 3D things if required
    if ( m_b3D )
    {
        // Update our position and velocity if we're attached
        CClientEntity* pAttachedToEntity = GetAttachedTo ();
        if ( pAttachedToEntity )
        {
            GetPosition( m_vecPosition );
            DoAttaching ();
            CVector vecVelocity;
            if ( CStaticFunctionDefinitions::GetElementVelocity ( *pAttachedToEntity, vecVelocity ) )
                SetVelocity ( vecVelocity );
            // Update our spatial data position
            UpdateSpatialData ();
        }
    }
    // If the sound isn't active, we don't need to process it
    // Moved after 3D updating as the streamer didn't know the position changed if a sound isn't streamed in when attached.
    if ( !m_pAudio )
        return;

    m_pAudio->DoPulse ( vecPlayerPosition, vecCameraPosition, vecLookAt );


    // Trigger script events for things
    SSoundEventInfo eventInfo;
    while ( m_pAudio->GetQueuedEvent ( eventInfo ) )
    {
        if ( eventInfo.type == SOUND_EVENT_FINISHED_DOWNLOAD )
        {
            CLuaArguments Arguments;
            Arguments.PushNumber ( eventInfo.dNumber );
            CallEvent ( "onClientSoundFinishedDownload", Arguments, true );
            OutputDebugLine ( SString ( "[ClientSound] onClientSoundFinishedDownload %f", eventInfo.dNumber ) );
        }
        else
        if ( eventInfo.type == SOUND_EVENT_CHANGED_META )
        {
            CLuaArguments Arguments;
            Arguments.PushString ( eventInfo.strString );
            CallEvent ( "onClientSoundChangedMeta", Arguments, true );
            OutputDebugLine ( SString ( "[ClientSound] onClientSoundChangedMeta %s", *eventInfo.strString ) );
        }
        else
        if ( eventInfo.type == SOUND_EVENT_STREAM_RESULT )
        {
            // Call onClientSoundStream LUA event
            CLuaArguments Arguments;
            Arguments.PushBoolean ( eventInfo.bBool );
            Arguments.PushNumber ( eventInfo.dNumber );
            if ( !eventInfo.strString.empty () )
                Arguments.PushString ( eventInfo.strString );
            CallEvent ( "onClientSoundStream", Arguments, true );
            OutputDebugLine ( SString ( "[ClientSound] onClientSoundStream %d %f %s", eventInfo.bBool, eventInfo.dNumber, *eventInfo.strString ) );
        }
        else
        if ( eventInfo.type == SOUND_EVENT_BEAT )
        {
            CLuaArguments Arguments;
            Arguments.PushNumber ( eventInfo.dNumber );
            CallEvent ( "onClientSoundBeat", Arguments, true );
        }
    }
}
示例#19
0
bool CConsole::HandleInput ( const char* szCommand, CClient* pClient, CClient* pEchoClient )
{
    // Copy it
    char szCommandBuffer [256];
    szCommandBuffer [255] = 0;
    strncpy ( szCommandBuffer, szCommand, 255 );
    stripControlCodes ( szCommandBuffer );

    // Split it into two parts: Key and argument
    char* szKey = strtok ( szCommandBuffer, " " );
    char* szArguments = strtok ( NULL, "\0" );

    // Does the key exist?
    if ( szKey && szKey [0] != 0 )
    {
        CConsoleCommand* pCommand = GetCommand ( szKey );
        if ( pCommand )
        {
            // Can this user use this command?
            if ( m_pACLManager->CanObjectUseRight ( pClient->GetAccount ()->GetName ().c_str (),
                                                    CAccessControlListGroupObject::OBJECT_TYPE_USER,
                                                    szKey,
                                                    CAccessControlListRight::RIGHT_TYPE_COMMAND,
                                                    !pCommand->IsRestricted () ) )
            {
                return (*pCommand)( this, szArguments, pClient, pEchoClient );
            }

            // Not enough access, tell the console
            CLogger::LogPrintf ( "DENIED: Denied '%s' access to command '%s'\n", pClient->GetNick (), szKey );

            // Tell the client
            char szBuffer [128];
            _snprintf ( szBuffer, sizeof(szBuffer), "ACL: Access denied for '%s'", szKey );
            szBuffer[sizeof(szBuffer)-1] = '\0';

            pClient->SendEcho ( szBuffer );
            return false;
        }

        // Let the script handle it
        int iClientType = pClient->GetClientType ();

        switch ( iClientType )
        {
            case CClient::CLIENT_PLAYER:
            {
                // See if any registered command can process it
                CPlayer* pPlayer = static_cast < CPlayer* > ( pClient );
                m_pRegisteredCommands->ProcessCommand ( szKey, szArguments, pClient );

                // HACK: if the client gets destroyed before here, dont continue
                if ( m_pPlayerManager->Exists ( pPlayer ) )
                {
                    // Call the console event
                    CLuaArguments Arguments;
                    Arguments.PushString ( szCommand );
                    pPlayer->CallEvent ( "onConsole", Arguments );
                }
                break;
            }
            case CClient::CLIENT_CONSOLE:
            {
                // See if any registered command can process it
                CConsoleClient* pConsole = static_cast < CConsoleClient* > ( pClient );
                m_pRegisteredCommands->ProcessCommand ( szKey, szArguments, pClient );

                // Call the console event
                CLuaArguments Arguments;
                Arguments.PushString ( szCommand );
                pConsole->CallEvent ( "onConsole", Arguments );
                break;
            }
            default: break;
        }
    }

    // Doesn't exist
    return false;
}
示例#20
0
bool COMMAND_Executed(const char* szCommand, const char* szArguments, bool bHandleRemotely, bool bHandled, bool bIsScriptedBind)
{
    // Has the core already handled this command?
    if (!bHandled)
    {
        const char* szCommandBufferPointer = szCommand;

        if (!bHandleRemotely)
        {
            // Is the command "say" and the arguments start with '/' ? (command comes from the chatbox)
            if (stricmp(szCommand, "chatboxsay") == 0)
            {
                szCommandBufferPointer = "say";
            }
        }

        // Toss them together so we can send it to the server
        SString strClumpedCommand;
        if (szArguments && szArguments[0])
            strClumpedCommand.Format("%s %s", szCommandBufferPointer, szArguments);
        else
            strClumpedCommand = szCommandBufferPointer;

        // Convert to Unicode, and clamp it to a maximum command length
        std::wstring strClumpedCommandUTF = MbUTF8ToUTF16(strClumpedCommand.c_str());
        strClumpedCommandUTF = strClumpedCommandUTF.substr(0, MAX_COMMAND_LENGTH);
        strClumpedCommand = UTF16ToMbUTF8(strClumpedCommandUTF);

        g_pClientGame->GetRegisteredCommands()->ProcessCommand(szCommandBufferPointer, szArguments);

        // Call the onClientConsole event
        auto pLocalPlayer = g_pClientGame->GetLocalPlayer();

        if (pLocalPlayer)
        {
            CLuaArguments Arguments;

            // Censor input for /login command
            if (!stricmp(szCommandBufferPointer, "login"))
            {
                Arguments.PushString(SString("%s ***", szCommandBufferPointer));
            }
            else
            {
                Arguments.PushString(strClumpedCommand);
            }

            pLocalPlayer->CallEvent("onClientConsole", Arguments, true);
        }

        // Write the chatlength and the content
        NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream();
        if (!pBitStream)
            return false;

        // Write it to the bitstream
        pBitStream->Write(strClumpedCommand.c_str(), static_cast<int>(strlen(strClumpedCommand.c_str())));

        // Send the packet to the server and free it
        g_pNet->SendPacket(PACKET_ID_COMMAND, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED, PACKET_ORDERING_CHAT);
        g_pNet->DeallocateNetBitStream(pBitStream);

        return true;
    }
    else
    {
        // Call our comand-handlers for core-executed commands too
        g_pClientGame->GetRegisteredCommands()->ProcessCommand(szCommand, szArguments);
    }
    return false;
}
示例#21
0
// Set ( resource requesting the query, setting name, content )
bool CSettings::Set(const char *szLocalResource, const char *szSetting, const char *szContent)
{
    CXMLNode *      pNode;
    CResource *     pResource;
    CXMLAttributes *pAttributes;
    char            szBuffer[MAX_SETTINGS_LENGTH] = {0};
    char            szQueryResource[MAX_RESOURCE_LENGTH] = {0};
    SettingStatus   eStatus;
    bool            bDeleteNode, bExists;
    SString         strOldValue;

    // Check for empty strings
    if (strlen(szSetting) < 1)
        return false;

    // Get the actual resource name from the specified setting, and get the resource class
    if (!GetResourceName(szSetting, szQueryResource, MAX_RESOURCE_LENGTH - 1))
    {
        // No name was specified, so use the local resource
        pResource = m_pResourceManager->GetResource(szLocalResource);
    }
    else
        pResource = m_pResourceManager->GetResource(szQueryResource);

    // If we have a valid resource
    if (pResource)
    {
        CXMLNode *pSource = pResource->GetSettingsNode();

        // Check whether the setting exists in the settings registry
        pNode = Get(m_pNodeGlobalSettings, NULL, "", szLocalResource, szSetting, bDeleteNode, eStatus);
        bExists = true;            // Default value

        // Try to get the value for the appropriate setting from the resource's meta XML file
        if (eStatus == NotFound && pSource)
        {
            pNode = Get(pSource, NULL, pResource->GetName().c_str(), szLocalResource, szSetting, bDeleteNode, eStatus);
            bExists = false;            // There's no node in the settings registry, so we create one
        }

        // See if we have access
        if (eStatus != NoAccess)
        {
            // See if we have a prefix
            bool bPrefix = HasPrefix(szSetting[0]);

            // If no resource name was specified, use the local resource name
            if (!HasResourceName(szSetting))
            {
                // If we have a prefix, move it from szSetting and put it at the beginning
                if (bPrefix)
                    snprintf(szBuffer, MAX_SETTINGS_LENGTH - 1, "%c%s.%s", szSetting[0], szLocalResource, szSetting + 1);
                else
                    snprintf(szBuffer, MAX_SETTINGS_LENGTH - 1, "%s.%s", szLocalResource, szSetting);
            }
            else
            {
                // If we have a prefix, move it from szSetting and put it at the beginning
                if (bPrefix)
                    snprintf(szBuffer, MAX_SETTINGS_LENGTH - 1, "%c%s", szSetting[0], szSetting + 1);
                else
                    strncpy(szBuffer, szSetting, MAX_SETTINGS_LENGTH - 1);
            }

            if (!bExists || !pNode)
            {            // No existing settings registry entry, so create a new setting
                CreateSetting(m_pNodeGlobalSettings, szBuffer, szContent);
            }
            else
            {            // Existing settings registry entry
                // Get the attributes
                pAttributes = &(pNode->GetAttributes());

                // Abort if this value isnt public (but protected or private), and if the local resource
                // (doing the query) doesn't equal the setting's resource name
                if (GetAccessType(pAttributes->Find("name")->GetValue()[0]) != CSettings::Public && stricmp(pResource->GetName().c_str(), szLocalResource) != 0)
                    return false;

                // Get the node's current value
                strOldValue = pAttributes->Find("value")->GetValue();

                // Set the node's value
                pAttributes->Find("value")->SetValue(szContent);

                // If a prefix was given, set the node's name (to override any access operators)
                if (bPrefix)
                    pAttributes->Find("name")->SetValue(szBuffer);
            }

            // Trigger onSettingChange
            CLuaArguments Arguments;
            Arguments.PushString(szSetting);

            if (strOldValue.length() > 0)
                Arguments.PushString(strOldValue.c_str());
            else
                Arguments.PushNil();

            Arguments.PushString(szContent);

            g_pGame->GetMapManager()->GetRootElement()->CallEvent("onSettingChange", Arguments);

            // Save the XML file
            if (m_pFile->Write())
                return true;
            CLogger::ErrorPrintf("Error saving '%s'\n", FILENAME_SETTINGS);
        }
    }

    return false;
}
示例#22
0
bool CPlayerPuresyncPacket::Read ( NetBitStreamInterface& BitStream )
{
    if ( m_pSourceElement )
    {
        CPlayer * pSourcePlayer = static_cast < CPlayer * > ( m_pSourceElement );

        // Read out the time context
        unsigned char ucTimeContext = 0;
        if ( !BitStream.Read ( ucTimeContext ) )
            return false;

        // Only read this packet if it matches the current time context that
        // player is in.
        if ( !pSourcePlayer->CanUpdateSync ( ucTimeContext ) )
        {
            return false;
        }

        // Read out keys
        CControllerState ControllerState;
        ReadFullKeysync ( ControllerState, BitStream );
        pSourcePlayer->GetPad ()->NewControllerState ( ControllerState );

        // Read the flags
        SPlayerPuresyncFlags flags;
        if ( !BitStream.Read ( &flags ) )
            return false;

        pSourcePlayer->SetInWater ( flags.data.bIsInWater );
        pSourcePlayer->SetOnGround ( flags.data.bIsOnGround );
        pSourcePlayer->SetHasJetPack ( flags.data.bHasJetPack );
        pSourcePlayer->SetDucked ( flags.data.bIsDucked );
        pSourcePlayer->SetWearingGoggles ( flags.data.bWearsGoogles );
        pSourcePlayer->SetChoking ( flags.data.bIsChoking );
        pSourcePlayer->SetAkimboArmUp ( flags.data.bAkimboTargetUp );
        pSourcePlayer->SetOnFire ( flags.data.bIsOnFire );
        pSourcePlayer->SetStealthAiming ( flags.data.bStealthAiming );

        // Contact element
        CElement* pContactElement = NULL;
        if ( flags.data.bHasContact )
        {
            ElementID Temp;
            if ( !BitStream.ReadCompressed ( Temp ) )
                return false;
            pContactElement = CElementIDs::GetElement ( Temp );
        }
        CElement * pPreviousContactElement = pSourcePlayer->GetContactElement ();
        pSourcePlayer->SetContactElement ( pContactElement );

        if ( pPreviousContactElement != pContactElement )
        {
            // Call our onPlayerContact event
            CLuaArguments Arguments;
            if ( pPreviousContactElement )
                Arguments.PushElement ( pPreviousContactElement );
            else
                Arguments.PushNil ();
            if ( pContactElement )
                Arguments.PushElement ( pContactElement );
            else
                Arguments.PushNil ();

            pSourcePlayer->CallEvent ( "onPlayerContact", Arguments );
        }

        // Player position
        SPositionSync position ( false );
        if ( !BitStream.Read ( &position ) )
            return false;

        if ( pContactElement )
        {
            pSourcePlayer->SetContactPosition ( position.data.vecPosition );

            // Get the true position
            CVector vecTempPos = pContactElement->GetPosition ();
            position.data.vecPosition += vecTempPos;
        }
        pSourcePlayer->SetPosition ( position.data.vecPosition );

        // Player rotation
        SPedRotationSync rotation;
        if ( !BitStream.Read ( &rotation ) )
            return false;
        pSourcePlayer->SetRotation ( rotation.data.fRotation );

        // Move speed vector
        if ( flags.data.bSyncingVelocity )
        {
            SVelocitySync velocity;
            if ( !BitStream.Read ( &velocity ) )
                return false;
            pSourcePlayer->SetVelocity ( velocity.data.vecVelocity );
        }

        // Health ( stored with damage )
        SPlayerHealthSync health;
        if ( !BitStream.Read ( &health ) )
            return false;
        float fHealth = health.data.fValue;

        // Armor
        SPlayerArmorSync armor;
        if ( !BitStream.Read ( &armor ) )
            return false;

        float fArmor = armor.data.fValue;
        float fOldArmor = pSourcePlayer->GetArmor ();
        float fArmorLoss = fOldArmor - fArmor;

        pSourcePlayer->SetArmor ( fArmor );

        // Read out and set the camera rotation
        float fCameraRotation;
        if ( !BitStream.Read ( fCameraRotation ) )
            return false;
        pSourcePlayer->SetCameraRotation ( fCameraRotation );

        if ( flags.data.bHasAWeapon )
        {
            if ( BitStream.Version () >= 0x0d )
            {
                // Check client has the weapon we think he has
                unsigned char ucWeaponType;
                if ( !BitStream.Read ( ucWeaponType ) )
                    return false;

                if ( pSourcePlayer->GetWeaponType () != ucWeaponType )
                    return false;
            }

            // Current weapon slot
            SWeaponSlotSync slot;
            if ( !BitStream.Read ( &slot ) )
                return false;
            unsigned int uiSlot = slot.data.uiSlot;

            pSourcePlayer->SetWeaponSlot ( uiSlot );

            if ( CWeaponNames::DoesSlotHaveAmmo ( uiSlot ) )
            {
                // Read out the ammo states
                SWeaponAmmoSync ammo ( pSourcePlayer->GetWeaponType (), true, true );
                if ( !BitStream.Read ( &ammo ) )
                    return false;
                pSourcePlayer->SetWeaponAmmoInClip ( ammo.data.usAmmoInClip );
                pSourcePlayer->SetWeaponTotalAmmo ( ammo.data.usTotalAmmo );

                // Read out the aim data
                SWeaponAimSync sync ( pSourcePlayer->GetWeaponRange (), ( ControllerState.RightShoulder1 || ControllerState.ButtonCircle ) );
                if ( !BitStream.Read ( &sync ) )
                    return false;

                // Set the arm directions and whether or not arms are up
                pSourcePlayer->SetAimDirection ( sync.data.fArm );

                // Read the aim data only if he's shooting or aiming
                if ( sync.isFull() )
                {
                    pSourcePlayer->SetSniperSourceVector ( sync.data.vecOrigin );
                    pSourcePlayer->SetTargettingVector ( sync.data.vecTarget );
                }
            }
            else
            {
                pSourcePlayer->SetWeaponAmmoInClip ( 1 );
                pSourcePlayer->SetWeaponTotalAmmo ( 1 );
            }
        }
        else
        {
            pSourcePlayer->SetWeaponSlot ( 0 );
            pSourcePlayer->SetWeaponAmmoInClip ( 1 );
            pSourcePlayer->SetWeaponTotalAmmo ( 1 );
        }

        // Read out damage info if changed
        if ( BitStream.ReadBit () == true )
        {
            ElementID DamagerID;
            if ( !BitStream.ReadCompressed ( DamagerID ) )
                return false;

            SWeaponTypeSync weaponType;
            if ( !BitStream.Read ( &weaponType ) )
                return false;

            SBodypartSync bodyPart;
            if ( !BitStream.Read ( &bodyPart ) )
                return false;

            pSourcePlayer->SetDamageInfo ( DamagerID, weaponType.data.ucWeaponType, bodyPart.data.uiBodypart );
        }

        // If we know the player's dead, make sure the health we send on is 0
        if ( pSourcePlayer->IsDead () )
            fHealth = 0.0f;

        float fOldHealth = pSourcePlayer->GetHealth ();
        float fHealthLoss = fOldHealth - fHealth;
        pSourcePlayer->SetHealth ( fHealth );

        // Less than last packet's frame?
        if ( fHealthLoss > 0 || fArmorLoss > 0 )
        {
            float fDamage = 0.0f;
            if ( fHealthLoss > 0 ) fDamage += fHealthLoss;
            if ( fArmorLoss > 0 ) fDamage += fArmorLoss;

            // Call the onPlayerDamage event
            CLuaArguments Arguments;
            CElement* pKillerElement = CElementIDs::GetElement ( pSourcePlayer->GetPlayerAttacker () );
            if ( pKillerElement ) Arguments.PushElement ( pKillerElement );
            else Arguments.PushNil ();
            Arguments.PushNumber ( pSourcePlayer->GetAttackWeapon () );
            Arguments.PushNumber ( pSourcePlayer->GetAttackBodyPart () );
            Arguments.PushNumber ( fDamage );

            pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments );
        }

        // Success
        return true;
    }

    return false;
}
void CScriptDebugging::LogString ( const char* szPrePend, lua_State * luaVM, const char* szMessage, unsigned int uiMinimumDebugLevel, unsigned char ucRed, unsigned char ucGreen, unsigned char ucBlue )
{
    SString strText;
    lua_Debug debugInfo;

    // Initialize values for onDebugMessage
    SString strMsg  = szMessage;
    SString strFile = "";
    int     iLine   = -1;

    // Get a VM from somewhere
    if ( !luaVM && !m_LuaMainStack.empty () )
        luaVM = m_LuaMainStack.back ()->GetVM ();

    for ( int level = 1; level < 3; level++ )
    {
	    if ( luaVM && lua_getstack ( luaVM, level, &debugInfo ) )
	    {
		    lua_getinfo ( luaVM, "nlS", &debugInfo );

		     // Make sure this function isn't defined in a string (eg: from runcode)
            if ( debugInfo.source[0] == '@' )
            {
                // Get and store the location of the debug message
                strFile = debugInfo.source + 1;
                iLine   = debugInfo.currentline;

                // Populate a message to print/send (unless "info" type)
                if ( uiMinimumDebugLevel < 3 )
                    strText = SString ( "%s%s:%d: %s", szPrePend, strFile.c_str (), debugInfo.currentline, szMessage );
                // if the file isn't empty, stop trying any other levels
                break;
            }
            else
            {
                strFile = debugInfo.short_src;

                if ( uiMinimumDebugLevel < 3 )
                    strText = SString ( "%s%s %s", szPrePend, szMessage, strFile.c_str () );
                if ( strFile != "[string \"?\"]" ) // if the file isn't empty, stop trying any other levels
                    break;
            }
        }
        else
        {
            strText = SString ( "%s%s%s", szPrePend, m_strLineAndFile.c_str(), szMessage );
            // no point in trying other levels
            break;
        }
    }

    // Create a different message if type is "INFO"
    if ( uiMinimumDebugLevel > 2 )
        strText = SString ( "%s%s", szPrePend, szMessage );

    // Check whether onDebugMessage is currently being triggered
    if ( !m_bTriggeringOnDebugMessage )
    {
        // Make sure the state of onDebugMessage being triggered can be retrieved later
        m_bTriggeringOnDebugMessage = true;

        // Prepare onDebugMessage
        CLuaArguments Arguments;
        Arguments.PushString ( strMsg.c_str ( ) );
        Arguments.PushNumber ( uiMinimumDebugLevel );

        // Push the file name (if any)
        if ( strFile.length ( ) > 0 )
            Arguments.PushString ( strFile.c_str ( ) );
        else
            Arguments.PushNil ( );

        // Push the line (if any)
        if ( iLine > -1 )
            Arguments.PushNumber ( iLine );
        else
            Arguments.PushNil ( );
        
        // Call onDebugMessage
        g_pGame->GetMapManager ( )->GetRootElement ( )->CallEvent ( "onDebugMessage", Arguments );

        // Reset trigger state, so onDebugMessage can be called again at a later moment
        m_bTriggeringOnDebugMessage = false;
    }

    // Log it to the file if enough level
    if ( m_uiLogFileLevel >= uiMinimumDebugLevel )
    {
        PrintLog ( strText );
    }

    // Log to console
    CLogger::LogPrintf( "%s\n", strText.c_str () );

    // Not sure what this is for, seems pretty useless
    if ( m_uiHtmlLogLevel >= uiMinimumDebugLevel )
    {
        if ( luaVM )
        {
            CLuaMain* pLuaMain = g_pGame->GetLuaManager()->GetVirtualMachine ( luaVM );
            if ( pLuaMain )
            {
                CResourceFile * file = pLuaMain->GetResourceFile();
                if ( file && file->GetType() == CResourceHTMLItem::RESOURCE_FILE_TYPE_HTML )
                {
                    CResourceHTMLItem * html = (CResourceHTMLItem *)file;
                    html->AppendToPageBuffer ( strText );
                    html->AppendToPageBuffer ( "<br/>" );
                }
            }
        }
    }

    // Tell the players
    Broadcast ( CDebugEchoPacket ( strText, uiMinimumDebugLevel, ucRed, ucGreen, ucBlue ), uiMinimumDebugLevel );
}
示例#24
0
void CRemoteCall::DownloadFinishedCallback(const SHttpDownloadResult& result)
{
    CRemoteCall* pCall = (CRemoteCall*)result.pObj;
    if (!g_pClientGame->GetRemoteCalls()->CallExists(pCall))
        return;

    CLuaArguments arguments;
    if (pCall->IsLegacy())
    {
        if (result.bSuccess)
        {
            if (pCall->IsFetch())
            {
                arguments.PushString(std::string(result.pData, result.dataSize));
                arguments.PushNumber(0);
            }
            else
                arguments.ReadFromJSONString(result.pData);
        }
        else
        {
            arguments.PushString("ERROR");
            arguments.PushNumber(result.iErrorCode);
        }

    }
    else
    {
        // Append response body
        arguments.PushString(std::string(result.pData, result.dataSize));

        // Append info table
        CLuaArguments info;
        info.PushString("success");
        info.PushBoolean(result.iErrorCode >= 200 && result.iErrorCode <= 299);
        info.PushString("statusCode");
        info.PushNumber(result.iErrorCode);

        // Headers as a subtable
        CLuaArguments headers;
        for (auto iter : result.headers )
        {
            headers.PushString(iter.first);
            headers.PushString(iter.second);
        }
        info.PushString("headers");
        info.PushTable(&headers);

        arguments.PushTable(&info);
    }

    // Append stored arguments
    if (pCall->IsFetch())
        for (uint i = 0; i < pCall->GetFetchArguments().Count(); i++ )
            arguments.PushArgument(*(pCall->GetFetchArguments()[i]));

    arguments.Call(pCall->m_VM, pCall->m_iFunction);
    g_pClientGame->GetRemoteCalls()->Remove(pCall);
}
示例#25
0
bool CRemoteCall::ProgressCallback(double sizeJustDownloaded, double totalDownloaded, char * data, size_t dataLength, void * obj, bool complete, int error)
{
    //printf("Progress: %s\n", data);
    if ( complete )
    {
        CRemoteCall * call = (CRemoteCall*)obj;
        if ( g_pGame->GetRemoteCalls()->CallExists(call) )
        {
            //printf("RECIEVED: %s\n", data);
            CLuaArguments arguments;
            if ( call->IsFetch () )
            {
                arguments.PushString ( std::string ( data, dataLength ) );
                arguments.PushNumber ( 0 );
                for ( uint i = 0 ; i < call->GetFetchArguments ().Count () ; i++ )
                    arguments.PushArgument ( *( call->GetFetchArguments ()[i] ) );
            }
            else
                arguments.ReadFromJSONString ( data );

            arguments.Call ( call->m_VM, call->m_iFunction);   

            g_pGame->GetRemoteCalls()->Remove(call); // delete ourselves
            return true;
        }
    }
    else if ( error )
    {
        CRemoteCall * call = (CRemoteCall*)obj;
        if ( g_pGame->GetRemoteCalls()->CallExists(call) )
        {
            CLuaArguments arguments;
            arguments.PushString("ERROR");
            arguments.PushNumber(error);
            if ( call->IsFetch () )
                for ( uint i = 0 ; i < call->GetFetchArguments ().Count () ; i++ )
                    arguments.PushArgument ( *( call->GetFetchArguments ()[i] ) );

            arguments.Call ( call->m_VM, call->m_iFunction);   

            g_pGame->GetRemoteCalls()->Remove(call); // delete ourselves
            return true;
        }
    }

    return false;   // Possible problem
}
示例#26
0
bool CAccountManager::LogIn ( CClient* pClient, CClient* pEchoClient, const char* szAccountName, const char* szPassword )
{
    // Is he already logged in?
    if ( pClient->IsRegistered () )
    {
        if ( pEchoClient ) pEchoClient->SendEcho ( "login: You are already logged in" );
        return false;
    }

    if ( pClient->GetClientType () != CClient::CLIENT_PLAYER )
    {
        if ( pEchoClient ) pEchoClient->SendEcho ( "login: Only players can log in" );
        return false;
    }

    // Get the players details
    CPlayer* pPlayer = static_cast < CPlayer* > ( pClient );
    SString strPlayerName = pPlayer->GetNick ();
    SString strPlayerIP = pPlayer->GetSourceIP ();
    SString strPlayerSerial = pPlayer->GetSerial ();

    if ( m_AccountProtect.IsFlooding ( strPlayerIP.c_str () ) )
    {
        if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Account locked", szAccountName ).c_str() );
        CLogger::AuthPrintf ( "LOGIN: Ignoring %s trying to log in as '%s' (IP: %s  Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () );
        return false;
    }

    // Grab the account on his nick if any
    CAccount* pAccount = g_pGame->GetAccountManager ()->Get ( szAccountName );
    if ( !pAccount )
    {
        if ( pEchoClient ) pEchoClient->SendEcho( SString( "login: No known account for '%s'", szAccountName ).c_str() );
        CLogger::AuthPrintf ( "LOGIN: %s tried to log in as '%s' (Unknown account) (IP: %s  Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () );
        return false;
    }

    if ( pAccount->GetClient () )
    {
        if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Account for '%s' is already in use", szAccountName ).c_str() );
        return false;
    }
    if ( !IsValidPassword( szPassword ) || !pAccount->IsPassword ( szPassword ) )
    {
        if ( pEchoClient ) pEchoClient->SendEcho ( SString( "login: Invalid password for account '%s'", szAccountName ).c_str() );
        CLogger::AuthPrintf ( "LOGIN: %s tried to log in as '%s' with an invalid password (IP: %s  Serial: %s)\n", strPlayerName.c_str (), szAccountName, strPlayerIP.c_str (), strPlayerSerial.c_str () );
        m_AccountProtect.AddConnect ( strPlayerIP.c_str () );
        return false;
    }

    // Check serial authorization
    if ( IsAuthorizedSerialRequired( pAccount ) )
    {
        pAccount->AddSerialForAuthorization( strPlayerSerial, strPlayerIP );
        if ( !pAccount->IsSerialAuthorized( strPlayerSerial ) )
        {
            if ( pEchoClient )
                pEchoClient->SendEcho( SString( "login: Serial pending authorization for account '%s' - See https:""//mtasa.com/authserial", szAccountName ) );
            CLogger::AuthPrintf( "LOGIN: %s tried to log in as '%s' with an unauthorized serial (IP: %s  Serial: %s)\n", *strPlayerName, szAccountName, *strPlayerIP, *strPlayerSerial );
            CLogger::AuthPrintf( "LOGIN: See https:""//mtasa.com/authserial\n" );
            return false;
        }
    }

    // Log him in
    CAccount* pCurrentAccount = pClient->GetAccount ();
    pClient->SetAccount ( pAccount );
    pAccount->SetClient ( pClient );

    // Call the onPlayerLogin script event
    CLuaArguments Arguments;
    Arguments.PushAccount ( pCurrentAccount );
    Arguments.PushAccount ( pAccount );
    Arguments.PushBoolean ( false );    // was bAutoLogin
    if ( !pPlayer->CallEvent ( "onPlayerLogin", Arguments ) )
    {
        // DENIED!
        pClient->SetAccount ( pCurrentAccount );
        pAccount->SetClient ( NULL );
        return false;
    }

    // Success is here
    pAccount->OnLoginSuccess ( strPlayerSerial, strPlayerIP );

    SString strGroupList = SString::Join ( ", ", g_pGame->GetACLManager ()->GetObjectGroupNames ( pAccount->GetName (), CAccessControlListGroupObject::OBJECT_TYPE_USER ) );
    CLogger::AuthPrintf ( "LOGIN: (%s) %s successfully logged in as '%s' (IP: %s  Serial: %s)\n", strGroupList.c_str (), pClient->GetNick (), pAccount->GetName ().c_str (), strPlayerIP.c_str (), strPlayerSerial.c_str () );

    // Tell the player
    if ( pEchoClient )
    {
        pEchoClient->SendEcho ( "login: You successfully logged in" );
    }

    // Update who was info
    if ( pClient->GetClientType () == CClient::CLIENT_PLAYER )
        g_pGame->GetConsole ()->GetWhoWas ()->OnPlayerLogin ( static_cast < CPlayer* > ( pClient ) );

    // Delete the old account if it was a guest account
    if ( !pCurrentAccount->IsRegistered () )
        delete pCurrentAccount;

    return true;
}
int CLuaFunctionDefs::Get ( lua_State* luaVM )
{
    CResource* pResource = m_pLuaManager->GetVirtualMachine ( luaVM )->GetResource ();
    SString strSetting;
    CLuaArguments Args;

    CScriptArgReader argStream ( luaVM );
    argStream.ReadString ( strSetting );

    if ( !argStream.HasErrors () )
    {
        unsigned int uiIndex = 0;
        bool bDeleteNode;

        // Extract attribute name if setting to be gotten has three parts i.e. resname.settingname.attributename
        SString strAttribute = "value";
        vector < SString > Result;
        strSetting.Split ( ".", Result );
        if ( Result.size () == 3 && Result[2].length () )
        {
            strAttribute = Result[2];
        }

        // Get the setting
        CXMLNode *pSubNode, *pNode = g_pGame->GetSettings ()->Get ( pResource->GetName ().c_str (), strSetting.c_str (), bDeleteNode );

        // Only proceed if we have a valid node
        if ( pNode ) {
            // Argument count
            unsigned int uiArgCount = 1;

            // See if we need to return a table with single or multiple entries
            if ( pNode->GetSubNodeCount () == 0 ) {
                // See if required attribute exists
                CXMLAttribute *pAttribute = pNode->GetAttributes ().Find ( strAttribute.c_str () );
                if ( !pAttribute )
                {
                    if ( bDeleteNode )
                        delete pNode;
                    lua_pushboolean ( luaVM, false );
                    return 1;
                }
                // We only have a single entry for a specific setting, so output a string
                const std::string& strDataValue = pAttribute->GetValue ();
                if ( !Args.ReadFromJSONString ( strDataValue.c_str () ) ) {
                    // No valid JSON? Parse as plain text
                    Args.PushString ( strDataValue );
                }

                Args.PushArguments ( luaVM );
                uiArgCount = Args.Count ();

                /* Don't output a table because although it is more consistent with the multiple values output below,
                ** due to lua's implementation of associative arrays (assuming we use the "setting-name", "value" key-value pairs)
                ** it would require the scripter to walk through an array that only has a single entry which is a Bad Thing, performance wise.
                **
                PUSH_SETTING ( pNode );
                Args.PushAsTable ( luaVM );
                **/
            }
            else {
                // We need to return multiply entries, so push all subnodes
                while ( ( pSubNode = pNode->FindSubNode ( "setting", uiIndex++ ) ) )
                {
                    CXMLAttributes& attributes = pSubNode->GetAttributes ();
                    Args.PushString ( attributes.Find ( "name" )->GetValue () );
                    const std::string& strDataValue = attributes.Find ( "value" )->GetValue ();
                    if ( !Args.ReadFromJSONString ( strDataValue.c_str () ) )
                    {
                        Args.PushString ( strDataValue );
                    }
                }
                // Push a table and return
                Args.PushAsTable ( luaVM );
            }

            // Check if we have to delete the node
            if ( bDeleteNode )
                delete pNode;

            return uiArgCount;
        }
    }
    else
        m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () );

    lua_pushboolean ( luaVM, false );
    return 1;
}
bool CVehiclePuresyncPacket::Read ( NetBitStreamInterface& BitStream )
{
    // Got a player to read?
    if ( m_pSourceElement )
    {
        CPlayer * pSourcePlayer = static_cast < CPlayer * > ( m_pSourceElement );

        // Player is in a vehicle?
        CVehicle* pVehicle = pSourcePlayer->GetOccupiedVehicle ();
        if ( pVehicle )
        {
            // Read out the time context
            unsigned char ucTimeContext = 0;
            if ( !BitStream.Read ( ucTimeContext ) )
                return false;

            // Only read this packet if it matches the current time context that
            // player is in.
            if ( !pSourcePlayer->CanUpdateSync ( ucTimeContext ) )
            {
                return false;
            }

            // Read out the keysync data
            CControllerState ControllerState;
            if ( !ReadFullKeysync ( ControllerState, BitStream ) )
                return false;

            // Read out its position
            SPositionSync position ( false );
            if ( !BitStream.Read ( &position ) )
                return false;
            pSourcePlayer->SetPosition ( position.data.vecPosition );

            // Jax: don't allow any outdated packets through
            unsigned char ucSeat;
            if ( !BitStream.Read ( ucSeat ) )
                return false;
            if ( ucSeat != pSourcePlayer->GetOccupiedVehicleSeat () )
            {
                // Mis-matching seats can happen when we warp into a different one,
                // which will screw up the whole packet
                return false;
            }

            // Read out the vehicle matrix only if he's the driver
            unsigned int uiSeat = pSourcePlayer->GetOccupiedVehicleSeat ();
            if ( uiSeat == 0 )
            {
                // Read out the vehicle rotation in degrees
                SRotationDegreesSync rotation;
                if( !BitStream.Read ( &rotation ) )
                    return false;

                // Set it
                pVehicle->SetPosition ( position.data.vecPosition );
                pVehicle->SetRotationDegrees ( rotation.data.vecRotation );

                // Move speed vector
                SVelocitySync velocity;
                if ( !BitStream.Read ( &velocity ) )
                    return false;

                pVehicle->SetVelocity ( velocity.data.vecVelocity );
                pSourcePlayer->SetVelocity ( velocity.data.vecVelocity );

                // Turn speed vector
                SVelocitySync turnSpeed;
                if ( !BitStream.Read ( &turnSpeed ) )
                    return false;

                pVehicle->SetTurnSpeed ( turnSpeed.data.vecVelocity );

                // Health
                SVehicleHealthSync health;
                if ( !BitStream.Read ( &health ) )
                    return false;
                float fPreviousHealth = pVehicle->GetHealth ();                
                float fHealth = health.data.fValue;

                // Less than last time?
                if ( fHealth < fPreviousHealth )
                {                 
                    // Grab the delta health
                    float fDeltaHealth = fPreviousHealth - fHealth;

					if ( fDeltaHealth > 0.0f )
					{
						// Call the onVehicleDamage event
						CLuaArguments Arguments;
						Arguments.PushNumber ( fDeltaHealth );
						pVehicle->CallEvent ( "onVehicleDamage", Arguments );
					}
                }
                pVehicle->SetHealth ( fHealth );

                // Trailer chain
                CVehicle* pTowedByVehicle = pVehicle;
                CVehicle* pTrailer = NULL;
                ElementID TrailerID;
                bool bHasTrailer;
                if ( !BitStream.ReadBit ( bHasTrailer ) )
                    return false;

                while ( bHasTrailer )
                {
                    BitStream.ReadCompressed ( TrailerID );
                    CElement* pElement = CElementIDs::GetElement ( TrailerID );
                    if ( pElement )
                        pTrailer = static_cast < CVehicle* > ( pElement );
                    
                    // Read out the trailer position and rotation
                    SPositionSync trailerPosition ( false );
                    if ( !BitStream.Read ( &trailerPosition ) )
                        return false;

                    SRotationDegreesSync trailerRotation;
                    if ( !BitStream.Read ( &trailerRotation ) )
                        return false;

                    // If we found the trailer
                    if ( pTrailer )
                    {
                        // Set its position and rotation
                        pTrailer->SetPosition ( trailerPosition.data.vecPosition );
                        pTrailer->SetRotationDegrees ( trailerRotation.data.vecRotation );
    
                        // Is this a new trailer, attached?
                        CVehicle* pCurrentTrailer = pTowedByVehicle->GetTowedVehicle ();
                        if ( pCurrentTrailer != pTrailer )
                        {
                            // If theres a trailer already attached
                            if ( pCurrentTrailer )
                            {
                                pTowedByVehicle->SetTowedVehicle ( NULL );
                                pCurrentTrailer->SetTowedByVehicle ( NULL );

                                // Tell everyone to detach them
                                CVehicleTrailerPacket AttachPacket ( pTowedByVehicle, pCurrentTrailer, false );
                                g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket );

                                // Execute the attach trailer script function
                                CLuaArguments Arguments;
                                Arguments.PushElement ( pTowedByVehicle );
                                pCurrentTrailer->CallEvent ( "onTrailerDetach", Arguments );
                            }

                            // If something else is towing this trailer
                            CVehicle* pCurrentVehicle = pTrailer->GetTowedByVehicle ();
                            if ( pCurrentVehicle )
                            {
                                pCurrentVehicle->SetTowedVehicle ( NULL );
                                pTrailer->SetTowedByVehicle ( NULL );

                                // Tell everyone to detach them
                                CVehicleTrailerPacket AttachPacket ( pCurrentVehicle, pTrailer, false );
                                g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket );

                                // Execute the attach trailer script function
                                CLuaArguments Arguments;
                                Arguments.PushElement ( pCurrentVehicle );
                                pTrailer->CallEvent ( "onTrailerDetach", Arguments );
                            }

                            pTowedByVehicle->SetTowedVehicle ( pTrailer );
                            pTrailer->SetTowedByVehicle ( pTowedByVehicle );

                            // Execute the attach trailer script function
                            CLuaArguments Arguments;
                            Arguments.PushElement ( pTowedByVehicle );
                            bool bContinue = pTrailer->CallEvent ( "onTrailerAttach", Arguments );

                            // Attach or detach trailers depending on the event outcome
                            CVehicleTrailerPacket TrailerPacket ( pTowedByVehicle, pTrailer, bContinue );
                            g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( TrailerPacket );
                        }
                    }
                    else
                        break;

                    pTowedByVehicle = pTrailer;

                    if ( BitStream.ReadBit ( bHasTrailer ) == false )
                        return false;
                }

                // If there was a trailer before
                CVehicle* pCurrentTrailer = pTowedByVehicle->GetTowedVehicle ();
                if ( pCurrentTrailer )
                {
                    pTowedByVehicle->SetTowedVehicle ( NULL );
                    pCurrentTrailer->SetTowedByVehicle ( NULL );

                    // Tell everyone else to detach them
                    CVehicleTrailerPacket AttachPacket ( pTowedByVehicle, pCurrentTrailer, false );
                    g_pGame->GetPlayerManager ()->BroadcastOnlyJoined ( AttachPacket );

                    // Execute the detach trailer script function
                    CLuaArguments Arguments;
                    Arguments.PushElement ( pTowedByVehicle );
                    pCurrentTrailer->CallEvent ( "onTrailerDetach", Arguments );                    
                }
            }

            // Player health
            SPlayerHealthSync health;
            if ( !BitStream.Read ( &health ) )
                return false;
            float fHealth = health.data.fValue;

            float fOldHealth = pSourcePlayer->GetHealth ();
			float fHealthLoss = fOldHealth - fHealth;

            // Less than last packet's frame?
            if ( fHealth < fOldHealth && fHealthLoss > 0 )
            {
                // Call the onPlayerDamage event
                CLuaArguments Arguments;
                Arguments.PushNil ();
                Arguments.PushNumber ( false );
                Arguments.PushNumber ( false );
                Arguments.PushNumber ( fHealthLoss );
                pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments );
            }
            pSourcePlayer->SetHealth ( fHealth );

			// Armor
            SPlayerArmorSync armor;
            if ( !BitStream.Read ( &armor ) )
                return false;
            float fArmor = armor.data.fValue;

			float fOldArmor = pSourcePlayer->GetArmor ();
			float fArmorLoss = fOldArmor - fArmor;

			// Less than last packet's frame?
			if ( fArmor < fOldArmor && fArmorLoss > 0 )
			{
				// Call the onPlayerDamage event
				CLuaArguments Arguments;
                Arguments.PushNil ();
                Arguments.PushNumber ( false );
                Arguments.PushNumber ( false );
				Arguments.PushNumber ( fArmorLoss );

				pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments );					
			}
            pSourcePlayer->SetArmor ( fArmor );

            // Flags
            SVehiclePuresyncFlags flags;
            if ( !BitStream.Read ( &flags ) )
                return false;

            pSourcePlayer->SetWearingGoggles ( flags.data.bIsWearingGoggles );
            pSourcePlayer->SetDoingGangDriveby ( flags.data.bIsDoingGangDriveby );            

            // Weapon sync
            if ( flags.data.bHasAWeapon )
            {
                SWeaponSlotSync slot;
                if ( !BitStream.Read ( &slot ) )
                    return false;

                pSourcePlayer->SetWeaponSlot ( slot.data.uiSlot );

                if ( flags.data.bIsDoingGangDriveby && CWeaponNames::DoesSlotHaveAmmo ( slot.data.uiSlot ) )
                {
                    // Read the ammo states
                    SWeaponAmmoSync ammo ( pSourcePlayer->GetWeaponType (), false, true );
                    if ( !BitStream.Read ( &ammo ) )
                        return false;
                    pSourcePlayer->SetWeaponAmmoInClip ( ammo.data.usAmmoInClip );

                    // Read aim data
                    SWeaponAimSync aim ( pSourcePlayer->GetWeaponRange (), true );
                    if ( !BitStream.Read ( &aim ) )
                        return false;
                    pSourcePlayer->SetAimDirection ( aim.data.fArm );
                    pSourcePlayer->SetSniperSourceVector ( aim.data.vecOrigin );
                    pSourcePlayer->SetTargettingVector ( aim.data.vecTarget );

                    // Read the driveby direction
                    SDrivebyDirectionSync driveby;
                    if ( !BitStream.Read ( &driveby ) )
                        return false;
                    pSourcePlayer->SetDriveByDirection ( driveby.data.ucDirection );
                }
            }
            else
                pSourcePlayer->SetWeaponSlot ( 0 );


            // Vehicle specific data if he's the driver
            if ( uiSeat == 0 )
            {
                ReadVehicleSpecific ( pVehicle, BitStream );

                // Set vehicle specific stuff if he's the driver
                pVehicle->SetSirenActive ( flags.data.bIsSirenOrAlarmActive );
                pVehicle->SetSmokeTrailEnabled ( flags.data.bIsSmokeTrailEnabled );
                pVehicle->SetLandingGearDown ( flags.data.bIsLandingGearDown );
                pVehicle->SetOnGround ( flags.data.bIsOnGround );
                pVehicle->SetInWater ( flags.data.bIsInWater );
                pVehicle->SetDerailed ( flags.data.bIsDerailed );
                pVehicle->SetHeliSearchLightVisible ( flags.data.bIsHeliSearchLightVisible );
            }

            // Read the vehicle_look_left and vehicle_look_right control states
            // if it's an aircraft.
            if ( flags.data.bIsAircraft )
            {
                ControllerState.LeftShoulder2 = BitStream.ReadBit () * 255;
                ControllerState.RightShoulder2 = BitStream.ReadBit () * 255;
            }

            pSourcePlayer->GetPad ()->NewControllerState ( ControllerState );

            // Success
            return true;
        }
    }

    return false;
}
int CLuaFunctionDefs::Load( lua_State* luaVM )
{
//  func,err load( callback callbackFunction[, string name] )
    CLuaFunctionRef iLuaFunction; SString strName;

    CScriptArgReader argStream( luaVM );
    argStream.ReadFunction( iLuaFunction );
    argStream.ReadString( strName, "=(load)" );
    argStream.ReadFunctionComplete();

    if ( !argStream.HasErrors() )
    {
        // Call supplied function to get all the bits
        // Should apply some limit here?
        SString strInput;
        CLuaArguments callbackArguments;
        CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine( luaVM );
        while( pLuaMain )
        {
            CLuaArguments returnValues;
            callbackArguments.Call( pLuaMain, iLuaFunction, &returnValues );
            if ( returnValues.Count() )
            {
                CLuaArgument* returnedValue = *returnValues.IterBegin();
                if ( returnedValue->GetType() == LUA_TSTRING )
                {
                    strInput += returnedValue->GetString();
                    continue;
                }
            }
            break;
        }

        const char* szChunkname = *strName;
        const char* cpInBuffer = strInput;
        uint uiInSize = strInput.length();

        // Decrypt if required
        const char* cpBuffer;
        uint uiSize;
        if ( !g_pNet->DecryptScript( cpInBuffer, uiInSize, &cpBuffer, &uiSize, m_pResourceManager->GetResourceName( luaVM ) + "/load" ) )
        {
            SString strMessage( "argument 2 is invalid. Please re-compile at http://luac.mtasa.com/", 0 ); 
            argStream.SetCustomError( strMessage );
            cpBuffer = NULL;
            g_pCore->GetConsole()->Print( argStream.GetFullErrorMessage() );
            g_pClientGame->TellServerSomethingImportant( 1005, argStream.GetFullErrorMessage(), true );
        }

        if ( !argStream.HasErrors() )
        {
            CLuaShared::CheckUTF8BOMAndUpdate ( &cpBuffer, &uiSize );
            if ( !CLuaMain::LuaLoadBuffer( luaVM, cpBuffer, uiSize, szChunkname ) )
            {
                // Ok
                return 1;
            }
            else
            {
                lua_pushnil( luaVM );
                lua_insert( luaVM, -2 );  /* put before error message */
                return 2;  /* return nil plus error message */
            }
        }
    }
    if ( argStream.HasErrors() )
        m_pScriptDebugging->LogCustom( luaVM, argStream.GetFullErrorMessage() );

    lua_pushboolean( luaVM, false );
    return 1;
}
示例#30
0
void CClientWebBrowser::Events_OnDocumentReady ( const SString& strURL )
{
    CLuaArguments Arguments;
    Arguments.PushString ( strURL );
    CallEvent ( "onClientBrowserDocumentReady", Arguments, false );
}