Esempio n. 1
0
void AOnlineBeaconHost::RegisterHost(AOnlineBeaconHostObject* NewHostObject)
{
	const FString& BeaconType = NewHostObject->GetBeaconType();

	bool bFound = false;
	for (int32 HostIdx=0; HostIdx < Children.Num(); HostIdx++)
	{
		AOnlineBeaconHostObject* HostObject = Cast<AOnlineBeaconHostObject>(Children[HostIdx]);
		if (HostObject && HostObject->GetBeaconType() == BeaconType)
		{
			bFound = true;
			break;
		}
	}

	if (!bFound)
	{
		NewHostObject->SetOwner(this);
		OnBeaconSpawned(BeaconType).BindUObject(NewHostObject, &AOnlineBeaconHostObject::SpawnBeaconActor);
		OnBeaconConnected(BeaconType).BindUObject(NewHostObject, &AOnlineBeaconHostObject::ClientConnected);
	}
	else
	{
		UE_LOG(LogBeacon, Warning, TEXT("Beacon host type %s already exists"), *BeaconType);
	}
}
Esempio n. 2
0
void AOnlineBeaconClient::OnNetCleanup(UNetConnection* Connection)
{
	AOnlineBeaconHostObject* BeaconHost = GetBeaconOwner();
	if (BeaconHost)
	{
		BeaconHost->RemoveClientActor(this);
	}
}
void AOnlineBeaconClient::OnNetCleanup(UNetConnection* Connection)
{
	AOnlineBeaconHostObject* BeaconHostObject = GetBeaconOwner();
	if (BeaconHostObject)
	{
		BeaconHostObject->NotifyClientDisconnected(this);
	}
}
Esempio n. 4
0
void AOnlineBeaconHost::UnregisterHost(const FString& BeaconType)
{
	AOnlineBeaconHostObject* HostObject = GetHost(BeaconType);
	if (HostObject)
	{
		HostObject->SetOwner(NULL);
	}
	
	OnBeaconSpawned(BeaconType).Unbind();
	OnBeaconConnected(BeaconType).Unbind();
}
void AOnlineBeaconClient::OnNetCleanup(UNetConnection* Connection)
{
	ensure(Connection == BeaconConnection);
	SetConnectionState(EBeaconConnectionState::Closed);

	AOnlineBeaconHostObject* BeaconHostObject = GetBeaconOwner();
	if (BeaconHostObject)
	{
		BeaconHostObject->NotifyClientDisconnected(this);
	}
}
Esempio n. 6
0
AOnlineBeaconHostObject* AOnlineBeaconHost::GetHost(const FString& BeaconType)
{
	for (int32 HostIdx=0; HostIdx < Children.Num(); HostIdx++)
	{
		AOnlineBeaconHostObject* HostObject = Cast<AOnlineBeaconHostObject>(Children[HostIdx]);
		if (HostObject && HostObject->GetBeaconType() == BeaconType)
		{
			return HostObject;
		}
	}

	return NULL;
}
void AOnlineBeaconHost::NotifyControlMessage(UNetConnection* Connection, uint8 MessageType, class FInBunch& Bunch)
{
	if(NetDriver->ServerConnection == nullptr)
	{
		bool bCloseConnection = false;

		// We are the server.
#if !(UE_BUILD_SHIPPING && WITH_EDITOR)
		UE_LOG(LogBeacon, Verbose, TEXT("%s[%s] Host received: %s"), *GetName(), Connection ? *Connection->GetName() : TEXT("Invalid"), FNetControlMessageInfo::GetName(MessageType));
#endif
		switch (MessageType)
		{
		case NMT_Hello:
			{
				UE_LOG(LogBeacon, Log, TEXT("Beacon Hello"));
				uint8 IsLittleEndian;

				uint32 RemoteNetworkVersion = 0;
				uint32 LocalNetworkVersion = FNetworkVersion::GetLocalNetworkVersion();

				FNetControlMessage<NMT_Hello>::Receive(Bunch, IsLittleEndian, RemoteNetworkVersion);

				if (!FNetworkVersion::IsNetworkCompatible(LocalNetworkVersion, RemoteNetworkVersion))
				{
					UE_LOG(LogBeacon, Log, TEXT("Client not network compatible %s"), *Connection->GetName());
					FNetControlMessage<NMT_Upgrade>::Send(Connection, LocalNetworkVersion);
					bCloseConnection = true;
				}
				else
				{
					Connection->Challenge = FString::Printf(TEXT("%08X"), FPlatformTime::Cycles());
					FNetControlMessage<NMT_BeaconWelcome>::Send(Connection);
					Connection->FlushNet();
				}
				break;
			}
		case NMT_Netspeed:
			{
				int32 Rate;
				FNetControlMessage<NMT_Netspeed>::Receive(Bunch, Rate);
				Connection->CurrentNetSpeed = FMath::Clamp(Rate, 1800, NetDriver->MaxClientRate);
				UE_LOG(LogBeacon, Log, TEXT("Client netspeed is %i"), Connection->CurrentNetSpeed);
				break;
			}
		case NMT_BeaconJoin:
			{
				FString ErrorMsg;
				FString BeaconType;
				FUniqueNetIdRepl UniqueId;
				FNetControlMessage<NMT_BeaconJoin>::Receive(Bunch, BeaconType, UniqueId);
				UE_LOG(LogBeacon, Log, TEXT("Beacon Join %s %s"), *BeaconType, *UniqueId.ToDebugString());

				if (Connection->ClientWorldPackageName == NAME_None)
				{
					AOnlineBeaconClient* ClientActor = GetClientActor(Connection);
					if (ClientActor == nullptr)
					{
						UWorld* World = GetWorld();
						Connection->ClientWorldPackageName = World->GetOutermost()->GetFName();

						AOnlineBeaconClient* NewClientActor = nullptr;
						FOnBeaconSpawned* OnBeaconSpawnedDelegate = OnBeaconSpawnedMapping.Find(BeaconType);
						if (OnBeaconSpawnedDelegate && OnBeaconSpawnedDelegate->IsBound())
						{
							NewClientActor = OnBeaconSpawnedDelegate->Execute(Connection);
						}

						if (NewClientActor && BeaconType == NewClientActor->GetBeaconType())
						{
							NewClientActor->SetConnectionState(EBeaconConnectionState::Pending);

							FNetworkGUID NetGUID = Connection->Driver->GuidCache->AssignNewNetGUID_Server(NewClientActor);
							NewClientActor->SetNetConnection(Connection);
							Connection->PlayerId = UniqueId;
							Connection->OwningActor = NewClientActor;
							NewClientActor->Role = ROLE_Authority;
							NewClientActor->SetReplicates(false);
							check(NetDriverName == NetDriver->NetDriverName);
							NewClientActor->SetNetDriverName(NetDriverName);
							ClientActors.Add(NewClientActor);
							FNetControlMessage<NMT_BeaconAssignGUID>::Send(Connection, NetGUID);
						}
						else
						{
							ErrorMsg = NSLOCTEXT("NetworkErrors", "BeaconSpawnFailureError", "Join failure, Couldn't spawn beacon.").ToString();
						}
					}
					else
					{
						ErrorMsg = NSLOCTEXT("NetworkErrors", "BeaconSpawnExistingActorError", "Join failure, existing beacon actor.").ToString();
					}
				}
				else
				{
					ErrorMsg = NSLOCTEXT("NetworkErrors", "BeaconSpawnClientWorldPackageNameError", "Join failure, existing ClientWorldPackageName.").ToString();
				}

				if (!ErrorMsg.IsEmpty())
				{
					UE_LOG(LogBeacon, Log, TEXT("%s: %s"), *Connection->GetName(), *ErrorMsg);
					FNetControlMessage<NMT_Failure>::Send(Connection, ErrorMsg);
					bCloseConnection = true;
				}

				break;
			}
		case NMT_BeaconNetGUIDAck:
			{
				FString ErrorMsg;
				FString BeaconType;
				FNetControlMessage<NMT_BeaconNetGUIDAck>::Receive(Bunch, BeaconType);

				AOnlineBeaconClient* ClientActor = GetClientActor(Connection);
				if (ClientActor && BeaconType == ClientActor->GetBeaconType())
				{
					FOnBeaconConnected* OnBeaconConnectedDelegate = OnBeaconConnectedMapping.Find(BeaconType);
					if (OnBeaconConnectedDelegate)
					{
						ClientActor->SetReplicates(true);
						ClientActor->SetAutonomousProxy(true);
						ClientActor->SetConnectionState(EBeaconConnectionState::Open);
						// Send an RPC to the client to open the actor channel and guarantee RPCs will work
						ClientActor->ClientOnConnected();
						UE_LOG(LogBeacon, Log, TEXT("Handshake complete for %s!"), *ClientActor->GetName());

						OnBeaconConnectedDelegate->ExecuteIfBound(ClientActor, Connection);
					}
					else
					{
						// Failed to connect.
						ErrorMsg = NSLOCTEXT("NetworkErrors", "BeaconSpawnNetGUIDAckError1", "Join failure, no host object at NetGUIDAck.").ToString();
					}
				}
				else
				{
					// Failed to connect.
					ErrorMsg = NSLOCTEXT("NetworkErrors", "BeaconSpawnNetGUIDAckError2", "Join failure, no actor at NetGUIDAck.").ToString();
				}

				if (!ErrorMsg.IsEmpty())
				{
					UE_LOG(LogBeacon, Log, TEXT("%s: %s"), *Connection->GetName(), *ErrorMsg);
					FNetControlMessage<NMT_Failure>::Send(Connection, ErrorMsg);
					bCloseConnection = true;
				}

				break;
			}
		case NMT_BeaconWelcome:
		case NMT_BeaconAssignGUID:
		default:
			{
				FString ErrorMsg = NSLOCTEXT("NetworkErrors", "BeaconSpawnUnexpectedError", "Join failure, unexpected control message.").ToString();
				UE_LOG(LogBeacon, Log, TEXT("%s: %s"), *Connection->GetName(), *ErrorMsg);
				FNetControlMessage<NMT_Failure>::Send(Connection, ErrorMsg);
				bCloseConnection = true;
			}
			break;
		}

		if (bCloseConnection)
		{		
			UE_LOG(LogBeacon, Verbose, TEXT("Closing connection %s: %s"), *Connection->GetName(), *Connection->PlayerId.ToDebugString());
			AOnlineBeaconClient* ClientActor = GetClientActor(Connection);
			if (ClientActor)
			{
				UE_LOG(LogBeacon, Verbose, TEXT("- BeaconActor: %s %s"), *ClientActor->GetName(), *ClientActor->GetBeaconType());
				AOnlineBeaconHostObject* BeaconHostObject = GetHost(ClientActor->GetBeaconType());
				if (BeaconHostObject)
				{
					UE_LOG(LogBeacon, Verbose, TEXT("- HostObject: %s"), *BeaconHostObject->GetName());
					BeaconHostObject->NotifyClientDisconnected(ClientActor);
				}

				RemoveClientActor(ClientActor);
			}

			Connection->FlushNet(true);
			Connection->Close();
			UE_LOG(LogBeacon, Verbose, TEXT("--------------------------------"));
		}
	}
}