You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Game client now accepts only -filehostip for connection to a CTOF server, -cookonthefly is no longer necessary and is ignored. Game client will now receive ProjectName (ProjectId), Platform (OplogId), Zen server host name and port from COTF server if running with zenstore. Fixed issues with generating the ProjectId from a path where drive letters where lower case. #rb zousar.shaker pj.kack #preflight [CL 24889513 by dan engelbrecht in ue5-main branch]
277 lines
6.9 KiB
C++
277 lines
6.9 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "TCPServer.h"
|
|
#include "HAL/RunnableThread.h"
|
|
#include "Misc/OutputDeviceRedirector.h"
|
|
#include "IPAddress.h"
|
|
#include "Sockets.h"
|
|
#include "SocketSubsystem.h"
|
|
#include "NetworkMessage.h"
|
|
|
|
class FCookOnTheFlyClientConnectionTCP
|
|
: public FCookOnTheFlyClientConnectionBase
|
|
{
|
|
public:
|
|
|
|
FCookOnTheFlyClientConnectionTCP(FCookOnTheFlyServerTCP& InOwner, FSocket* InSocket)
|
|
: FCookOnTheFlyClientConnectionBase(InOwner)
|
|
, Socket(InSocket)
|
|
{
|
|
}
|
|
|
|
~FCookOnTheFlyClientConnectionTCP()
|
|
{
|
|
ISocketSubsystem::Get()->DestroySocket(Socket);
|
|
}
|
|
|
|
virtual bool ReceivePayload(FArrayReader& Payload) override
|
|
{
|
|
return FNFSMessageHeader::ReceivePayload(Payload, FSimpleAbstractSocket_FSocket(Socket));
|
|
}
|
|
|
|
virtual bool SendPayload(const TArray<uint8>& Payload) override
|
|
{
|
|
return FNFSMessageHeader::WrapAndSendPayload(Payload, FSimpleAbstractSocket_FSocket(Socket));
|
|
}
|
|
|
|
virtual void OnExit() override
|
|
{
|
|
Socket->Close();
|
|
}
|
|
|
|
void GetAddress(FInternetAddr& Addr)
|
|
{
|
|
Socket->GetAddress(Addr);
|
|
}
|
|
|
|
void GetPeerAddress(FInternetAddr& Addr)
|
|
{
|
|
Socket->GetPeerAddress(Addr);
|
|
}
|
|
|
|
private:
|
|
FSocket* Socket;
|
|
};
|
|
|
|
|
|
|
|
/* FCookOnTheFlyServerTCP constructors
|
|
*****************************************************************************/
|
|
|
|
FCookOnTheFlyServerTCP::FCookOnTheFlyServerTCP(int32 InPort, const TArray<ITargetPlatform*>& InTargetPlatforms)
|
|
: FCookOnTheFlyNetworkServerBase(InTargetPlatforms)
|
|
, Port(InPort)
|
|
{
|
|
if (Port < 0)
|
|
{
|
|
Port = DEFAULT_TCP_FILE_SERVING_PORT;
|
|
}
|
|
|
|
Running.Set(false);
|
|
StopRequested.Set(false);
|
|
}
|
|
|
|
FCookOnTheFlyServerTCP::~FCookOnTheFlyServerTCP()
|
|
{
|
|
// Kill the running thread.
|
|
if (Thread != NULL)
|
|
{
|
|
Thread->Kill(true);
|
|
|
|
delete Thread;
|
|
Thread = NULL;
|
|
}
|
|
|
|
// We are done with the socket.
|
|
Socket->Close();
|
|
ISocketSubsystem::Get()->DestroySocket(Socket);
|
|
Socket = NULL;
|
|
}
|
|
|
|
bool FCookOnTheFlyServerTCP::Start()
|
|
{
|
|
// make sure sockets are going
|
|
ISocketSubsystem* SocketSubsystem = ISocketSubsystem::Get();
|
|
|
|
if (!SocketSubsystem)
|
|
{
|
|
UE_LOG(LogCookOnTheFlyNetworkServer, Error, TEXT("Could not get socket subsystem."));
|
|
}
|
|
else
|
|
{
|
|
// listen on any IP address
|
|
ListenAddr = SocketSubsystem->GetLocalBindAddr(*GLog);
|
|
ListenAddr->SetPort(Port);
|
|
|
|
// create a server TCP socket
|
|
Socket = SocketSubsystem->CreateSocket(NAME_Stream, TEXT("FCookOnTheFlyServerTCP-listen"), ListenAddr->GetProtocolType());
|
|
|
|
if (!Socket)
|
|
{
|
|
UE_LOG(LogCookOnTheFlyNetworkServer, Error, TEXT("Could not create listen socket."));
|
|
}
|
|
else
|
|
{
|
|
Socket->SetReuseAddr();
|
|
Socket->SetNoDelay();
|
|
|
|
// bind to the address
|
|
if (!Socket->Bind(*ListenAddr))
|
|
{
|
|
UE_LOG(LogCookOnTheFlyNetworkServer, Warning, TEXT("Failed to bind listen socket %s in FCookOnTheFlyServerTCP"), *ListenAddr->ToString(true));
|
|
}
|
|
// listen for connections
|
|
else if (!Socket->Listen(16))
|
|
{
|
|
UE_LOG(LogCookOnTheFlyNetworkServer, Warning, TEXT("Failed to listen on socket %s in FCookOnTheFlyServerTCP"), *ListenAddr->ToString(true));
|
|
}
|
|
else
|
|
{
|
|
// set the port on the listen address to be the same as the port on the socket
|
|
int32 port = Socket->GetPortNo();
|
|
check((Port == 0 && port != 0) || port == Port);
|
|
ListenAddr->SetPort(port);
|
|
|
|
// now create a thread to accept connections
|
|
Thread = FRunnableThread::Create(this, TEXT("FCookOnTheFlyServerTCP"), 8 * 1024, TPri_AboveNormal);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/* FRunnable overrides
|
|
*****************************************************************************/
|
|
|
|
uint32 FCookOnTheFlyServerTCP::Run()
|
|
{
|
|
Running.Set(true);
|
|
// go until requested to be done
|
|
while (!StopRequested.GetValue())
|
|
{
|
|
bool bReadReady = false;
|
|
|
|
// clean up closed connections
|
|
for (int32 ConnectionIndex = 0; ConnectionIndex < Connections.Num(); ++ConnectionIndex)
|
|
{
|
|
FCookOnTheFlyClientConnectionTCP* Connection = Connections[ConnectionIndex];
|
|
|
|
if (!Connection->IsRunning())
|
|
{
|
|
UE_LOG(LogCookOnTheFlyNetworkServer, Display, TEXT("Client disconnected."));
|
|
Connections.RemoveAtSwap(ConnectionIndex);
|
|
delete Connection;
|
|
}
|
|
}
|
|
|
|
// check for incoming connections
|
|
if (Socket->WaitForPendingConnection(bReadReady, FTimespan::FromSeconds(0.25f)))
|
|
{
|
|
if (bReadReady)
|
|
{
|
|
FSocket* ClientSocket = Socket->Accept(TEXT("Remote Console Connection"));
|
|
|
|
if (ClientSocket != NULL)
|
|
{
|
|
TSharedPtr<FInternetAddr> Addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
|
|
ClientSocket->GetAddress(*Addr);
|
|
TSharedPtr<FInternetAddr> PeerAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
|
|
ClientSocket->GetPeerAddress(*PeerAddr);
|
|
|
|
for (auto PreviousConnection : Connections)
|
|
{
|
|
TSharedPtr<FInternetAddr> PreviousAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();;
|
|
PreviousConnection->GetAddress(*PreviousAddr);
|
|
TSharedPtr<FInternetAddr> PreviousPeerAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();;
|
|
PreviousConnection->GetPeerAddress(*PreviousPeerAddr);
|
|
if ((*Addr == *PreviousAddr) &&
|
|
(*PeerAddr == *PreviousPeerAddr))
|
|
{
|
|
// kill the connection
|
|
PreviousConnection->Disconnect();
|
|
UE_LOG(LogCookOnTheFlyNetworkServer, Warning, TEXT("Killing client connection because new client connected from same address."));
|
|
}
|
|
}
|
|
|
|
FCookOnTheFlyClientConnectionTCP* Connection = new FCookOnTheFlyClientConnectionTCP(*this, ClientSocket);
|
|
if (Connection->Initialize())
|
|
{
|
|
Connections.Add(Connection);
|
|
UE_LOG(LogCookOnTheFlyNetworkServer, Display, TEXT("Client connected."));
|
|
}
|
|
else
|
|
{
|
|
delete Connection;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FPlatformProcess::Sleep(0.25f);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void FCookOnTheFlyServerTCP::Exit()
|
|
{
|
|
// close all connections
|
|
for (int32 ConnectionIndex = 0; ConnectionIndex < Connections.Num(); ConnectionIndex++)
|
|
{
|
|
|
|
delete Connections[ConnectionIndex];
|
|
}
|
|
|
|
Connections.Empty();
|
|
}
|
|
|
|
|
|
/* ICookOnTheFlyNetworkServer overrides
|
|
*****************************************************************************/
|
|
|
|
FString FCookOnTheFlyServerTCP::GetSupportedProtocol() const
|
|
{
|
|
return FString("tcp");
|
|
}
|
|
|
|
|
|
bool FCookOnTheFlyServerTCP::GetAddressList(TArray<TSharedPtr<FInternetAddr> >& OutAddresses) const
|
|
{
|
|
if (ListenAddr.IsValid())
|
|
{
|
|
FString ListenAddressString = ListenAddr->ToString(true);
|
|
|
|
if (ListenAddressString.StartsWith(TEXT("0.0.0.0")))
|
|
{
|
|
if (ISocketSubsystem::Get()->GetLocalAdapterAddresses(OutAddresses))
|
|
{
|
|
for (int32 AddressIndex = 0; AddressIndex < OutAddresses.Num(); ++AddressIndex)
|
|
{
|
|
OutAddresses[AddressIndex]->SetPort(ListenAddr->GetPort());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OutAddresses.Add(ListenAddr);
|
|
}
|
|
}
|
|
|
|
return (OutAddresses.Num() > 0);
|
|
}
|
|
|
|
|
|
bool FCookOnTheFlyServerTCP::IsReadyToAcceptConnections(void) const
|
|
{
|
|
return (Running.GetValue() != 0);
|
|
}
|
|
|
|
int32 FCookOnTheFlyServerTCP::NumConnections(void) const
|
|
{
|
|
return Connections.Num();
|
|
}
|