2022-05-24 02:50:39 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "CookOnTheFlyNetServerBase.h"
# include "Serialization/BufferArchive.h"
# include "Interfaces/ITargetPlatform.h"
# include "Serialization/ArrayReader.h"
# include "HAL/RunnableThread.h"
2023-06-20 10:53:32 -04:00
# include "SocketSubsystem.h"
# include "IPAddress.h"
2022-05-24 02:50:39 -04:00
FCookOnTheFlyClientConnectionBase : : FCookOnTheFlyClientConnectionBase ( FCookOnTheFlyNetworkServerBase & InOwner )
: Owner ( InOwner )
{
}
FCookOnTheFlyClientConnectionBase : : ~ FCookOnTheFlyClientConnectionBase ( )
{
if ( WorkerThread )
{
delete WorkerThread ;
}
if ( bClientConnectedBroadcasted & & Owner . ClientDisconnectedEvent . IsBound ( ) )
{
Owner . ClientDisconnectedEvent . Broadcast ( * this ) ;
}
}
bool FCookOnTheFlyClientConnectionBase : : Initialize ( )
{
FArrayReader HandshakeRequestPayload ;
if ( ! ReceivePayload ( HandshakeRequestPayload ) )
{
UE_LOG ( LogCookOnTheFlyNetworkServer , Warning , TEXT ( " Failed to receive handshake payload " ) ) ;
return false ;
}
TArray < FString > TargetPlatformNames ;
HandshakeRequestPayload < < TargetPlatformNames ;
HandshakeRequestPayload < < bIsSingleThreaded ;
bool bIsOk = true ;
FString PlatformNameString ;
if ( ! TargetPlatformNames . IsEmpty ( ) )
{
// figure out the best matching target platform for the set of valid ones
for ( int32 TPIndex = 0 ; TPIndex < TargetPlatformNames . Num ( ) & & ! TargetPlatform ; TPIndex + + )
{
UE_LOG ( LogCookOnTheFlyNetworkServer , Verbose , TEXT ( " Possible Target Platform from client: %s " ) , * TargetPlatformNames [ TPIndex ] ) ;
// look for a matching target platform
for ( int32 ActiveTPIndex = 0 ; ActiveTPIndex < Owner . ActiveTargetPlatforms . Num ( ) ; ActiveTPIndex + + )
{
UE_LOG ( LogCookOnTheFlyNetworkServer , Verbose , TEXT ( " Checking against: %s " ) , * Owner . ActiveTargetPlatforms [ ActiveTPIndex ] - > PlatformName ( ) ) ;
if ( Owner . ActiveTargetPlatforms [ ActiveTPIndex ] - > PlatformName ( ) = = TargetPlatformNames [ TPIndex ] )
{
TargetPlatform = Owner . ActiveTargetPlatforms [ ActiveTPIndex ] ;
PlatformNameString = TargetPlatform - > PlatformName ( ) ;
PlatformName = FName ( PlatformNameString ) ;
break ;
}
}
}
// if we didn't find one, reject client and also print some warnings
if ( ! TargetPlatform )
{
// reject client we can't cook/compile shaders for you!
UE_LOG ( LogCookOnTheFlyNetworkServer , Warning , TEXT ( " Unable to find target platform for client, terminating client connection! " ) ) ;
for ( int32 TPIndex = 0 ; TPIndex < TargetPlatformNames . Num ( ) ; TPIndex + + )
{
UE_LOG ( LogCookOnTheFlyNetworkServer , Warning , TEXT ( " Target platforms from client: %s " ) , * TargetPlatformNames [ TPIndex ] ) ;
}
for ( int32 ActiveTPIndex = 0 ; ActiveTPIndex < Owner . ActiveTargetPlatforms . Num ( ) ; ActiveTPIndex + + )
{
UE_LOG ( LogCookOnTheFlyNetworkServer , Warning , TEXT ( " Active target platforms on server: %s " ) , * Owner . ActiveTargetPlatforms [ ActiveTPIndex ] - > PlatformName ( ) ) ;
}
bIsOk = false ;
}
}
if ( ! bIsOk )
{
return false ;
}
if ( Owner . ClientConnectedEvent . IsBound ( ) )
{
Owner . ClientConnectedEvent . Broadcast ( * this ) ;
bClientConnectedBroadcasted = true ;
}
FBufferArchive HandshakeResponsePayload ;
HandshakeResponsePayload < < bIsOk ;
HandshakeResponsePayload < < PlatformNameString ;
2023-04-03 01:51:40 -04:00
HandshakeResponsePayload < < ZenProjectId ;
HandshakeResponsePayload < < ZenHostName ;
HandshakeResponsePayload < < ZenHostPort ;
2022-05-24 02:50:39 -04:00
2023-06-20 10:53:32 -04:00
if ( ZenHostName = = " localhost " )
{
TArray < FString > RemoteHostNames ;
ISocketSubsystem * SocketSubsystem = ISocketSubsystem : : Get ( ) ;
if ( SocketSubsystem ! = nullptr )
{
TArray < TSharedPtr < FInternetAddr > > Addresses ;
if ( SocketSubsystem - > GetLocalAdapterAddresses ( Addresses ) )
{
for ( const TSharedPtr < FInternetAddr > & Address : Addresses )
{
RemoteHostNames . Add ( Address - > ToString ( false ) ) ;
}
}
}
int32 RemoteHostNameCount = RemoteHostNames . Num ( ) ;
HandshakeResponsePayload < < RemoteHostNameCount ;
for ( FString RemoteHostName : RemoteHostNames )
{
HandshakeResponsePayload < < RemoteHostName ;
}
}
2022-05-24 02:50:39 -04:00
if ( ! SendPayload ( HandshakeResponsePayload ) )
{
return false ;
}
# if UE_BUILD_DEBUG
// this thread needs more space in debug builds as it tries to log messages and such
const static uint32 ThreadSize = 2 * 1024 * 1024 ;
# else
const static uint32 ThreadSize = 1 * 1024 * 1024 ;
# endif
WorkerThread = FRunnableThread : : Create ( this , TEXT ( " FCookOnTheFlyClientConnection " ) , ThreadSize , TPri_AboveNormal ) ;
return true ;
}
uint32 FCookOnTheFlyClientConnectionBase : : Run ( )
{
while ( ! bStopRequested )
{
// read a header and payload pair
FArrayReader Payload ;
if ( ! ReceivePayload ( Payload ) )
{
UE_LOG ( LogCookOnTheFlyNetworkServer , Warning , TEXT ( " ReceivePayload failed " ) ) ;
break ;
}
ProcessPayload ( Payload ) ;
}
return 0 ;
}
bool FCookOnTheFlyClientConnectionBase : : ProcessPayload ( FArchive & Payload )
{
using namespace UE : : Cook ;
FCookOnTheFlyRequest Request ;
Payload < < Request ;
return Owner . ProcessRequest ( * this , Request ) ;
}
bool FCookOnTheFlyClientConnectionBase : : SendMessage ( const UE : : Cook : : FCookOnTheFlyMessage & Message )
{
FBufferArchive Payload ;
2023-01-12 13:17:30 -05:00
Payload . Reserve ( IntCastChecked < int32 > ( Message . TotalSize ( ) ) ) ;
2022-05-24 02:50:39 -04:00
Payload < < const_cast < UE : : Cook : : FCookOnTheFlyMessage & > ( Message ) ;
return SendPayload ( Payload ) ;
}
2023-04-03 01:51:40 -04:00
FCookOnTheFlyNetworkServerBase : : FCookOnTheFlyNetworkServerBase ( const TArray < ITargetPlatform * > & InActiveTargetPlatforms )
2022-05-24 02:50:39 -04:00
: ActiveTargetPlatforms ( InActiveTargetPlatforms )
{
}
bool FCookOnTheFlyNetworkServerBase : : ProcessRequest ( FCookOnTheFlyClientConnectionBase & Connection , const UE : : Cook : : FCookOnTheFlyRequest & Request )
{
using namespace UE : : Cook ;
ECookOnTheFlyMessage RequestType = Request . GetMessageType ( ) ;
FHandleRequestDelegate * Handler = Handlers . Find ( RequestType ) ;
if ( ! Handler )
{
return false ;
}
if ( ! Handler - > IsBound ( ) )
{
return false ;
}
return Handler - > Execute ( Connection , Request ) ;
}
UE : : Cook : : ICookOnTheFlyNetworkServer : : FHandleRequestDelegate & FCookOnTheFlyNetworkServerBase : : OnRequest ( UE : : Cook : : ECookOnTheFlyMessage MessageType )
{
FHandleRequestDelegate & Handler = Handlers . FindOrAdd ( MessageType ) ;
return Handler ;
}