void rvInstance::PopulateFromMessage( const idBitMsg& msg ) { bool proto69 = ( gameLocal.GetCurrentDemoProtocol() == 69 ); if ( proto69 ) { numMapEntities = msg.ReadShort(); } initialSpawnCount = msg.ReadShort(); delete[] mapEntityNumbers; mapEntityNumbers = NULL; if ( proto69 ) { RV_PUSH_SYS_HEAP_ID(RV_HEAP_ID_LEVEL); mapEntityNumbers = new unsigned short[ numMapEntities ]; RV_POP_HEAP(); memset( mapEntityNumbers, -1, sizeof( unsigned short ) * numMapEntities ); for ( int i = 0; i < numMapEntities; i++ ) { mapEntityNumbers[ i ] = msg.ReadShort(); } Populate(); } else { int populateIndex = msg.ReadLong(); gameLocal.ClientSetStartingIndex( populateIndex ); //common->Printf( "pos: set firstFreeIndex to %d\n", populateIndex ); int checksum = msg.ReadLong(); Populate( checksum ); } }
/* ================ sdStatsTracker::OnServerStatsRequestMessage ================ */ void sdStatsTracker::OnServerStatsRequestMessage( const idBitMsg& msg ) { idStrPool* globalKeys; idStrPool* globalValues; idDict::GetGlobalPools( globalKeys, globalValues ); char buffer[ 2048 ]; sdNetStatKeyValList list; int numEntries = msg.ReadLong(); for ( int i = 0; i < numEntries; i++ ) { msg.ReadString( buffer, sizeof( buffer ) ); sdNetStatKeyValue kv; kv.type = ( sdNetStatKeyValue::statValueType )msg.ReadByte(); kv.key = globalKeys->AllocString( buffer ); switch ( kv.type ) { case sdNetStatKeyValue::SVT_FLOAT: case sdNetStatKeyValue::SVT_FLOAT_MAX: kv.val.f = msg.ReadFloat(); break; case sdNetStatKeyValue::SVT_INT: case sdNetStatKeyValue::SVT_INT_MAX: kv.val.i = msg.ReadLong(); break; } list.Append( kv ); } OnServerStatsRequestMessage( list ); sdReliableClientMessage response( GAME_RELIABLE_CMESSAGE_ACKNOWLEDGESTATS ); response.Send(); }
/* ============ sdGeneralMover::ClientReceiveEvent ============ */ bool sdGeneralMover::ClientReceiveEvent( int event, int time, const idBitMsg& msg ) { switch ( event ) { case EVENT_MOVE: { int startPos = msg.ReadLong(); int endPos = msg.ReadLong(); int moveTime = msg.ReadLong(); int startTime = msg.ReadLong(); StartTimedMove( startPos, endPos, moveTime, startTime ); return true; } } return sdScriptEntity::ClientReceiveEvent( event, time, msg ); }
/* ============ sdGUIDFile::ListBans ============ */ void sdGUIDFile::ListBans( const idBitMsg& msg ) { while ( msg.GetSize() != msg.GetReadCount() ) { int index = msg.ReadLong(); char buffer[ 128 ]; msg.ReadString( buffer, sizeof( buffer ) ); gameLocal.Printf( "%d: %s\n", index, buffer ); } }
/* ================ sdGameRulesCampaign::ReadCampaignInfo ================ */ void sdGameRulesCampaign::ReadCampaignInfo( const idBitMsg& msg ) { int campaignIndex = msg.ReadLong(); const sdDeclCampaign* newCampaign = NULL; if ( campaignIndex != -1 ) { newCampaign = gameLocal.declCampaignType[ campaignIndex ]; } SetCampaign( newCampaign ); }
/* ================ idExplodingBarrel::ClientReceiveEvent ================ */ bool idExplodingBarrel::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) { switch( event ) { case EVENT_EXPLODE: if ( gameLocal.realClientTime - msg.ReadLong() < spawnArgs.GetInt( "explode_lapse", "1000" ) ) { ExplodingEffects( ); } return true; default: break; } return idBarrel::ClientReceiveEvent( event, time, msg ); }
/* ================= idEntityFx::ReadFromSnapshot ================= */ void idEntityFx::ReadFromSnapshot( const idBitMsg &msg ) { int fx_index, start_time, max_lapse; GetPhysics()->ReadFromSnapshot( msg ); ReadBindFromSnapshot( msg ); fx_index = gameLocal.ClientRemapDecl( DECL_FX, msg.ReadLong() ); start_time = msg.ReadLong(); if ( fx_index != -1 && start_time > 0 && !fxEffect && started < 0 ) { spawnArgs.GetInt( "effect_lapse", "1000", max_lapse ); if ( gameLocal.time - start_time > max_lapse ) { // too late, skip the effect completely started = 0; return; } const idDeclFX *fx = static_cast<const idDeclFX *>( declManager->DeclByIndex( DECL_FX, fx_index ) ); if ( !fx ) { gameLocal.Error( "FX at index %d not found", fx_index ); } fxEffect = fx; Setup( fx->GetName() ); Start( start_time ); } }
/* ================ idPhysics_Monster::ReadFromSnapshot ================ */ void idPhysics_Monster::ReadFromSnapshot( const idBitMsg& msg ) { current.origin[0] = msg.ReadFloat(); current.origin[1] = msg.ReadFloat(); current.origin[2] = msg.ReadFloat(); current.velocity[0] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); current.velocity[1] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); current.velocity[2] = msg.ReadFloat( MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); current.localOrigin[0] = msg.ReadDeltaFloat( current.origin[0] ); current.localOrigin[1] = msg.ReadDeltaFloat( current.origin[1] ); current.localOrigin[2] = msg.ReadDeltaFloat( current.origin[2] ); current.pushVelocity[0] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); current.pushVelocity[1] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); current.pushVelocity[2] = msg.ReadDeltaFloat( 0.0f, MONSTER_VELOCITY_EXPONENT_BITS, MONSTER_VELOCITY_MANTISSA_BITS ); current.atRest = msg.ReadLong(); current.onGround = msg.ReadBits( 1 ) != 0; }
/* ================ sdProficiencyTable::ReadNetworkState ================ */ void sdProficiencyTable::ReadNetworkState( const sdNetworkData& baseData, sdNetworkData& newData, const idBitMsg& msg ) const { if ( msg.ReadBool() ) { for ( int i = 0; i < points.Num(); i++ ) { newData.points[ i ] = msg.ReadDeltaFloat( baseData.points[ i ] ); } } else { for ( int i = 0; i < points.Num(); i++ ) { newData.points[ i ] = baseData.points[ i ]; } } if ( msg.ReadBool() ) { for ( int i = 0; i < basePoints.Num(); i++ ) { newData.basePoints[ i ] = msg.ReadDeltaFloat( baseData.basePoints[ i ] ); } } else { for ( int i = 0; i < basePoints.Num(); i++ ) { newData.basePoints[ i ] = baseData.basePoints[ i ]; } } if ( msg.ReadBool() ) { for ( int i = 0; i < points.Num(); i++ ) { newData.spawnLevels[ i ] = msg.ReadDeltaLong( baseData.spawnLevels[ i ] ); } } else { for ( int i = 0; i < points.Num(); i++ ) { newData.spawnLevels[ i ] = baseData.spawnLevels[ i ]; } } if ( !baseData.fixedRank ) { newData.fixedRank = msg.ReadBool(); if ( newData.fixedRank ) { newData.fixedRankIndex = msg.ReadLong(); } else { newData.fixedRankIndex = -1; } } else { newData.fixedRank = true; newData.fixedRankIndex = baseData.fixedRankIndex; } }
/* ================ sdGameRulesCampaign::ReadMapStats ================ */ void sdGameRulesCampaign::ReadMapStats( const idBitMsg& msg ) { int index = msg.ReadLong(); if ( index >= campaignMapData.Num() ) { gameLocal.Warning( "sdGameRulesCampaign::ReadStats Out of Bounds Map Stats Received" ); return; } mapData_t& mapData = campaignMapData[ index ]; mapData.winner = sdTeamManager::GetInstance().ReadTeamFromStream( msg ); mapData.written = true; for ( int i = 0; i < mapData.teamData.Num(); i++ ) { teamMapData_t& teamData = mapData.teamData[ i ]; for ( int j = 0; j < teamData.xp.Num(); j++ ) { teamData.xp[ j ] = msg.ReadFloat(); } } OnMapStatsReceived( index ); }
/* ======================== idLobby::HandleHeadsetStateChange ======================== */ void idLobby::HandleHeadsetStateChange( int fromPeer, idBitMsg & msg ) { int userCount = msg.ReadLong(); for ( int i = 0; i < userCount; ++i ) { lobbyUserID_t lobbyUserID; lobbyUserID.ReadFromMsg( msg ); bool state = msg.ReadBool(); int talkerIndex = sessionCB->GetVoiceChat()->FindTalkerByUserId( lobbyUserID, lobbyType ); sessionCB->GetVoiceChat()->SetHeadsetState( talkerIndex, state ); idLib::Printf( "User %d headset status: %d\n", talkerIndex, state ); // If we are the host, let the other clients know about the headset state of this peer if ( IsHost() ) { // We should not be receiving a message with a user count > 1 if we are the host assert( userCount == 1 ); byte buffer[ idPacketProcessor::MAX_MSG_SIZE ]; idBitMsg outMsg( buffer, sizeof( buffer ) ); outMsg.WriteLong( 1 ); lobbyUserID.WriteToMsg( outMsg ); outMsg.WriteBool( state ); for ( int j = 0; j < peers.Num(); ++j ) { // Don't send this to the player that we just received the message from if ( !peers[ j ].IsConnected() || j == fromPeer ) { continue; } QueueReliableMessage( j, RELIABLE_HEADSET_STATE, outMsg.GetReadData(), outMsg.GetSize() ); } } } }
/* ================ idGameLocal::ServerProcessReliableMessage ================ */ void idGameLocal::ServerProcessReliableMessage( int clientNum, int type, const idBitMsg& msg ) { if( clientNum < 0 ) { return; } switch( type ) { case GAME_RELIABLE_MESSAGE_CHAT: case GAME_RELIABLE_MESSAGE_TCHAT: { char name[128]; char text[128]; msg.ReadString( name, sizeof( name ) ); msg.ReadString( text, sizeof( text ) ); mpGame.ProcessChatMessage( clientNum, type == GAME_RELIABLE_MESSAGE_TCHAT, name, text, NULL ); break; } case GAME_RELIABLE_MESSAGE_VCHAT: { int index = msg.ReadLong(); bool team = msg.ReadBits( 1 ) != 0; mpGame.ProcessVoiceChat( clientNum, team, index ); break; } case GAME_RELIABLE_MESSAGE_DROPWEAPON: { mpGame.DropWeapon( clientNum ); break; } case GAME_RELIABLE_MESSAGE_EVENT: { // allocate new event entityNetEvent_t* event = eventQueue.Alloc(); eventQueue.Enqueue( event, idEventQueue::OUTOFORDER_DROP ); event->spawnId = msg.ReadBits( 32 ); event->event = msg.ReadByte(); event->time = msg.ReadLong(); event->paramsSize = msg.ReadBits( idMath::BitsForInteger( MAX_EVENT_PARAM_SIZE ) ); if( event->paramsSize ) { if( event->paramsSize > MAX_EVENT_PARAM_SIZE ) { NetworkEventWarning( event, "invalid param size" ); return; } msg.ReadByteAlign(); msg.ReadData( event->paramsBuf, event->paramsSize ); } break; } case GAME_RELIABLE_MESSAGE_SPECTATE: { bool spec = msg.ReadBool(); idPlayer* player = GetClientByNum( clientNum ); if( serverInfo.GetBool( "si_spectators" ) ) { // never let spectators go back to game while sudden death is on if( mpGame.GetGameState() == idMultiplayerGame::SUDDENDEATH && !spec && player->wantSpectate ) { // Don't allow the change } else { if( player->wantSpectate && !spec ) { player->forceRespawn = true; } player->wantSpectate = spec; } } else { // If the server turned off si_spectators while a player is spectating, then any spectate message forces the player out of spectate mode if( player->wantSpectate ) { player->forceRespawn = true; } player->wantSpectate = false; } break; } case GAME_RELIABLE_MESSAGE_CLIENT_HITSCAN_HIT: { const int attackerNum = msg.ReadShort(); const int victimNum = msg.ReadShort(); idVec3 dir; msg.ReadVectorFloat( dir ); const int damageDefIndex = msg.ReadLong(); const float damageScale = msg.ReadFloat(); const int location = msg.ReadLong(); if( gameLocal.entities[victimNum] == NULL ) { break; } if( gameLocal.entities[attackerNum] == NULL ) { break; } idPlayer& victim = static_cast< idPlayer& >( *gameLocal.entities[victimNum] ); idPlayer& attacker = static_cast< idPlayer& >( *gameLocal.entities[attackerNum] ); if( victim.GetPhysics() == NULL ) { break; } if( attacker.weapon.GetEntity() == NULL ) { break; } if( location == INVALID_JOINT ) { break; } // Line of sight check. As a basic precaution against cheating, // the server performs a ray intersection from the client's position // to the joint he hit on the target. idVec3 muzzleOrigin; idMat3 muzzleAxis; attacker.weapon.GetEntity()->GetProjectileLaunchOriginAndAxis( muzzleOrigin, muzzleAxis ); idVec3 targetLocation = victim.GetRenderEntity()->origin + victim.GetRenderEntity()->joints[location].ToVec3() * victim.GetRenderEntity()->axis; trace_t tr; gameLocal.clip.Translation( tr, muzzleOrigin, targetLocation, NULL, mat3_identity, MASK_SHOT_RENDERMODEL, &attacker ); idEntity* hitEnt = gameLocal.entities[ tr.c.entityNum ]; if( hitEnt != &victim ) { break; } const idDeclEntityDef* damageDef = static_cast<const idDeclEntityDef*>( declManager->DeclByIndex( DECL_ENTITYDEF, damageDefIndex, false ) ); if( damageDef != NULL ) { victim.Damage( NULL, gameLocal.entities[attackerNum], dir, damageDef->GetName(), damageScale, location ); } break; } default: { Warning( "Unknown reliable message (%d) from client %d", type, clientNum ); break; } } }