예제 #1
0
void CClientEntity::_GetEntitiesFromRoot ( unsigned int uiTypeHash, std::map < CClientEntity*, int >& mapResults )
{
    t_mapEntitiesFromRoot::iterator find = ms_mapEntitiesFromRoot.find ( uiTypeHash );
    if ( find != ms_mapEntitiesFromRoot.end () )
    {
        const std::list < CClientEntity* >& listEntities = find->second;
        CClientEntity* pEntity;
        unsigned int uiIndex = 0;

        for ( std::list < CClientEntity* >::const_reverse_iterator i = listEntities.rbegin ();
              i != listEntities.rend ();
              ++i )
        {
            pEntity = *i;

            assert ( pEntity );
            ElementID ID = pEntity->GetID ();
            assert ( ID != INVALID_ELEMENT_ID );
            assert ( pEntity == CElementIDs::GetElement ( ID ) );
            if ( pEntity->IsBeingDeleted () )
                OutputDebugString ( SString ( "Client: 0x%08x  %s is flagged as IsBeingDeleted() but is still in GetEntitiesFromRoot\n", pEntity, pEntity->GetTypeName () ) );

            assert ( mapResults.find ( pEntity ) == mapResults.end () );
            mapResults [ pEntity ] = 1;
        }
    }    
}
///////////////////////////////////////////////////////////////
//
// CGameEntityXRefManagerImpl::OnGameEntityDestruct
//
// Called when GTA is destroying a game entity
//
///////////////////////////////////////////////////////////////
void CGameEntityXRefManagerImpl::OnGameEntityDestruct ( CEntitySAInterface* pEntitySAInterface )
{
    if ( MapContains ( m_InterfaceToClientMap, pEntitySAInterface ) )
    {
        BYTE* pInterface = (BYTE*)pEntitySAInterface;
        DWORD InterfaceVtbl = *(DWORD*)pInterface;
        ushort InterfaceModelId = *(ushort*)(pInterface + 34);
        CClientEntity* pClientEntity = MapFindRef ( m_InterfaceToClientMap, pEntitySAInterface );
        bool bClientEntityValid = MapContains ( m_ValidClientEntityMap, pClientEntity );

        SString strClientEntityInfo;
        if ( bClientEntityValid )
        {
            CEntity* pGameEntity = NULL;

            if ( CClientPed* pPed = DynamicCast < CClientPed > ( pClientEntity ) )
                pGameEntity = pPed->GetGameEntity ();

            if ( CClientVehicle* pVehicle = DynamicCast < CClientVehicle > ( pClientEntity ) )
                pGameEntity = pVehicle->GetGameEntity ();

            if ( CClientObject* pObject = DynamicCast < CClientObject > ( pClientEntity ) )
                pGameEntity = pObject->GetGameEntity ();

            if ( CClientProjectile* pProjectile = DynamicCast < CClientProjectile > ( pClientEntity ) )
                pGameEntity = pProjectile->GetGameEntity ();

            if ( CClientPickup* pPickup = DynamicCast < CClientPickup > ( pClientEntity ) )
                pGameEntity = pPickup->GetGameObject ();

            CEntity* pMappedGameEntity = MapFindRef ( m_ClientToGameMap, pClientEntity );
            CClientEntity* pMappedClientEntity = MapFindRef ( m_GameToClientMap, pGameEntity );


            strClientEntityInfo = SString ( "%s Id:%x GameEntity:%08x MappedGameEntity:%08x MappedClientEntity:%08x"
                                            , pClientEntity->GetClassName ()
                                            , pClientEntity->GetID ()
                                            , (int)pGameEntity
                                            , (int)pMappedGameEntity
                                            , (int)pMappedClientEntity
                                        );
        }

        SString strMessage ( "EntitySAInterface:%08x  Vtbl:%08x  ModelId:%d   ClientEntity:%08x  [%s]"
                                , (int)pEntitySAInterface
                                , InterfaceVtbl
                                , InterfaceModelId
                                , (int)pClientEntity
                                , *strClientEntityInfo
                                );

        g_pCore->LogEvent ( 8542, "XRefManager", "GameEntity Mismatch", strMessage );
        AddReportLog ( 8542, strMessage );
        dassert ( 0 );
    }
}
예제 #3
0
bool CLuaArgument::WriteToBitStream ( NetBitStreamInterface& bitStream, std::map < CLuaArguments*, unsigned long > * pKnownTables ) const
{
    SLuaTypeSync type;

    switch ( GetType () )
    {
        // Nil type
        case LUA_TNIL:
        {
            type.data.ucType = LUA_TNIL;
            bitStream.Write ( &type );
            break;
        }

        // Boolean type
        case LUA_TBOOLEAN:
        {
            type.data.ucType = LUA_TBOOLEAN;
			bitStream.Write ( &type );

            // Write the boolean to it
            bitStream.WriteBit ( GetBoolean () );
            break;
        }

        // Table argument
        case LUA_TTABLE:
        {
            if ( pKnownTables && pKnownTables->find ( m_pTableData ) != pKnownTables->end () )
            {
                // Self-referencing table
                type.data.ucType = LUA_TTABLEREF;
                bitStream.Write ( &type );
                bitStream.WriteCompressed ( pKnownTables->find ( m_pTableData )->second );
            }
            else
            {
                type.data.ucType = LUA_TTABLE;
                bitStream.Write ( &type );

                // Write the subtable to the bitstream
                m_pTableData->WriteToBitStream ( bitStream, pKnownTables );
            }
            break;
        }

        // Number argument?
        case LUA_TNUMBER:
        {
            type.data.ucType = LUA_TNUMBER;
            bitStream.Write ( &type );
            float fNumber = static_cast < float > ( GetNumber () );
            long lNumber = static_cast < long > ( fNumber );
            float fNumberInteger = static_cast < float > ( lNumber );

            // Check if the number is an integer and can fit a long datatype
            if ( fabs ( fNumber ) > fabs ( fNumberInteger + 1 ) ||
                 fabs ( fNumber - fNumberInteger ) >= FLOAT_EPSILON )
            {
                bitStream.WriteBit ( true );
                bitStream.Write ( fNumber );
            }
            else
            {
                bitStream.WriteBit ( false );
                bitStream.WriteCompressed ( lNumber );
            }
            break;
        }

        // String argument
        case LUA_TSTRING:
        {           
            // Grab the string and its length. Is it short enough to be sendable?
            const char* szTemp = m_strString.c_str ();
            size_t sizeTemp = strlen ( szTemp );
            unsigned short usLength = static_cast < unsigned short > ( sizeTemp );
			if ( sizeTemp == usLength )
			{
                // This is a string argument
                type.data.ucType = LUA_TSTRING;
			    bitStream.Write ( &type );

                // Write its length
				bitStream.WriteCompressed ( usLength );

                // Write the content too if it's not empty
                if ( usLength > 0 )
                {
				    bitStream.Write ( const_cast < char* > ( szTemp ), usLength );
                }
			}
			else
			{
                // Too long string
                LogUnableToPacketize ( "Couldn't packetize argument list. Invalid string specified, limit is 65535 characters." );

                // Write a nil though so other side won't get out of sync
                bitStream.Write ( (unsigned char) LUA_TNIL );
                return false;
			}
            break;
        }

        // Element packet
        case LUA_TLIGHTUSERDATA:
        {
            // Got a valid element to send?
            CClientEntity* pElement = GetElement ();
			if ( pElement )
			{
                // Clientside element?
                if ( !pElement->IsLocalEntity () )
                {
                    type.data.ucType = LUA_TLIGHTUSERDATA;
	    			bitStream.Write ( &type );
    				bitStream.WriteCompressed ( static_cast < ElementID > ( pElement->GetID () ) );
                }
                else
                {
                    // Write a nil though so other side won't get out of sync
                    type.data.ucType = LUA_TNIL;
                    bitStream.Write ( &type );
                    return false;
                }
			}
			else
			{
                // Write a nil though so other side won't get out of sync
                type.data.ucType = LUA_TNIL;
                bitStream.Write ( &type );
				return false;
			}
            break;
        }

        // Unpacketizable type.
		default:
		{
            // Unpacketizable
			LogUnableToPacketize ( "Couldn't packetize argument list, unknown type specified." );

            // Write a nil though so other side won't get out of sync
            type.data.ucType = LUA_TNIL;
            bitStream.Write ( &type );
			return false;
		}
    }

    // Success
    return true;
}
예제 #4
0
char * CLuaArgument::WriteToString ( char * szBuffer, int length )
{
    switch ( GetType () )
    {
        case LUA_TNIL:
        {
            snprintf ( szBuffer, length, "0" );
            return szBuffer;
        }
        case LUA_TBOOLEAN:
        {
            if ( GetBoolean () )
                snprintf ( szBuffer, length, "true" );
            else
                snprintf ( szBuffer, length, "false" );
            return szBuffer;
        }
        case LUA_TTABLE:
        {
            g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Cannot convert table to string (do not use tables as keys in tables if you want to send them over http/JSON)." );
            return NULL;
        }
        case LUA_TNUMBER:
        {
            int iNumber;
            if ( ShouldUseInt( GetNumber(), &iNumber ) )
            {
                snprintf ( szBuffer, length, "%d", iNumber );
                return szBuffer;
            }
            else
            {
                snprintf ( szBuffer, length, "%f", static_cast < float > ( GetNumber() ) );
                return szBuffer;
            }
            break;
        }
        case LUA_TSTRING:
        {
            const char* szTemp = GetString ();
            unsigned short usLength = static_cast < unsigned short > ( strlen ( szTemp ) );
            if ( strlen ( szTemp ) == usLength )
            {
                snprintf ( szBuffer, length, "%s", szTemp );
                return szBuffer;
            }
            else
            {
                g_pClientGame->GetScriptDebugging()->LogError ( NULL, "String is too long. Limit is 65535 characters." );
            }
            break;
        }
        case LUA_TLIGHTUSERDATA:
        case LUA_TUSERDATA:
        {
            CClientEntity* pElement = GetElement ();
            CResource* pResource = reinterpret_cast < CResource* > ( GetUserData() );
            if ( pElement )
            {
                snprintf ( szBuffer, length, "#E#%d", (int)pElement->GetID().Value() );
                return szBuffer;
            }
            else if ( VERIFY_RESOURCE(pResource) )
            {
                snprintf ( szBuffer, length, "#R#%s", pResource->GetName()/*.c_str ()*/ );
                return szBuffer;
            }
            else
            {
                g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert element to string, only valid elements can be sent." );
                return NULL;
            }
            break;
        }
        default:
        {
            g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument to string, unsupported data type. Use String, Number, Boolean or Element." );
            return NULL;
        }
    }
    return NULL;
}
예제 #5
0
json_object * CLuaArgument::WriteToJSONObject ( bool bSerialize, CFastHashMap < CLuaArguments*, unsigned long > * pKnownTables )
{
    switch ( GetType () )
    {
        case LUA_TNIL:
        {
            return json_object_new_int(0);
        }
        case LUA_TBOOLEAN:
        {
            return json_object_new_boolean(GetBoolean ());
        }
        case LUA_TTABLE:
        {
            ulong* pTableId;
            if ( pKnownTables && ( pTableId = MapFind ( *pKnownTables, m_pTableData ) ) )
            {
                // Self-referencing table
                char szTableID[10];
                snprintf ( szTableID, sizeof(szTableID), "^T^%lu", *pTableId );
                return json_object_new_string ( szTableID );
            }
            else
            {
                return m_pTableData->WriteTableToJSONObject ( bSerialize, pKnownTables );
            }
        }
        case LUA_TNUMBER:
        {
            int iNumber;
            if ( ShouldUseInt( GetNumber(), &iNumber ) )
            {
                return json_object_new_int( iNumber );
            }
            else
            {
                return json_object_new_double( static_cast < float > ( GetNumber() ) );
            }
            break;
        }
        case LUA_TSTRING:
        {
            const char* szTemp = GetString ();
            unsigned short usLength = static_cast < unsigned short > ( strlen ( szTemp ) );
            if ( strlen ( szTemp ) == usLength )
            {
                return json_object_new_string_len ( (char *)szTemp, usLength );
            }
            else
            {
                g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON. Invalid string specified, limit is 65535 characters." );
            }
            break;
        }
        case LUA_TUSERDATA:
        case LUA_TLIGHTUSERDATA:
        {
            CClientEntity* pElement = GetElement ();
            CResource* pResource = g_pClientGame->GetResourceManager ()->GetResourceFromScriptID ( reinterpret_cast < unsigned long > ( GetUserData () ) );

            // Elements are dynamic, so storing them is potentially unsafe
            if ( pElement && bSerialize )
            {
                char szElementID[10] = {0};
                snprintf ( szElementID, 9, "^E^%d", (int)pElement->GetID().Value() );
                return json_object_new_string ( szElementID );
            }
            else if ( VERIFY_RESOURCE(pResource) )
            {
                char szElementID[MAX_RESOURCE_NAME_LENGTH+4] = {0};
                snprintf ( szElementID, MAX_RESOURCE_NAME_LENGTH+3, "^R^%s", pResource->GetName()/*.c_str ()*/ );
                return json_object_new_string ( szElementID );
            }
            else
            {
                if ( pElement )     // eg toJSON() with valid element
                    g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert userdata argument to JSON, elements not allowed for this function." );
                else
                if ( !bSerialize )  // eg toJSON() with invalid element
                    g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert userdata argument to JSON, only valid resources can be included for this function." );
                else
                    g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert userdata argument to JSON, only valid elements or resources can be included." );
                return NULL;
            }
            break;
        }
        default:
        {
            g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON, unsupported data type. Use Table, Nil, String, Number, Boolean, Resource or Element." );
            return NULL;
        }
    }
    return NULL;
}
예제 #6
0
bool CLuaArgument::WriteToBitStream ( NetBitStreamInterface& bitStream, CFastHashMap < CLuaArguments*, unsigned long > * pKnownTables ) const
{
    SLuaTypeSync type;

    switch ( GetType () )
    {
        // Nil type
        case LUA_TNIL:
        {
            type.data.ucType = LUA_TNIL;
            bitStream.Write ( &type );
            break;
        }

        // Boolean type
        case LUA_TBOOLEAN:
        {
            type.data.ucType = LUA_TBOOLEAN;
            bitStream.Write ( &type );

            // Write the boolean to it
            bitStream.WriteBit ( GetBoolean () );
            break;
        }

        // Table argument
        case LUA_TTABLE:
        {
            ulong* pTableId;
            if ( pKnownTables && ( pTableId = MapFind ( *pKnownTables, m_pTableData ) ) )
            {
                // Self-referencing table
                type.data.ucType = LUA_TTABLEREF;
                bitStream.Write ( &type );
                bitStream.WriteCompressed ( *pTableId );
            }
            else
            {
                type.data.ucType = LUA_TTABLE;
                bitStream.Write ( &type );

                // Write the subtable to the bitstream
                m_pTableData->WriteToBitStream ( bitStream, pKnownTables );
            }
            break;
        }

        // Number argument?
        case LUA_TNUMBER:
        {
            type.data.ucType = LUA_TNUMBER;
            bitStream.Write ( &type );

            if ( bitStream.Version() < 0x59 )
            {
                // Old way
                int iNumber;
                if ( !ShouldUseInt( GetNumber(), &iNumber ) )
                {
                    bitStream.WriteBit ( true );
                    bitStream.Write ( static_cast < float > ( GetNumber() ) );
                }
                else
                {
                    bitStream.WriteBit ( false );
                    bitStream.WriteCompressed ( iNumber );
                }
            }
            else
            {
                // New way - Maybe use double to better preserve > 32bit numbers
                int iNumber;
                float fNumber;
                double dNumber;
                EDataType dataType = GetDataTypeToUse( GetNumber(), &iNumber, &fNumber, &dNumber );
                if ( dataType == DATA_TYPE_INT )
                {
                    bitStream.WriteBit ( false );
                    bitStream.WriteCompressed ( iNumber );
                }
                else
                if ( dataType == DATA_TYPE_FLOAT )
                {
                    bitStream.WriteBit ( true );
                    bitStream.WriteBit ( false );
                    bitStream.Write ( fNumber );
                }
                else
                {
                    bitStream.WriteBit ( true );
                    bitStream.WriteBit ( true );
                    bitStream.Write ( dNumber );
                }
            }
            break;
        }

        // String argument
        case LUA_TSTRING:
        {           
            // Grab the string and its length. Is it short enough to be sendable?
            const char* szTemp = m_strString.c_str ();
            size_t sizeTemp = m_strString.length ();
            unsigned short usLength = static_cast < unsigned short > ( sizeTemp );
            if ( sizeTemp == usLength )
            {
                // This is a string argument
                type.data.ucType = LUA_TSTRING;
                bitStream.Write ( &type );

                // Write its length
                bitStream.WriteCompressed ( usLength );

                // Write the content too if it's not empty
                if ( usLength > 0 )
                {
                    bitStream.Write ( szTemp, usLength );
                }
            }
            else
            {
                // This is a long string argument
                type.data.ucType = LUA_TSTRING_LONG;
                bitStream.Write ( &type );

                // Write its length
                uint uiLength = sizeTemp;
                bitStream.WriteCompressed ( uiLength );

                // Write the content too if it's not empty
                if ( uiLength > 0 )
                {
                    bitStream.AlignWriteToByteBoundary ();
                    bitStream.Write ( szTemp, uiLength );
                }
            }
            break;
        }

        // Element packet
        case LUA_TLIGHTUSERDATA:
        case LUA_TUSERDATA:
        {
            // Got a valid element to send?
            CClientEntity* pElement = GetElement ();
            if ( pElement )
            {
                // Clientside element?
                if ( !pElement->IsLocalEntity () )
                {
                    type.data.ucType = LUA_TLIGHTUSERDATA;
                    bitStream.Write ( &type );
                    bitStream.Write ( pElement->GetID () );
                }
                else
                {
                    // Write a nil though so other side won't get out of sync
                    type.data.ucType = LUA_TNIL;
                    bitStream.Write ( &type );
                    return false;
                }
            }
            else
            {
                // Write a nil though so other side won't get out of sync
                type.data.ucType = LUA_TNIL;
                bitStream.Write ( &type );
                return false;
            }
            break;
        }

        // Unpacketizable type.
        default:
        {
            // Unpacketizable
            LogUnableToPacketize ( "Couldn't packetize argument list, unknown type specified." );

            // Write a nil though so other side won't get out of sync
            type.data.ucType = LUA_TNIL;
            bitStream.Write ( &type );
            return false;
        }
    }

    // Success
    return true;
}
예제 #7
0
json_object * CLuaArgument::WriteToJSONObject ( bool bSerialize, std::map < CLuaArguments*, unsigned long > * pKnownTables )
{
    switch ( GetType () )
    {
        case LUA_TNIL:
        {
            return json_object_new_int(0);
        }
        case LUA_TBOOLEAN:
        {
            return json_object_new_boolean(GetBoolean ());
        }
        case LUA_TTABLE:
        {
            if ( pKnownTables && pKnownTables->find ( m_pTableData ) != pKnownTables->end () )
            {
                char szTableID[10];
                snprintf ( szTableID, sizeof(szTableID), "^T^%lu", pKnownTables->find ( m_pTableData )->second );
                return json_object_new_string ( szTableID );
            }
            else
            {
                return m_pTableData->WriteTableToJSONObject ( bSerialize, pKnownTables );
            }
        }
        case LUA_TNUMBER:
        {
            float fNum = static_cast < float > ( GetNumber () );
            int iNum = static_cast < int > ( GetNumber () );
            if ( iNum == fNum )
            {
                return json_object_new_int(iNum);
            }
            else
            {
                return json_object_new_double(fNum);
            }
            break;
        }
        case LUA_TSTRING:
        {
            const char* szTemp = GetString ();
            unsigned short usLength = static_cast < unsigned short > ( strlen ( szTemp ) );
            if ( strlen ( szTemp ) == usLength )
            {
                return json_object_new_string_len ( (char *)szTemp, usLength );
            }
            else
            {
                g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON. Invalid string specified, limit is 65535 characters." );
            }
            break;
        }
        case LUA_TLIGHTUSERDATA:
        {
            CClientEntity* pElement = GetElement ();
            CResource* pResource = reinterpret_cast < CResource* > ( GetLightUserData() );
            
            // Elements are dynamic, so storing them is potentially unsafe
            if ( pElement && bSerialize )
            {
                char szElementID[10] = {0};
                snprintf ( szElementID, 9, "^E^%d", (int)pElement->GetID().Value() );
                return json_object_new_string ( szElementID );
            }
            else if ( VERIFY_RESOURCE(pResource) )
            {
                char szElementID[MAX_RESOURCE_NAME_LENGTH+4] = {0};
                snprintf ( szElementID, MAX_RESOURCE_NAME_LENGTH+3, "^R^%s", pResource->GetName()/*.c_str ()*/ );
                return json_object_new_string ( szElementID );
            }
            else
            {
                g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON, only valid elements can be sent." );
                return NULL;
            }
            break;
        }
        default:
        {
            g_pClientGame->GetScriptDebugging()->LogError ( NULL, "Couldn't convert argument list to JSON, unsupported data type. Use Table, Nil, String, Number, Boolean, Resource or Element." );
            return NULL;
        }
    }
    return NULL;
}