void CClientWebBrowser::Events_OnNavigate ( const SString& strURL, bool bIsBlocked, bool bIsMainFrame ) { CLuaArguments Arguments; Arguments.PushString ( strURL ); Arguments.PushBoolean ( bIsBlocked ); Arguments.PushBoolean ( bIsMainFrame ); CallEvent ( "onClientBrowserNavigate", Arguments, false ); }
void CRegisteredCommands::CallCommandHandler(CLuaMain* pLuaMain, const CLuaFunctionRef& iLuaFunction, const char* szKey, const char* szArguments, CClient* pClient) { assert(pLuaMain); assert(szKey); CLuaArguments Arguments; // First, try to call a handler with the same number of arguments if (pClient) { switch (pClient->GetClientType()) { case CClient::CLIENT_PLAYER: { Arguments.PushElement(static_cast<CPlayer*>(pClient)); break; } case CClient::CLIENT_CONSOLE: { Arguments.PushElement(static_cast<CConsoleClient*>(pClient)); break; } default: { Arguments.PushBoolean(false); break; } } } else Arguments.PushBoolean(false); Arguments.PushString(szKey); if (szArguments) { // Create a copy and strtok modifies the string char* szTempArguments = new char[strlen(szArguments) + 1]; strcpy(szTempArguments, szArguments); char* arg; arg = strtok(szTempArguments, " "); while (arg) { Arguments.PushString(arg); arg = strtok(NULL, " "); } delete[] szTempArguments; } // Call the handler with the arguments we pushed Arguments.Call(pLuaMain, iLuaFunction); }
// // 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 CClientWebBrowser::Events_OnLoadingStart ( const SString& strURL, bool bMainFrame ) { CLuaArguments Arguments; Arguments.PushString ( strURL ); Arguments.PushBoolean ( bMainFrame ); CallEvent ( "onClientBrowserLoadingStart", Arguments, false ); }
void CClientSound::ThreadCallback ( HSTREAM pSound ) { if ( pSound ) { m_pSound = pSound; if ( m_b3D ) { BASS_3DVECTOR pos ( m_vecPosition.fX, m_vecPosition.fY, m_vecPosition.fZ ); BASS_ChannelSet3DPosition ( pSound, &pos, NULL, NULL ); BASS_ChannelSet3DAttributes ( pSound, BASS_3DMODE_NORMAL, 1.0f, 0.5f, 360, 360, 1.0f ); } // Set a Callback function for download finished BASS_ChannelSetSync ( pSound, BASS_SYNC_DOWNLOAD, 0, &DownloadSync, this ); BASS_ChannelGetAttribute ( pSound, BASS_ATTRIB_FREQ, &m_fDefaultFrequency ); BASS_ChannelPlay ( pSound, false ); } else g_pCore->GetConsole()->Printf ( "BASS ERROR %d in PlayStream b3D = %s path = %s", BASS_ErrorGetCode(), m_b3D ? "true" : "false", m_strPath.c_str() ); // Call onClientSoundStream LUA event CLuaArguments Arguments; Arguments.PushBoolean ( pSound ? true : false ); Arguments.PushNumber ( GetLength () ); this->CallEvent ( "onClientSoundStream", Arguments, true ); }
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); }
int CLuaFunctionDefs::RequestBrowserDomains ( lua_State* luaVM ) { // bool requestBrowserDomains ( table domains, bool isURL [, function callback ] ) std::vector<SString> pages; bool bIsURL; CLuaFunctionRef callbackFunction; CScriptArgReader argStream ( luaVM ); argStream.ReadStringTable ( pages ); argStream.ReadBool ( bIsURL, false ); argStream.ReadFunction ( callbackFunction, LUA_REFNIL ); argStream.ReadFunctionComplete (); if ( !argStream.HasErrors () ) { // Convert to domains if we got a list of URLs if ( bIsURL ) { for ( auto& strURL : pages ) { strURL = g_pCore->GetWebCore ()->GetDomainFromURL ( strURL ); } } WebRequestCallback callback = [=]( bool bAllow, const std::vector<SString>& domains ) { // Test if luaVM is still available if ( m_pLuaManager->IsLuaVMValid ( luaVM ) && VERIFY_FUNCTION ( callbackFunction ) ) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( !pLuaMain ) return; CLuaArguments arguments; arguments.PushBoolean ( bAllow ); CLuaArguments LuaTable; int i = 0; for ( const auto& domain : domains ) { LuaTable.PushNumber ( ++i ); LuaTable.PushString ( domain ); } arguments.PushTable ( &LuaTable ); arguments.Call ( pLuaMain, callbackFunction ); } }; g_pCore->GetWebCore ()->RequestPages ( pages, VERIFY_FUNCTION ( callbackFunction ) ? &callback : nullptr ); lua_pushboolean ( luaVM, true ); return 1; } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage () ); lua_pushboolean ( luaVM, false ); return 1; }
void CClientMarker::Callback_OnLeave ( CClientColShape& Shape, CClientEntity& Entity ) { if ( IS_PLAYER ( &Entity ) ) { // Call the marker hit event CLuaArguments Arguments; Arguments.PushElement ( &Entity ); // player that hit it Arguments.PushBoolean ( ( Shape.GetDimension () == Entity.GetDimension () ) ); // matching dimension? CallEvent ( "onClientMarkerLeave", Arguments, true ); } }
int CFunctions::base64_encode( lua_State* luaVM ) { if( luaVM ) { CLuaArguments args; if( lua_type( luaVM, 1 ) == LUA_TSTRING || lua_type( luaVM, 1 ) == LUA_TNUMBER ) { args.PushString( base64::encode( lua_tostring( luaVM, 1 ) ).c_str( ) ); } else { luaL_error( luaVM, "Bad argument @ 'base64_encode'" ); args.PushBoolean( false ); } args.PushArguments( luaVM ); return 1; } return 0; }
void CRPCFunctions::PlayerTarget ( NetBitStreamInterface & bitStream ) { if ( m_pSourcePlayer->IsJoined () ) { ElementID TargetID; bitStream.ReadCompressed ( TargetID ); CElement* pTarget = NULL; if ( TargetID != INVALID_ELEMENT_ID ) pTarget = CElementIDs::GetElement ( TargetID ); m_pSourcePlayer->SetTargetedElement ( pTarget ); // Call our script event CLuaArguments Arguments; if ( pTarget ) Arguments.PushElement ( pTarget ); else Arguments.PushBoolean ( false ); m_pSourcePlayer->CallEvent ( "onPlayerTarget", Arguments ); } }
void CClientPickup::Callback_OnLeave ( CClientColShape& Shape, CClientEntity& Entity ) { if ( IS_PLAYER ( &Entity ) ) { bool bMatchingDimensions = (GetDimension () == Entity.GetDimension ()); // Matching dimensions? // Call the pickup leave event (source = the pickup that was left) CLuaArguments Arguments; Arguments.PushElement ( &Entity ); // The element that left the pickup Arguments.PushBoolean ( bMatchingDimensions ); CallEvent ( "onClientPickupLeave", Arguments, true); // Call the player pickup leave event (source = the player that left the pickup) CLuaArguments Arguments2; Arguments2.PushElement ( this ); // The pickup that was left (this) Arguments2.PushBoolean ( bMatchingDimensions ); Entity.CallEvent ( "onClientPlayerPickupLeave", Arguments2, true ); } }
void CMarker::Callback_OnLeave ( CColShape& Shape, CElement& Element ) { // Matching interior? if ( GetInterior () == Element.GetInterior () ) { // Call the marker hit event CLuaArguments Arguments; Arguments.PushElement ( &Element ); // Hit element Arguments.PushBoolean ( GetDimension () == Element.GetDimension () ); // Matching dimension? CallEvent ( "onMarkerLeave", Arguments ); if ( IS_PLAYER ( &Element ) ) { CLuaArguments Arguments2; Arguments2.PushElement ( this ); // marker Arguments2.PushBoolean ( GetDimension () == Element.GetDimension () ); // Matching dimension? Element.CallEvent ( "onPlayerMarkerLeave", Arguments2 ); } } }
void CMapManager::DoVehicleRespawning ( void ) { // TODO: needs speeding up (no good looping through thousands of vehicles each frame) CVehicleSpawnPacket VehicleSpawnPacket; CVehicle* pVehicle = NULL; // Grab the current time unsigned long ulTime = GetTime (); bool bRespawn, bExploded; unsigned long ulBlowTime, ulIdleTime; // Loop through all the vehicles list < CVehicle* > ::const_iterator iter = m_pVehicleManager->IterBegin (); for ( ; iter != m_pVehicleManager->IterEnd (); iter++ ) { pVehicle = *iter; bRespawn = false, bExploded = false; // It's been set to respawn if ( pVehicle->GetRespawnEnabled () ) { // Did we get deserted? bool bDeserted = ( !pVehicle->GetFirstOccupant () ); // Grab when it blew and when it was last not touched ulBlowTime = pVehicle->GetBlowTime (); ulIdleTime = pVehicle->GetIdleTime (); // Been blown long enough? if ( ulBlowTime != 0 && ulTime >= ( ulBlowTime + pVehicle->GetRespawnTime () ) ) { bRespawn = true; bExploded = true; } // Been deserted long enough? else if ( bDeserted && ulIdleTime != 0 && ulTime >= ( ulIdleTime + pVehicle->GetIdleRespawnTime () ) ) { bRespawn = true; } } // Need to respawn? if ( bRespawn ) { // Respawn it and add it to the packet pVehicle->Respawn (); VehicleSpawnPacket.Add ( pVehicle ); // Call the respawn event CLuaArguments Arguments; Arguments.PushBoolean ( bExploded ); pVehicle->CallEvent ( "onVehicleRespawn", Arguments ); } } // Send it m_pPlayerManager->BroadcastOnlyJoined ( VehicleSpawnPacket ); }
void CMapManager::DoVehicleRespawning ( void ) { CVehicleSpawnPacket VehicleSpawnPacket; // Loop through all vehicles with respawn enabled list < CVehicle* >& respawnEnabledList = m_pVehicleManager->GetRespawnEnabledVehicles ( ); list < CVehicle* > ::const_iterator iter = respawnEnabledList.begin ( ); for ( ; iter != respawnEnabledList.end ( ); ++iter ) { CVehicle* pVehicle = *iter; // No need to respawn vehicles if they're being deleted anyway if ( pVehicle->IsBeingDeleted ( ) ) continue; // Did we get deserted? bool bDeserted = ( !pVehicle->GetFirstOccupant ( ) ); bool bRespawn = false; bool bExploded = false; if ( bDeserted ) { // If moved, or idle timer not running, restart idle timer if ( !pVehicle->IsStationary ( ) || !pVehicle->IsIdleTimerRunning ( ) ) pVehicle->RestartIdleTimer ( ); } else { // Stop idle timer if car is occupied pVehicle->StopIdleTimer ( ); } // Been blown long enough? if ( pVehicle->IsBlowTimerFinished ( ) ) { bRespawn = true; bExploded = true; } // Been deserted long enough? else if ( bDeserted && pVehicle->IsIdleTimerFinished ( ) ) { // Check is far enough away from respawn point (Ignore first 20 units on z) CVector vecDif = pVehicle->GetRespawnPosition ( ) - pVehicle->GetPosition ( ); vecDif.fZ = Max ( 0.f, fabsf ( vecDif.fZ ) - 20.f ); if ( vecDif.LengthSquared ( ) > 2 * 2 ) bRespawn = true; pVehicle->StopIdleTimer ( ); } // Need to respawn? if ( bRespawn ) { // Respawn it and add it to the packet pVehicle->Respawn ( ); VehicleSpawnPacket.Add ( pVehicle ); // Call the respawn event CLuaArguments Arguments; Arguments.PushBoolean ( bExploded ); pVehicle->CallEvent ( "onVehicleRespawn", Arguments ); } } // Send it m_pPlayerManager->BroadcastOnlyJoined ( VehicleSpawnPacket ); }
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; }
bool CAccountManager::LogIn ( CClient* pClient, CClient* pEchoClient, CAccount* pAccount, bool bAutoLogin ) { // Log him in CAccount* pCurrentAccount = pClient->GetAccount (); pClient->SetAccount ( pAccount ); pAccount->SetClient ( pClient ); string strPlayerIP, strPlayerSerial; if ( pClient->GetClientType () == CClient::CLIENT_PLAYER ) { CPlayer* pPlayer = static_cast < CPlayer* > ( pClient ); // Get the players details strPlayerIP = pPlayer->GetSourceIP () ; strPlayerSerial = pPlayer->GetSerial (); // Set in account pAccount->SetIP ( strPlayerIP ); pAccount->SetSerial ( strPlayerSerial ); } // Call the onClientLogin script event CElement* pClientElement = NULL; switch ( pClient->GetClientType () ) { case CClient::CLIENT_PLAYER: { CPlayer* pPlayer = static_cast < CPlayer* > ( pClient ); pClientElement = static_cast < CElement* > ( pPlayer ); break; } case CClient::CLIENT_CONSOLE: { CConsoleClient* pConsoleClient = static_cast < CConsoleClient* > ( pClient ); pClientElement = static_cast < CElement* > ( pConsoleClient ); break; } } if ( pClientElement ) { CLuaArguments Arguments; Arguments.PushAccount ( pCurrentAccount ); Arguments.PushAccount ( pAccount ); Arguments.PushBoolean ( bAutoLogin ); if ( !pClientElement->CallEvent ( "onPlayerLogin", Arguments ) ) { // DENIED! pClient->SetAccount ( pCurrentAccount ); pAccount->SetClient ( NULL ); return false; } } // Get the names of the groups the client belongs to - I did it like this for a larf string strGroupList; for ( list <CAccessControlListGroup* > ::const_iterator iterg = g_pGame->GetACLManager ()->Groups_Begin () ; iterg != g_pGame->GetACLManager ()->Groups_End (); iterg++ ) for ( list <CAccessControlListGroupObject* > ::iterator itero = (*iterg)->IterBeginObjects () ; itero != (*iterg)->IterEndObjects (); itero++ ) if ( (*itero)->GetObjectType () == CAccessControlListGroupObject::OBJECT_TYPE_USER ) if ( (*itero)->GetObjectName () == pAccount->GetName () || strcmp ( (*itero)->GetObjectName (), "*" ) == 0 ) strGroupList = string( (*iterg)->GetGroupName () ) + ( strGroupList.length() ? ", " : "" ) + strGroupList; 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 ) { if ( bAutoLogin ) pEchoClient->SendEcho ( "auto-login: You successfully logged in" ); else 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; }
void CClientWebBrowser::Events_OnInputFocusChanged ( bool bGainedFocus ) { CLuaArguments Arguments; Arguments.PushBoolean ( bGainedFocus ); CallEvent ( "onClientBrowserInputFocusChanged", Arguments, false ); }
//////////////////////////////////////////////////////////// // // 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 ); } } }
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 ) { // 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 bool bDamageInfo = BitStream.ReadBit (); if ( bDamageInfo ) { 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 ); bDamageInfo = true; } // 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 > FLOAT_EPSILON || fArmorLoss > FLOAT_EPSILON ) { float fDamage = 0.0f; if ( fHealthLoss > 0 ) fDamage += fHealthLoss; if ( fArmorLoss > 0 ) fDamage += fArmorLoss; CElement * pKillerElement = NULL; unsigned char ucWeapon = 0xFF; unsigned char ucBodyPart = 0xFF; if ( bDamageInfo ) { pKillerElement = CElementIDs::GetElement ( pSourcePlayer->GetPlayerAttacker () ); ucWeapon = pSourcePlayer->GetAttackWeapon (); ucBodyPart = pSourcePlayer->GetAttackBodyPart (); } // Call the onPlayerDamage event CLuaArguments Arguments; if ( pKillerElement ) Arguments.PushElement ( pKillerElement ); else Arguments.PushNil (); if ( ucWeapon != 0xFF ) Arguments.PushNumber ( ucWeapon ); else Arguments.PushBoolean ( false ); if ( ucBodyPart != 0xFF ) Arguments.PushNumber ( ucBodyPart ); else Arguments.PushBoolean ( false ); Arguments.PushNumber ( fDamage ); pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments ); } // Success return true; } return false; }