예제 #1
0
void CElement::DeleteCustomData ( const char* szName )
{
    // Grab the old variable
    SCustomData * pData = m_pCustomData->Get ( szName );
    if ( pData )
    {
        CLuaArgument oldVariable;
        oldVariable = pData->Variable;

        // Delete the custom data
        m_pCustomData->Delete ( szName );

        // Trigger the onElementDataChange event on us
        CLuaArguments Arguments;
        Arguments.PushString ( szName );
        Arguments.PushArgument ( oldVariable );
        Arguments.PushArgument ( CLuaArgument() );  // Use nil as the new value to indicate the data has been removed
        CallEvent ( "onElementDataChange", Arguments );
    }
}
예제 #2
0
void CElement::SetCustomData ( const char* szName, const CLuaArgument& Variable, CLuaMain* pLuaMain, bool bSynchronized )
{
    assert ( szName );

    // Grab the old variable
    CLuaArgument oldVariable;
    const SCustomData * pData = m_pCustomData->Get ( szName );
    if ( pData )
    {
        oldVariable = pData->Variable;
    }

    // Set the new data
    m_pCustomData->Set ( szName, Variable, pLuaMain, bSynchronized );

    // Trigger the onElementDataChange event on us
    CLuaArguments Arguments;
    Arguments.PushString ( szName );
    Arguments.PushArgument ( oldVariable  );
    CallEvent ( "onElementDataChange", Arguments );
}
예제 #3
0
void CClientEntity::SetCustomData ( const char* szName, const CLuaArgument& Variable, CLuaMain* pLuaMain )
{
    assert ( szName );

    // Grab the old variable
    CLuaArgument oldVariable;
    SCustomData * pData = m_pCustomData->Get ( szName );
    if ( pData )
    {
        oldVariable = pData->Variable;
    }

    // Set the new data
    m_pCustomData->Set ( szName, Variable, pLuaMain );

    // Trigger the onClientElementDataChange event on us
    CLuaArguments Arguments;
    Arguments.PushString ( szName );
    Arguments.PushArgument ( oldVariable  );
    CallEvent ( "onClientElementDataChange", Arguments, true );
}
int CLuaFunctionDefs::GetBrowserSource ( lua_State* luaVM )
{
//  bool getBrowserSource ( function callback )
    CClientWebBrowser* pWebBrowser; CLuaFunctionRef callbackFunction;

    CScriptArgReader argStream ( luaVM );
    argStream.ReadUserData ( pWebBrowser );
    argStream.ReadFunction ( callbackFunction );
    argStream.ReadFunctionComplete ();

    if ( !argStream.HasErrors () )
    {
        CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM );
        if ( pLuaMain && VERIFY_FUNCTION ( callbackFunction ) )
        {
            pWebBrowser->GetSourceCode ( [callbackFunction, pLuaMain]( const std::string& code ) {
                /*
                    This function should not be called when the resource is about to stop as
                    stopping the resource destroys the browser element and thus cancels the 
                    CefStringVisitor callback class (see CWebView::GetSourceCode::MyStringVisitor)
                */
                if ( VERIFY_FUNCTION ( callbackFunction ) )
                {
                    CLuaArguments arguments;
                    // TODO: Use SCharStringRef/direct string access instead of copying strings around
                    arguments.PushString ( code );
                    arguments.Call ( pLuaMain, callbackFunction );
                }
            });

            lua_pushboolean ( luaVM, true );
            return 1;
        }
    }
    else
        m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () );

    lua_pushboolean ( luaVM, false );
    return 1;
}
예제 #5
0
void CElementDeleter::Delete ( class CElement* pElement, bool bUnlink, bool bUpdatePerPlayerEntities, CResource* pDebugResource, const char* szDebugText )
{
    if ( pElement )
    {
        if ( !IsBeingDeleted ( pElement ) )
        {
            // Before we do anything, fire the on-destroy event
            CLuaArguments Arguments;
            if ( pDebugResource )
                Arguments.PushResource( pDebugResource );
            else
                Arguments.PushNil();
            Arguments.PushString( szDebugText );
            pElement->CallEvent ( "onElementDestroy", Arguments );

            // Add it to our list
            if ( !pElement->IsBeingDeleted () )
            {
                m_List.push_back ( pElement );
            }

            // Flag it as being deleted and unlink it from the tree/managers
            pElement->SetIsBeingDeleted ( true );
            pElement->ClearChildren ();
            pElement->SetParentObject ( NULL, bUpdatePerPlayerEntities );

            if ( bUnlink )
                pElement->Unlink ();
        }
        else
        {
            if ( pElement->GetType ( ) == CElement::PLAYER )
            {
                // Tell the console
                CLogger::LogPrint ( "URGENT: Report this error on bugs.mtasa.com error code: 6930-1\n" );
            }
        }
    }
}
예제 #6
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 );
        }
    }
}
예제 #7
0
ResponseCode CResourceHTMLItem::Request ( HttpRequest * ipoHttpRequest, HttpResponse * ipoHttpResponse, CAccount * account )
{
    if ( !m_pVM )
        Start ();

    if ( m_bIsBeingRequested )
    {
        ipoHttpResponse->SetBody ( "Busy!", strlen("Busy!") );
        return HTTPRESPONSECODE_500_INTERNALSERVERERROR;
    }

    m_bIsBeingRequested = true;

    m_responseCode = HTTPRESPONSECODE_200_OK;

    if ( !m_bIsRaw )
    {
        ipoHttpResponse->oResponseHeaders [ "content-type" ] = m_strMime;

        CLuaArguments formData;
        for ( FormValueMap::iterator iter = ipoHttpRequest->oFormValueMap.begin(); iter != ipoHttpRequest->oFormValueMap.end(); iter++ )
        {
            formData.PushString ( (*iter).first.c_str() );
            formData.PushString ( ((FormValue)(*iter).second).sBody.c_str() );
        }

        CLuaArguments cookies;
        for ( CookieMap::iterator iter = ipoHttpRequest->oCookieMap.begin(); iter != ipoHttpRequest->oCookieMap.end(); iter++ )
        {
            cookies.PushString ( (*iter).first.c_str() );
            cookies.PushString ( (*iter).second.c_str() );
        }

        CLuaArguments headers;
        for ( StringMap::iterator iter = ipoHttpRequest->oRequestHeaders.begin(); iter != ipoHttpRequest->oRequestHeaders.end(); iter++ )
        {
            headers.PushString ( (*iter).first.c_str() );
            headers.PushString ( (*iter).second.c_str() );
        }

        m_currentResponse = ipoHttpResponse;
        CLuaArguments querystring ( formData );
        CLuaArguments args;
        args.PushTable ( &headers ); // requestHeaders
        args.PushTable ( &formData ); // form
        args.PushTable ( &cookies ); // cookies
        args.PushString ( ipoHttpRequest->GetAddress().c_str() ); // hostname
        args.PushString ( ipoHttpRequest->sOriginalUri.c_str() ); // url
        args.PushTable ( &querystring ); // querystring
        args.PushAccount ( account );

       // g_pGame->Lock(); // get the mutex (blocking)
        args.CallGlobal ( m_pVM, "renderPage" );
       // g_pGame->Unlock(); // release the mutex

        ipoHttpResponse->SetBody ( m_strPageBuffer.c_str (), m_strPageBuffer.size () );
        m_strPageBuffer.clear ();
    }
    else
    {
        // its a raw page
        FILE * file = fopen ( m_strResourceFileName.c_str (), "rb" );
        if ( file )
        {
            fseek ( file, 0, SEEK_END );
            long lBufferLength = ftell ( file );
            char* pBuffer = new char [ lBufferLength ];
            rewind ( file );
            fread ( pBuffer, 1, lBufferLength, file );
            fclose ( file );
            ipoHttpResponse->oResponseHeaders [ "content-type" ] = m_strMime;
            ipoHttpResponse->SetBody ( pBuffer, lBufferLength );
            delete[] pBuffer;
        }
        else
        {
            ipoHttpResponse->SetBody ( "Can't read file!", strlen("Can't read file!") );
        }
    }
    m_bIsBeingRequested = false;
    return m_responseCode;
}
예제 #8
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;
}
예제 #9
0
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 );
}
예제 #10
0
void CClientWebBrowser::Events_OnTooltip ( const SString& strTooltip )
{
    CLuaArguments Arguments;
    Arguments.PushString ( strTooltip );
    CallEvent ( "onClientBrowserTooltip", Arguments, false );
}
예제 #11
0
void CClientWebBrowser::Events_OnDocumentReady ( const SString& strURL )
{
    CLuaArguments Arguments;
    Arguments.PushString ( strURL );
    CallEvent ( "onClientBrowserDocumentReady", Arguments, false );
}
예제 #12
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;
}
예제 #13
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;
}
예제 #14
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 )
    {
        //char szBuffer [256];
        CLuaArguments Arguments;

        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 )
            {
                /* This code seems redundant, the chatbox now properly simulates commands.
                // His line starts with '/'?
                if ( *szArguments == '/' )
                {
                    // Copy the characters after the slash to the 0 terminator to a seperate buffer
                    strncpy ( szBuffer, &szArguments [ 1 ], 256 );
                    szBuffer [ 255 ] = 0;

                    // Split it into command and arguments
                    char* szNewCommand = strtok ( szBuffer, " " );
                    char* szNewArguments = strtok ( NULL, "\0" );
                    if ( szNewCommand )
                    {
                        // Execute it as another command
                        if ( szNewArguments )
                        {
                            g_pCore->GetCommands ()->Execute ( szNewCommand, szNewArguments );
                        }
                        else
                        {
                            g_pCore->GetCommands ()->Execute ( szNewCommand, "" );
                        }

                        return true;
                    }
                }
                */
                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
        Arguments.PushString ( strClumpedCommand );

        // Call the event on the local player's onClientConsole first
        if ( g_pClientGame->GetLocalPlayer () )
            g_pClientGame->GetLocalPlayer ()->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;
}
int CLuaFunctionDefs::SetBrowserAjaxHandler ( lua_State* luaVM )
{
    //  bool setBrowserAjaxHandler ( browser browser, string URL[, function callback] )
    CClientWebBrowser* pWebBrowser; SString strURL; CLuaFunctionRef callbackFunction;

    CScriptArgReader argStream ( luaVM );
    argStream.ReadUserData ( pWebBrowser );
    argStream.ReadString ( strURL );

    if ( argStream.NextIsNil () || argStream.NextIsNone () )
    {
        if ( !argStream.HasErrors () )
        {
            lua_pushboolean ( luaVM, pWebBrowser->RemoveAjaxHandler ( strURL ) );
            return 1;
        }
        else
            m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () );
    }
    else
    {
        argStream.ReadFunction ( callbackFunction );
        argStream.ReadFunctionComplete ();
        if ( !argStream.HasErrors () )
        {
            CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM );
            if ( pLuaMain && VERIFY_FUNCTION ( callbackFunction ) )
            {
                CResource* pResource = pLuaMain->GetResource ();
                CResourceManager * pResourceManager = m_pResourceManager;
                auto netId = pResource->GetNetID ();

                bool bResult = pWebBrowser->AddAjaxHandler ( strURL, 
                [=] ( std::vector<SString>& vecGet, std::vector<SString>& vecPost ) -> const SString
                {
                    // Make sure the resource is still running
                    if ( !pResourceManager->Exists ( pResource ) || pResource->GetNetID() != netId )
                    {
                        return "";
                    }

                    // Make sure the function is valid
                    if ( VERIFY_FUNCTION ( callbackFunction ) )
                    {
                        CLuaArguments arguments;
                        CLuaArguments getArguments;
                        CLuaArguments postArguments;

                        for ( auto&& param : vecGet )
                            getArguments.PushString ( param );

                        for ( auto&& param : vecPost )
                            postArguments.PushString ( param );

                        arguments.PushTable ( &getArguments );
                        arguments.PushTable ( &postArguments );

                        CLuaArguments result;
                        
                        arguments.Call ( pLuaMain, callbackFunction, &result );

                        if ( result.Count () == 0 )
                            return "";


                        CLuaArgument* returnedValue = *result.IterBegin ();
                        if ( returnedValue->GetType () == LUA_TSTRING )                       
                            return returnedValue->GetString ();
                        else
                            return "";
                    }
                    else
                        return "";

                } );

                lua_pushboolean ( luaVM, bResult );
                return 1;
            }
        }
        else
            m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () );
    }

    lua_pushboolean ( luaVM, false );
    return 1;
}
예제 #16
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 );
        }
    }
}
예제 #17
0
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 onClientDebugMessage
    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", szPrePend, 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 );

    if ( !m_bTriggeringOnClientDebugMessage )
    {
        m_bTriggeringOnClientDebugMessage = true;

        // Prepare onClientDebugMessage
        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 onClientDebugMessage
        g_pClientGame->GetRootEntity ( )->CallEvent ( "onClientDebugMessage", Arguments, false );

        m_bTriggeringOnClientDebugMessage = false;
    }

    // Log it to the file if enough level
    if ( m_uiLogFileLevel >= uiMinimumDebugLevel )
    {
        PrintLog ( strText );
    }
    switch ( uiMinimumDebugLevel )
    {
    case 1:
        ucRed = 255, ucGreen = 0, ucBlue = 0;
        break;
    case 2:
        ucRed = 255, ucGreen = 128, ucBlue = 0;
        break;
    case 3:
        ucRed = 0, ucGreen = 255, ucBlue = 0;
        break;
    }
