void NetworkManagerServer::HandlePacketFromNewClient( InputMemoryBitStream& inInputStream, const SocketAddress& inFromAddress ) { //read the beginning- is it a hello? uint32_t packetType; inInputStream.Read( packetType ); if( packetType == kHelloCC ) { //read the name string name; inInputStream.Read( name ); ClientProxyPtr newClientProxy = std::make_shared< ClientProxy >( inFromAddress, name, mNewPlayerId++ ); mAddressToClientMap[ inFromAddress ] = newClientProxy; mPlayerIdToClientMap[ newClientProxy->GetPlayerId() ] = newClientProxy; //tell the server about this client, spawn a cat, etc... //if we had a generic message system, this would be a good use for it... //instead we'll just tell the server directly static_cast< Server* > ( Engine::sInstance.get() )->HandleNewClient( newClientProxy ); //and welcome the client... SendWelcomePacket( newClientProxy ); //and now init the replication manager with everything we know about! for( const auto& pair: mNetworkIdToGameObjectMap ) { newClientProxy->GetReplicationManagerServer().ReplicateCreate( pair.first, pair.second->GetAllStateMask() ); } } else { //bad incoming packet from unknown client- we're under attack!! LOG( "Bad incoming packet from unknown client at socket %s", inFromAddress.ToString().c_str() ); } }
void TurnData::Read( InputMemoryBitStream& inInputStream ) { inInputStream.Read( mPlayerId ); inInputStream.Read( mRandomValue ); inInputStream.Read( mCRC ); mCommandList.Read( inInputStream ); }
void ReplicationManagerClient::Read( InputMemoryBitStream& inInputStream ) { while ( inInputStream.GetRemainingBitCount() >= 32 ) { int networkId; inInputStream.Read( networkId ); // 2 bits for action uint8_t action; inInputStream.Read( action, 2 ); switch ( action ) { case RA_CREATE: ReadAndDoCreateAction( inInputStream, networkId ); break; case RA_UPDATE: ReadAndDoUpdateAction( inInputStream, networkId ); break; case RA_DESTROY: ReadAndDoDestroyAction( inInputStream, networkId ); break; default: LOG( "No Action found for %d", action ); } } }
void NetworkManagerClient::ReadLastMoveProcessedOnServerTimestamp( InputMemoryBitStream& inInputStream ) { bool isTimestampDirty; inInputStream.Read( isTimestampDirty ); if( isTimestampDirty ) { inInputStream.Read( mLastMoveProcessedByServerTimestamp ); float rtt = Timing::sInstance.GetFrameStartTime() - mLastMoveProcessedByServerTimestamp; mLastRoundTripTime = rtt; mAvgRoundTripTime.Update( rtt ); InputManager::sInstance->GetMoveList().RemovedProcessedMoves( mLastMoveProcessedByServerTimestamp ); } }
void AckRange::Read( InputMemoryBitStream& inInputStream ) { inInputStream.Read( mStart ); bool hasCount; inInputStream.Read( hasCount ); if( hasCount ) { uint8_t countMinusOne; inInputStream.Read( countMinusOne ); mCount = countMinusOne + 1; } else { //default! mCount = 1; } }
void ChickenClassComponent::readNetAbility(InputMemoryBitStream& aPacket) { PowerShieldObjectFactory sFactory; uint64_t ID; float posX, posY; bool direction; int team; aPacket.Read(ID); aPacket.Read(posX); aPacket.Read(posY); aPacket.Read(direction); aPacket.Read(team); timer = new Invoke(shieldLength); invokeHelper = true; activeShields++; shieldIDs.push_back(ID); GameObjects.AddObject(sFactory.Spawn(ID, posX, posY, direction, team)); }
void CommandList::Read(InputMemoryBitStream& inInputStream) { int count; inInputStream.Read(count); for (int i = 0; i < count; ++i) { mCommands.push_back(Command::StaticReadAndCreate(inInputStream)); } }
bool InputState::Read( InputMemoryBitStream& inInputStream ) { ReadSignedBinaryValue( inInputStream, mDesiredRightAmount ); ReadSignedBinaryValue( inInputStream, mDesiredForwardAmount ); inInputStream.Read( mIsShooting ); return true; }
void NetworkManager::HandleTurnPacket( InputMemoryBitStream& inInputStream, uint64_t inFromPlayer ) { int turnNum; uint64_t playerId; inInputStream.Read( turnNum ); inInputStream.Read( playerId ); if ( playerId != inFromPlayer ) { LOG( "We received turn data for a different player Id...stop trying to cheat!" ); return; } TurnData data; data.Read( inInputStream ); mTurnData[ turnNum ].emplace( playerId, data ); }
bool ScoreBoardManager::Entry::Read( InputMemoryBitStream& inInputStream ) { bool didSucceed = true; inInputStream.Read( mColor ); inInputStream.Read( mPlayerId ); inInputStream.Read( mPlayerName ); int score; inInputStream.Read( score ); if( didSucceed ) { SetScore( score ); } return didSucceed; }
void NetworkManagerClient::HandleWelcomePacket( InputMemoryBitStream& inInputStream ) { if( mState == NCS_SayingHello ) { //if we got a player id, we've been welcomed! int playerId; inInputStream.Read( playerId ); mPlayerId = playerId; mState = NCS_Welcomed; LOG( "'%s' was welcomed on client as player %d", mName.c_str(), mPlayerId ); } }
void NetworkManagerClient::HandleGameObjectState( InputMemoryBitStream& inInputStream ) { //copy the mNetworkIdToGameObjectMap so that anything that doesn't get an updated can be destroyed... IntToGameObjectMap objectsToDestroy = mNetworkIdToGameObjectMap; int stateCount; inInputStream.Read( stateCount ); if( stateCount > 0 ) { for( int stateIndex = 0; stateIndex < stateCount; ++stateIndex ) { int networkId; uint32_t fourCC; inInputStream.Read( networkId ); inInputStream.Read( fourCC ); GameObjectPtr go; auto itGO = mNetworkIdToGameObjectMap.find( networkId ); //didn't find it, better create it! if( itGO == mNetworkIdToGameObjectMap.end() ) { go = GameObjectRegistry::sInstance->CreateGameObject( fourCC ); go->SetNetworkId( networkId ); AddToNetworkIdToGameObjectMap( go ); } else { //found it go = itGO->second; } //now we can update into it go->Read( inInputStream ); objectsToDestroy.erase( networkId ); } } //anything left gets the axe DestroyGameObjectsInMap( objectsToDestroy ); }
bool ScoreBoardManager::Read( InputMemoryBitStream& inInputStream ) { int entryCount; inInputStream.Read( entryCount ); //just replace everything that's here, it don't matter... mEntries.resize( entryCount ); for( Entry& entry: mEntries ) { entry.Read( inInputStream ); } return true; }
void NetworkManager::ProcessPacketsDelay( InputMemoryBitStream& inInputStream, uint64_t inFromPlayer ) { //the only packet we can even consider here is an input one, since we //only can only enter delay after we've been playing uint32_t packetType; inInputStream.Read( packetType ); if ( packetType == kTurnCC ) { HandleTurnPacket( inInputStream, inFromPlayer ); //if we're lucky, maybe this was the packet we were waiting on? TryAdvanceTurn(); } }
void NetworkManagerClient::ProcessPacket( InputMemoryBitStream& inInputStream, const SocketAddress& inFromAddress ) { uint32_t packetType; inInputStream.Read( packetType ); switch( packetType ) { case kWelcomeCC: HandleWelcomePacket( inInputStream ); break; case kStateCC: HandleStatePacket( inInputStream ); break; } }
void NetworkManager::ProcessPacketsPlaying( InputMemoryBitStream& inInputStream, uint64_t inFromPlayer ) { uint32_t packetType; inInputStream.Read( packetType ); switch ( packetType ) { case kTurnCC: HandleTurnPacket( inInputStream, inFromPlayer ); break; default: //ignore anything else break; } }
void NetworkManager::HandleStartPacket( InputMemoryBitStream& inInputStream, uint64_t inFromPlayer ) { //make sure this is the master peer, cause we don't want any funny business if ( inFromPlayer == mMasterPeerId ) { LOG( "Got the orders to go!" ); //get the rng seed uint32_t seed; inInputStream.Read( seed ); RandGen::sInstance->Seed( seed ); //for now, assume that we're one frame off, but ideally we would RTT to adjust //the time to start, based on latency/jitter mState = NMS_Starting; mTimeToStart = kStartDelay - Timing::sInstance.GetDeltaTime(); } }
void NetworkManager::ProcessPacketsLobby( InputMemoryBitStream& inInputStream, uint64_t inFromPlayer ) { //should only be a ready packet uint32_t packetType; inInputStream.Read( packetType ); switch ( packetType ) { case kReadyCC: HandleReadyPacket( inInputStream, inFromPlayer ); break; default: //ignore anything else break; } }
// Tell inflight packets if they have been dropped or delivered void DeliveryNotificationManager::ProcessAcks( InputMemoryBitStream& inInputStream ) { bool hasAcks; inInputStream.Read( hasAcks ); if ( !hasAcks ) // nothing to ack { return; } AckRange ackRange; ackRange.Read( inInputStream ); PacketSequenceNumber nextAckdSequenceNumber = ackRange.GetStart(); uint32_t maxAckdSequenceNumber = nextAckdSequenceNumber + ackRange.GetCount(); while ( nextAckdSequenceNumber < maxAckdSequenceNumber && !mInFlightPackets.empty() ) { const auto& nextInflightPacket = mInFlightPackets.front(); PacketSequenceNumber nextSequenceNumber = nextInflightPacket.GetSequenceNumber(); if ( nextSequenceNumber < nextAckdSequenceNumber ) { // Copy Droped packet, didn't get an ack for it. Note, don't // increment ack number, we need to find the packet for it! auto inFlightPacket = nextInflightPacket; mInFlightPackets.pop_front(); HandlePacketDeliveryFailure( inFlightPacket ); } else if ( nextSequenceNumber == nextAckdSequenceNumber ) { HandlePacketDeliverySuccess( nextInflightPacket ); mInFlightPackets.pop_front(); ++nextAckdSequenceNumber; } else if ( nextSequenceNumber > nextAckdSequenceNumber ) { // Well this is embarassing, we already dropped that one... nextAckdSequenceNumber++; } } }
void NetworkManagerClient::ProcessPacket( InputMemoryBitStream& inInputStream, const SocketAddress& inFromAddress ) { uint32_t packetType; inInputStream.Read( packetType ); switch( packetType ) { case kWelcomeCC: HandleWelcomePacket( inInputStream ); break; case kStateCC: if( mDeliveryNotificationManager.ReadAndProcessState( inInputStream ) ) { HandleStatePacket( inInputStream ); } break; } }
void NetworkManagerServer::HandleInputPacket( ClientProxyPtr inClientProxy, InputMemoryBitStream& inInputStream ) { uint32_t moveCount = 0; Move move; inInputStream.Read( moveCount, 2 ); for( ; moveCount > 0; --moveCount ) { if( move.Read( inInputStream ) ) { if( inClientProxy->GetUnprocessedMoveList().AddMove( move ) ) { inClientProxy->SetIsLastMoveTimestampDirty( true ); } } } }
void NetworkManager::ProcessPacketsReady( InputMemoryBitStream& inInputStream, uint64_t inFromPlayer ) { //could be another ready packet or a start packet uint32_t packetType; inInputStream.Read( packetType ); switch( packetType ) { case kReadyCC: HandleReadyPacket( inInputStream, inFromPlayer ); break; case kStartCC: HandleStartPacket( inInputStream, inFromPlayer ); break; default: //ignore anything else break; } }
// The first field in a packet. Process the sequence number if it's one we care // about bool DeliveryNotificationManager::ProcessSequenceNumber( InputMemoryBitStream& inInputStream ) { PacketSequenceNumber sequenceNumber; inInputStream.Read( sequenceNumber ); // Uh...old packet, we have moved on to greater things if ( sequenceNumber < mNextExpectedSequenceNumber ) { return false; } // The packet is either matching our sequence number or greater than it, // either way we move on, we only go forward mNextExpectedSequenceNumber = sequenceNumber + 1; if ( mShouldSendAcks ) { AddPendingAck( sequenceNumber ); } return true; }
// TODO: This should be managed by some sort of packet class void ReplicationManagerClient::ReadAndDoCreateAction( InputMemoryBitStream& inInputStream, int inNetworkId ) { uint32_t fourCCName; inInputStream.Read( fourCCName ); GameObjectPtr gameObject = NetworkManagerClient::sInstance->GetGameObject( inNetworkId ); if ( !gameObject ) { gameObject = GameObjectRegistry::sInstance->CreateGameObject( fourCCName ); gameObject->SetNetworkId( inNetworkId ); NetworkManagerClient::sInstance->AddToNetworkIdToGameObjectMap( gameObject ); } gameObject->Read( inInputStream ); // Read state }
void NetworkManagerServer::ProcessPacket( ClientProxyPtr inClientProxy, InputMemoryBitStream& inInputStream ) { //remember we got a packet so we know not to disconnect for a bit inClientProxy->UpdateLastPacketTime(); uint32_t packetType; inInputStream.Read( packetType ); switch( packetType ) { case kHelloCC: //need to resend welcome. to be extra safe we should check the name is the one we expect from this address, //otherwise something weird is going on... SendWelcomePacket( inClientProxy ); break; case kInputCC: HandleInputPacket( inClientProxy, inInputStream ); break; default: LOG( "Unknown packet type received from %s", inClientProxy->GetSocketAddress().ToString().c_str() ); break; } }