Пример #1
0
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();
}
Пример #2
0
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++;
	}
}
Пример #3
0
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;
}