#ifdef MTA_DEBUG
    if ( !g_pCore->IsDebugVisible () ) return;
#endif
    g_pCore->DebugEchoColor ( strText, ucRed, ucGreen, ucBlue );
}
int CLuaFunctionDefs::GetCTime ( lua_State* luaVM )
{
    // table getRealTime( [int seconds = current], bool localTime = true )
    time_t timer;
    time ( &timer );
    bool bLocalTime = true;
    CScriptArgReader argStream ( luaVM );

    if ( argStream.NextCouldBeNumber () )
    {
        argStream.ReadNumber ( timer );
        if ( timer < 0 )
        {
            argStream.SetCustomError ( "seconds cannot be negative" );
        }
    }

    if ( argStream.NextIsBool () )
        argStream.ReadBool ( bLocalTime );

    tm * time;
    if ( bLocalTime )
        time = localtime ( &timer );
    else
        time = gmtime ( &timer );

    if ( time == NULL )
        argStream.SetCustomError ( "seconds is out of range" );

    if ( argStream.HasErrors () )
    {
        m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () );
        lua_pushboolean ( luaVM, false );
        return 1;
    }

    CLuaArguments ret;
    ret.PushString ( "second" );
    ret.PushNumber ( time->tm_sec );
    ret.PushString ( "minute" );
    ret.PushNumber ( time->tm_min );
    ret.PushString ( "hour" );
    ret.PushNumber ( time->tm_hour );
    ret.PushString ( "monthday" );
    ret.PushNumber ( time->tm_mday );
    ret.PushString ( "month" );
    ret.PushNumber ( time->tm_mon );
    ret.PushString ( "year" );
    ret.PushNumber ( time->tm_year );
    ret.PushString ( "weekday" );
    ret.PushNumber ( time->tm_wday );
    ret.PushString ( "yearday" );
    ret.PushNumber ( time->tm_yday );
    ret.PushString ( "isdst" );
    ret.PushNumber ( time->tm_isdst );
    ret.PushString ( "timestamp" );
    ret.PushNumber ( (double) timer );

    ret.PushAsTable ( luaVM );

    return 1;
}
예제 #19
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;
    }

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

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

#if 0
    // 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/>" );
                }
            }
        }
    }
#endif

    // Tell the players
    Broadcast ( CDebugEchoPacket ( strText, uiMinimumDebugLevel, ucRed, ucGreen, ucBlue ), uiMinimumDebugLevel );
}
예제 #20
0
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;
}
예제 #21
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
        }
    }
}