void UDemoNetDriver::FinishDestroy() { if ( !HasAnyFlags( RF_ClassDefaultObject ) ) { // Make sure we stop any recording that might be going on if ( ClientConnections.Num() > 0 ) { StopDemo(); } } Super::FinishDestroy(); }
void UDemoNetDriver::TickDemoPlayback( float DeltaSeconds ) { if ( ServerConnection == NULL || ServerConnection->State == USOCK_Closed ) { StopDemo(); return; } DemoDeltaTime += DeltaSeconds; while ( true ) { // Read demo frames until we are caught up if ( !ReadDemoFrame() ) { break; } DemoFrameNum++; } }
bool UDemoNetDriver::ReadDemoFrame() { if ( FileAr->IsError() ) { StopDemo(); return false; } if ( FileAr->AtEnd() || FileAr->Tell() >= EndOfStreamOffset ) { bDemoPlaybackDone = true; // Pause all non player controller actors for ( int32 i = ServerConnection->OpenChannels.Num() - 1; i >= 0; i-- ) { UChannel* OpenChannel = ServerConnection->OpenChannels[i]; if ( OpenChannel != NULL ) { UActorChannel* ActorChannel = Cast< UActorChannel >( OpenChannel ); if ( ActorChannel != NULL && ActorChannel->GetActor() != NULL ) { if ( Cast< APlayerController >( ActorChannel->GetActor() ) == NULL ) { // Better way to pause each actor? ActorChannel->GetActor()->CustomTimeDilation = 0.0f; } } } } return false; } const int32 OldFilePos = FileAr->Tell(); float ServerDeltaTime; // Peek at the next demo delta time, and see if we should process this frame *FileAr << ServerDeltaTime; #if DEMO_CHECKSUMS == 1 { uint32 ServerDeltaTimeCheksum = 0; *FileAr << ServerDeltaTimeCheksum; const uint32 DeltaTimeChecksum = FCrc::MemCrc32( &ServerDeltaTime, sizeof( ServerDeltaTime ), 0 ); if ( DeltaTimeChecksum != ServerDeltaTimeCheksum ) { UE_LOG( LogDemo, Error, TEXT( "UDemoNetDriver::ReadDemoFrame: DeltaTimeChecksum != ServerDeltaTimeCheksum" ) ); StopDemo(); return false; } } #endif if ( FileAr->IsError() ) { UE_LOG( LogDemo, Error, TEXT( "UDemoNetDriver::ReadDemoFrame: Failed to read demo ServerDeltaTime" ) ); StopDemo(); return false; } if ( DemoDeltaTime < ServerDeltaTime )//&& ServerConnection->State != USOCK_Pending ) { // Not enough time has passed to read another frame FileAr->Seek( OldFilePos ); return false; } DemoDeltaTime -= ServerDeltaTime; while ( true ) { uint8 ReadBuffer[ MAX_DEMO_READ_WRITE_BUFFER ]; int32 PacketBytes; *FileAr << PacketBytes; if ( FileAr->IsError() ) { UE_LOG( LogDemo, Error, TEXT( "UDemoNetDriver::ReadDemoFrame: Failed to read demo PacketBytes" ) ); StopDemo(); return false; } if ( PacketBytes == 0 ) { break; } if ( PacketBytes > sizeof( ReadBuffer ) ) { UE_LOG( LogDemo, Error, TEXT( "UDemoNetDriver::ReadDemoFrame: PacketBytes > sizeof( ReadBuffer )" ) ); StopDemo(); if ( World != NULL && World->GetGameInstance() != NULL ) { World->GetGameInstance()->HandleDemoPlaybackFailure( EDemoPlayFailure::Generic, FString( TEXT( "UDemoNetDriver::ReadDemoFrame: PacketBytes > sizeof( ReadBuffer )" ) ) ); } return false; } // Read data from file. FileAr->Serialize( ReadBuffer, PacketBytes ); if ( FileAr->IsError() ) { UE_LOG( LogDemo, Error, TEXT( "UDemoNetDriver::ReadDemoFrame: Failed to read demo file packet" ) ); StopDemo(); return false; } #if DEMO_CHECKSUMS == 1 { uint32 ServerChecksum = 0; *FileAr << ServerChecksum; const uint32 Checksum = FCrc::MemCrc32( ReadBuffer, PacketBytes, 0 ); if ( Checksum != ServerChecksum ) { UE_LOG( LogDemo, Error, TEXT( "UDemoNetDriver::ReadDemoFrame: Checksum != ServerChecksum" ) ); StopDemo(); return false; } } #endif // Process incoming packet. ServerConnection->ReceivedRawPacket( ReadBuffer, PacketBytes ); if ( ServerConnection == NULL || ServerConnection->State == USOCK_Closed ) { // Something we received resulted in the demo being stopped UE_LOG( LogDemo, Error, TEXT( "UDemoNetDriver::ReadDemoFrame: ReceivedRawPacket closed connection" ) ); StopDemo(); return false; } } return true; }