void UUpdateManager::StartPlatformEnvironmentCheck()
{
	IOnlineSubsystem* OnlineSubConsole = IOnlineSubsystem::GetByPlatform();
	if (!bPlatformEnvironmentDetected &&
		OnlineSubConsole != nullptr &&
		OnlineSubConsole->GetIdentityInterface().IsValid())
	{
		SetUpdateState(EUpdateState::DetectingPlatformEnvironment);

		ULocalPlayer* LP = GetGameInstance()->GetFirstGamePlayer();
		if (LP != nullptr)
		{
			const int32 ControllerId = LP->GetControllerId();
			OnLoginConsoleCompleteHandle = OnlineSubConsole->GetIdentityInterface()->AddOnLoginCompleteDelegate_Handle(
				ControllerId,
				FOnLoginCompleteDelegate::CreateUObject(this, &ThisClass::PlatformEnvironmentCheck_OnLoginConsoleComplete)
				);

			OnlineSubConsole->GetIdentityInterface()->Login(ControllerId, FOnlineAccountCredentials());
		}
	}
	else
	{
		StartHotfixCheck();
	}
}
void APuzzlePresetPlayerController::OnEndTurn()
{
	/*UPuzzlePresetGameInstance* ppgi = Cast<UPuzzlePresetGameInstance>(GetGameInstance());
	ULocalPlayer* LocalPlayer = GetLocalPlayer();
	ppgi->HostSession(MakeShareable(LocalPlayer->GetControllerId()),)
	return;*/

	IOnlineSubsystem* ion = IOnlineSubsystem::Get(FName("Steam"));

	if (ion != nullptr)
	{
		ULocalPlayer* LocalPlayer = GetLocalPlayer();
		if (LocalPlayer && LocalPlayer->GetControllerId() != -1)
		{
			UE_LOG(LogTemp, Warning, TEXT("steam user name: %s"), *PlayerState->PlayerName);
			uint8 status = ion->GetIdentityInterface()->GetLoginStatus(LocalPlayer->GetControllerId());
			UE_LOG(LogTemp, Warning, TEXT("steam user status: %d"), status);
		}

		/*if (ion->InitSteamworksClient(false, 480))
		{
		UE_LOG(LogTemp, Warning, TEXT("Steam API initialized succesfully!"));
		}
		else
		{
		UE_LOG(LogTemp, Warning, TEXT("Failed to initialize Steam API :("));
		}*/
	}
}
Beispiel #3
0
/* After release of left mouse button, check if this unit is within selection box. */ 
void ARTSUnit::CheckForSelection()
{

	/* Find screen coordinates of the unit. */
	FVector2D MyResult = FVector2D(0, 0);

	ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PC->Player);

	if (LocalPlayer != NULL && LocalPlayer->ViewportClient != NULL && LocalPlayer->ViewportClient->Viewport != NULL)
	{
		FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
			LocalPlayer->ViewportClient->Viewport,
			GetWorld()->Scene,
			LocalPlayer->ViewportClient->EngineShowFlags)
			.SetRealtimeUpdate(true));

		FVector ViewLocation;
		FRotator ViewRotation;
		FSceneView* SceneView = LocalPlayer->CalcSceneView(&ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport);

		if (SceneView)
		{
			auto MyWorldPosition = GetActorLocation();
			MyResult;
			SceneView->WorldToPixel(MyWorldPosition, MyResult);
		}
	}

	/* If the selection box contains the screen postion: */
	if (ARTSHUD::SelectionContainsPoint(MyResult)){

		// Select this unit, and leave possibility to select others.
		Select();
	}
}
void UShowLoginUICallbackProxy::OnShowLoginUICompleted(TSharedPtr<const FUniqueNetId> UniqueId, int LocalPlayerNum)
{
	// Update the cached unique ID for the local player and the player state.
	APlayerController* PlayerController = PlayerControllerWeakPtr.Get();
	
	if (PlayerController != nullptr)
	{
		ULocalPlayer* LocalPlayer = PlayerController->GetLocalPlayer();
		if (LocalPlayer != nullptr)
		{
			LocalPlayer->SetCachedUniqueNetId(UniqueId);
		}
		
		if (PlayerController->PlayerState != nullptr)
		{
			PlayerController->PlayerState->SetUniqueId(UniqueId);
		}
	}

	if (UniqueId.IsValid())
	{
		OnSuccess.Broadcast(PlayerControllerWeakPtr.Get());
	}
	else
	{
		OnFailure.Broadcast(PlayerControllerWeakPtr.Get());
	}
}
Beispiel #5
0
FVector2D AHUD::GetCoordinateOffset() const
{
	FVector2D Offset(0.f, 0.f);

	ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(GetOwningPlayerController()->Player);

	if (LocalPlayer)
	{
		// Create a view family for the game viewport
		FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
			LocalPlayer->ViewportClient->Viewport,
			GetWorld()->Scene,
			LocalPlayer->ViewportClient->EngineShowFlags)
			.SetRealtimeUpdate(true));

		// Calculate a view where the player is to update the streaming from the players start location
		FVector ViewLocation;
		FRotator ViewRotation;
		FSceneView* SceneView = LocalPlayer->CalcSceneView(&ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport);

		if (SceneView)
		{
			Offset.X = (SceneView->ViewRect.Min.X - SceneView->UnscaledViewRect.Min.X) // This accounts for the borders when the aspect ratio is locked
				- SceneView->UnscaledViewRect.Min.X;						// And this will deal with the viewport offset if its a split screen

			Offset.Y = (SceneView->ViewRect.Min.Y - SceneView->UnscaledViewRect.Min.Y)
				- SceneView->UnscaledViewRect.Min.Y;
		}
	}

	return Offset;
}
void UAdvancedFriendsLibrary::IsAFriend(APlayerController *PlayerController, const FBPUniqueNetId UniqueNetId, bool &IsFriend)
{
	if (!PlayerController)
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("IsAFriend Had a bad Player Controller!"));
		return;
	}

	if (!UniqueNetId.IsValid())
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("IsAFriend Had a bad UniqueNetId!"));
		return;
	}

	IOnlineFriendsPtr FriendsInterface = Online::GetFriendsInterface();

	if (!FriendsInterface.IsValid())
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("IsAFriend Failed to get friends interface!"));
		return;
	}

	ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerController->Player);

	if (!Player)
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("IsAFriend Failed to get LocalPlayer!"));
		return;
	}

	IsFriend = FriendsInterface->IsFriend(Player->GetControllerId(), *UniqueNetId.GetUniqueNetId(), EFriendsLists::ToString(EFriendsLists::Type::Default));
}
void UGetFriendsCallbackProxy::Activate()
{
	if (!PlayerControllerWeakPtr.IsValid())
	{
		// Fail immediately
		UE_LOG(AdvancedGetFriendsLog, Warning, TEXT("GetFriends Failed received a bad player controller!"));
		TArray<FBPFriendInfo> EmptyArray;
		OnFailure.Broadcast(EmptyArray);
		return;
	}

	IOnlineFriendsPtr Friends = Online::GetFriendsInterface();
	if (Friends.IsValid())
	{	
		ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerControllerWeakPtr->Player);

		Friends->ReadFriendsList(Player->GetControllerId(), EFriendsLists::ToString((EFriendsLists::Type::Default)), FriendListReadCompleteDelegate);
		return;
	}

	// Fail immediately
	TArray<FBPFriendInfo> EmptyArray;

	OnFailure.Broadcast(EmptyArray);
}
bool UAmethystPersistentUser::IsInvertedYAxisDirty() const
{
    bool bIsInvertedYAxisDirty = false;
    if (GEngine)
    {
        TArray<APlayerController*> PlayerList;
        GEngine->GetAllLocalPlayerControllers(PlayerList);
        
        for (auto It = PlayerList.CreateIterator(); It; ++It)
        {
            APlayerController* PC = *It;
            if (!PC || !PC->Player || !PC->PlayerInput)
            {
                continue;
            }
            
            // Update key bindings for the current user only
            ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PC->Player);
            if(!LocalPlayer || LocalPlayer->GetControllerId() != UserIndex)
            {
                continue;
            }
            
            bIsInvertedYAxisDirty |= PC->PlayerInput->GetInvertAxis("Lookup") != GetInvertedYAxis();
            bIsInvertedYAxisDirty |= PC->PlayerInput->GetInvertAxis("LookupRate") != GetInvertedYAxis();
        }
    }
    
    return bIsInvertedYAxisDirty;
}
Beispiel #9
0
void ATimeIsUpPlayerState::InformAboutRing_Implementation(class ATimeIsUpPlayerState* PlayerState) {
	/* Search for the player */
	for (FConstPlayerControllerIterator It = GetWorld()->GetPlayerControllerIterator(); It; ++It) {
		ATimeIsUpPlayerController *TestPC = Cast<ATimeIsUpPlayerController>(*It);
		if (TestPC) {
			ULocalPlayer *LocalPlayer = Cast<ULocalPlayer>(TestPC->Player);
			TSharedPtr<FUniqueNetId> LocalID = LocalPlayer->GetUniqueNetId();
			if (LocalID.IsValid() && *LocalPlayer->GetUniqueNetId() == *PlayerState->UniqueId) {
				TestPC->OnRingGet();
			}
		}
	}
}
void UAdvancedFriendsLibrary::SendSessionInviteToFriends(APlayerController *PlayerController, const TArray<FBPUniqueNetId> &Friends, TEnumAsByte<EBlueprintResultSwitch::Type> &Result)
{
	if (!PlayerController)
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had a bad Player Controller!"));
		Result = EBlueprintResultSwitch::Type::OnFailure;
		return;
	}

	if (Friends.Num() < 1)
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had no friends in invitation array!"));
		Result = EBlueprintResultSwitch::Type::OnFailure;
		return;
	}

	IOnlineSessionPtr SessionInterface = Online::GetSessionInterface();

	if (!SessionInterface.IsValid())
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Failed to get session interface!"));
		Result = EBlueprintResultSwitch::Type::OnFailure;
		return;
	}

	ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerController->Player);

	if (!Player)
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend failed to get LocalPlayer!"));
		Result = EBlueprintResultSwitch::Type::OnFailure;
		return;
	}

	TArray<TSharedRef<const FUniqueNetId>> List;
	for (int i = 0; i < Friends.Num(); i++)
	{
		TSharedRef<const FUniqueNetId> val(Friends[i].UniqueNetId.ToSharedRef());
		//TSharedRef<const FUniqueNetId> val(Friends[i].GetUniqueNetId());
		List.Add(val);
	}

	if (SessionInterface->SendSessionInviteToFriends(Player->GetControllerId(), GameSessionName, List))
	{
		Result = EBlueprintResultSwitch::Type::OnSuccess;
		return;
	}

	Result = EBlueprintResultSwitch::Type::OnFailure;
	return;
}
void UAdvancedFriendsLibrary::GetStoredFriendsList(APlayerController *PlayerController, TArray<FBPFriendInfo> &FriendsList)
{

	if (!PlayerController)
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriendsList Had a bad Player Controller!"));
		return;
	}

	IOnlineFriendsPtr FriendsInterface = Online::GetFriendsInterface();
	
	if (!FriendsInterface.IsValid())
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriendsList Failed to get friends interface!"));
		return;
	}

	ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerController->Player);

	if (!Player)
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriendsList Failed to get LocalPlayer!"));
		return;
	}


	TArray< TSharedRef<FOnlineFriend> > FriendList;
	FriendsInterface->GetFriendsList(Player->GetControllerId(), EFriendsLists::ToString((EFriendsLists::Type::Default)), FriendList);

	for (int32 i = 0; i < FriendList.Num(); i++)
	{
		TSharedRef<FOnlineFriend> Friend = FriendList[i];
		FBPFriendInfo BPF;

		BPF.OnlineState = ((EBPOnlinePresenceState::Type)((int32)Friend->GetPresence().Status.State));
		BPF.DisplayName = Friend->GetDisplayName();
		BPF.RealName = Friend->GetRealName();
		BPF.UniqueNetId.SetUniqueNetId(Friend->GetUserId());
		BPF.bIsPlayingSameGame = Friend->GetPresence().bIsPlayingThisGame;

		BPF.PresenceInfo.bIsOnline = Friend->GetPresence().bIsOnline;
		BPF.PresenceInfo.bIsPlaying = Friend->GetPresence().bIsPlaying;
		BPF.PresenceInfo.PresenceState = ((EBPOnlinePresenceState::Type)((int32)Friend->GetPresence().Status.State));
		BPF.PresenceInfo.StatusString = Friend->GetPresence().Status.StatusStr;
		BPF.PresenceInfo.bIsJoinable = Friend->GetPresence().bIsJoinable;
		BPF.PresenceInfo.bIsPlayingThisGame = Friend->GetPresence().bIsPlayingThisGame;

		FriendsList.Add(BPF);
	}
}
void AEyeXSimpleInteractorPawn::UpdateRegion()
{
	FVector Origin;
	FVector Extents;
	GetActorBounds(false, Origin, Extents);

	auto playerController = Cast<APlayerController>(Controller);
	ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(playerController->Player);

	auto ViewFamilyArguments = FSceneViewFamily::ConstructionValues(LocalPlayer->ViewportClient->Viewport, GetWorld()->Scene, LocalPlayer->ViewportClient->EngineShowFlags);
	ViewFamilyArguments.SetRealtimeUpdate(true);
	FSceneViewFamilyContext ViewFamily(ViewFamilyArguments);

	// Calculate a view where the player is to update the streaming from the players start location
	FVector ViewLocation;
	FRotator ViewRotation;
	FSceneView* SceneView = LocalPlayer->CalcSceneView(&ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport);

	FVector2D ExtentPoints[8];
	SceneView->WorldToPixel(Origin + FVector(Extents.X, Extents.Y, Extents.Z), ExtentPoints[0]); //Right Top Front
	SceneView->WorldToPixel(Origin + FVector(Extents.X, Extents.Y, -Extents.Z), ExtentPoints[1]); //Right Top Back
	SceneView->WorldToPixel(Origin + FVector(Extents.X, -Extents.Y, Extents.Z), ExtentPoints[2]); //Right Bottom Front
	SceneView->WorldToPixel(Origin + FVector(Extents.X, -Extents.Y, -Extents.Z), ExtentPoints[3]); //Right Bottom Back
	SceneView->WorldToPixel(Origin + FVector(-Extents.X, Extents.Y, Extents.Z), ExtentPoints[4]); //Left Top Front
	SceneView->WorldToPixel(Origin + FVector(-Extents.X, Extents.Y, -Extents.Z), ExtentPoints[5]); //Left Top Back
	SceneView->WorldToPixel(Origin + FVector(-Extents.X, -Extents.Y, Extents.Z), ExtentPoints[6]); //Left Bottom Front
	SceneView->WorldToPixel(Origin + FVector(-Extents.X, -Extents.Y, -Extents.Z), ExtentPoints[7]); //Left Bottom Back

	FVector2D TopLeft = FVector2D(std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
	FVector2D BottomRight = FVector2D(std::numeric_limits<float>::min(), std::numeric_limits<float>::min());

	for (auto Point : ExtentPoints)
	{
		if (Point.X < TopLeft.X)
			TopLeft.X = Point.X;
		else if (Point.X > BottomRight.X)
			BottomRight.X = Point.X;

		if (Point.Y < TopLeft.Y)
			TopLeft.Y = Point.Y;
		else if (Point.Y > BottomRight.Y)
			BottomRight.Y = Point.Y;
	}

	MyRegion->bounds.left = TopLeft.X;
	MyRegion->bounds.top = TopLeft.Y;
	MyRegion->bounds.right = BottomRight.X;
	MyRegion->bounds.bottom = BottomRight.Y;
}
void AShooterPlayerController::OnDeathMessage(class AShooterPlayerState* KillerPlayerState, class AShooterPlayerState* KilledPlayerState, const UDamageType* KillerDamageType) 
{
	AShooterHUD* ShooterHUD = GetShooterHUD();
	if (ShooterHUD)
	{
		ShooterHUD->ShowDeathMessage(KillerPlayerState, KilledPlayerState, KillerDamageType);		
	}

	ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
	if (LocalPlayer && LocalPlayer->GetUniqueNetId().IsValid() && KilledPlayerState->UniqueId.IsValid())
	{
		// if this controller is the player who died, update the hero stat.
		if (*LocalPlayer->GetUniqueNetId() == *KilledPlayerState->UniqueId)
		{
			const auto Events = Online::GetEventsInterface();
			const auto Identity = Online::GetIdentityInterface();

			if (Events.IsValid() && Identity.IsValid())
			{							
				int32 UserIndex = LocalPlayer->ControllerId;
				TSharedPtr<FUniqueNetId> UniqueID = Identity->GetUniquePlayerId(UserIndex);
				if (UniqueID.IsValid())
				{				
					ACharacter* Pawn = GetCharacter();
					check(Pawn);
					FVector Location = Pawn->GetActorLocation();

					FOnlineEventParms Params;
					Params.Add( TEXT( "SectionId" ), FVariantData( (int32)1 ) );
					Params.Add( TEXT( "GameplayModeId" ), FVariantData( (int32)1 ) );
					Params.Add( TEXT( "DifficultyLevelId" ), FVariantData( (int32)0 ) );

					Params.Add( TEXT( "PlayerRoleId" ), FVariantData( (int32)0 ) );
					Params.Add( TEXT( "PlayerWeaponId" ), FVariantData( (int32)0 ) );
					Params.Add( TEXT( "EnemyRoleId" ), FVariantData( (int32)0 ) );
					Params.Add( TEXT( "EnemyWeaponId" ), FVariantData( (int32)0 ) );	
				
					Params.Add( TEXT( "LocationX" ), FVariantData( Location.X ) );
					Params.Add( TEXT( "LocationY" ), FVariantData( Location.Y ) );
					Params.Add( TEXT( "LocationZ" ), FVariantData( Location.Z ) );
										
					Events->TriggerEvent(*UniqueID, TEXT("PlayerDeath"), Params);
				}
			}
		}
	}	
}
AEyeXActorBase* AEyeXPlayerController::FindFocusedActor(FHitResult& OutHit, const FVector2D& GazePoint)
{
	// Get the scene view to deproject the gazepoint to world space
	ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);

	if (!LocalPlayer)
		return nullptr;

	FSceneViewFamily ViewFamily(FSceneViewFamily::ConstructionValues(
		LocalPlayer->ViewportClient->Viewport,
		GetWorld()->Scene,
		LocalPlayer->ViewportClient->EngineShowFlags)
		.SetRealtimeUpdate(true));

	FVector ViewLocation;
	FRotator ViewRotation;
	FSceneView* View = LocalPlayer->CalcSceneView(&ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport);

	// Initiate sweep/trace variables
	const FCollisionObjectQueryParams ObjectParams(FEyeXUtils::ECCArrayToBitField(CollisionChannels));
	const FCollisionQueryParams TraceParams(FName(TEXT("GazeTrace")), true, GetPawn());
	FHitResult HitResult;
	AEyeXActorBase* EyeXActor = nullptr;

	switch (DetectionMode)
	{
	case EEyeXDetectionMode::LineTrace:
		EyeXActor = FindByLineTrace(HitResult, View, GazePoint, ObjectParams, TraceParams);
		break;
	case EEyeXDetectionMode::BoxedLineTrace:
		EyeXActor = FindByBoxedLineTrace(HitResult, View, GazePoint, ObjectParams, TraceParams);
		break;
	case EEyeXDetectionMode::Sweep:
		EyeXActor = FindBySweep(HitResult, View, GazePoint, ObjectParams, TraceParams);
		break;
	case EEyeXDetectionMode::FrustrumIntersection:
		EyeXActor = FindByFrustumIntersection(HitResult, View, GazePoint, ObjectParams, TraceParams);
		break;
	default:
		break;
	}

	OutHit = HitResult; 
	return EyeXActor; // use out param for actor as well, alternatively use hit actor in hit result (with cast). make the method const too.
}
Beispiel #15
0
void ULucyFunctions::SetMouseLockedToViewport(const bool Locked)
{
	if (GEngine == nullptr)
	{
		return;
	}

	UGameViewportClient* ViewportClient = GEngine->GameViewport;
	if (ViewportClient == nullptr)
	{
		return;
	}

	TSharedPtr<SViewport> ViewportWidget = ViewportClient->GetGameViewportWidget();
	if (!ViewportWidget.IsValid())
	{
		return;
	}

	TArray<APlayerController*> LocalPlayerControllers;
	GEngine->GetAllLocalPlayerControllers(LocalPlayerControllers);

	for (APlayerController* LocalPlayerController : LocalPlayerControllers)
	{
		if (LocalPlayerController == nullptr)
		{
			continue;
		}

		ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(LocalPlayerController->Player);
		if (LocalPlayer == nullptr)
		{
			continue;
		}

		if (Locked)
		{
			LocalPlayer->GetSlateOperations().LockMouseToWidget(ViewportWidget.ToSharedRef());
		}
		else
		{
			LocalPlayer->GetSlateOperations().ReleaseMouseLock();
		}
	}
}
void UAmethystGameInstance::HandleControllerConnectionChange(bool bIsConnection, int32 Unused, int32 GameUserIndex)
{
	if (!bIsConnection)
	{
		// Controller was disconnected

		// Find the local player associated with this user index
		ULocalPlayer * LocalPlayer = FindLocalPlayerFromControllerId(GameUserIndex);

		if (LocalPlayer == NULL)
		{
			return;		// We don't care about players we aren't tracking
		}

		// Invalidate this local player's controller id.
		LocalPlayer->SetControllerId(-1);
	}
}
bool UAmethystPersistentUser::IsAimSensitivityDirty() const
{
    bool bIsAimSensitivityDirty = false;
    
    // Fixme: UAmethystPersistentUser is not setup to work with multiple worlds.
    // For now, user settings are global to all world instances.
    if (GEngine)
    {
        TArray<APlayerController*> PlayerList;
        GEngine->GetAllLocalPlayerControllers(PlayerList);
        
        for (auto It = PlayerList.CreateIterator(); It; ++It)
        {
            APlayerController* PC = *It;
            if (!PC || !PC->Player || !PC->PlayerInput)
            {
                continue;
            }
            
            // Update key bindings for the current user only
            ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PC->Player);
            if(!LocalPlayer || LocalPlayer->GetControllerId() != UserIndex)
            {
                continue;
            }
            
            // check if the aim sensitivity is off anywhere
            for (int32 Idx = 0; Idx < PC->PlayerInput->AxisMappings.Num(); Idx++)
            {
                FInputAxisKeyMapping &AxisMapping = PC->PlayerInput->AxisMappings[Idx];
                if (AxisMapping.AxisName == "Lookup" || AxisMapping.AxisName == "LookupRate" || AxisMapping.AxisName == "Turn" || AxisMapping.AxisName == "TurnRate")
                {
                    if (FMath::Abs(AxisMapping.Scale) != GetAimSensitivity())
                    {
                        bIsAimSensitivityDirty = true;
                        break;
                    }
                }
            }
        }
    }
    
    return bIsAimSensitivityDirty;
}
void UAmethystPersistentUser::TellInputAboutKeybindings()
{
    TArray<APlayerController*> PlayerList;
    GEngine->GetAllLocalPlayerControllers(PlayerList);
    
    for (auto It = PlayerList.CreateIterator(); It; ++It)
    {
        APlayerController* PC = *It;
        if (!PC || !PC->Player || !PC->PlayerInput)
        {
            continue;
        }
        
        // Update key bindings for the current user only
        ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PC->Player);
        if(!LocalPlayer || LocalPlayer->GetControllerId() != UserIndex)
        {
            continue;
        }
        
        //set the aim sensitivity
        for (int32 Idx = 0; Idx < PC->PlayerInput->AxisMappings.Num(); Idx++)
        {
            FInputAxisKeyMapping &AxisMapping = PC->PlayerInput->AxisMappings[Idx];
            if (AxisMapping.AxisName == "Lookup" || AxisMapping.AxisName == "LookupRate" || AxisMapping.AxisName == "Turn" || AxisMapping.AxisName == "TurnRate")
            {
                AxisMapping.Scale = (AxisMapping.Scale < 0.0f) ? -GetAimSensitivity() : +GetAimSensitivity();
            }
        }
        PC->PlayerInput->ForceRebuildingKeyMaps();
        
        //invert it, and if does not equal our bool, invert it again
        if (PC->PlayerInput->GetInvertAxis("LookupRate") != GetInvertedYAxis())
        {
            PC->PlayerInput->InvertAxis("LookupRate");
        }
        
        if (PC->PlayerInput->GetInvertAxis("Lookup") != GetInvertedYAxis())
        {
            PC->PlayerInput->InvertAxis("Lookup");
        }
    }
}
void UAdvancedFriendsLibrary::SendSessionInviteToFriend(APlayerController *PlayerController, const FBPUniqueNetId &FriendUniqueNetId, TEnumAsByte<EBlueprintResultSwitch::Type> &Result)
{
	if (!PlayerController)
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had a bad Player Controller!"));
		Result = EBlueprintResultSwitch::Type::OnFailure;
		return;
	}

	if (!FriendUniqueNetId.IsValid())
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had a bad UniqueNetId!"));
		Result = EBlueprintResultSwitch::Type::OnFailure;
		return;
	}

	IOnlineSessionPtr SessionInterface = Online::GetSessionInterface();

	if (!SessionInterface.IsValid())
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Failed to get session interface!"));
		Result = EBlueprintResultSwitch::Type::OnFailure;
		return;
	}

	ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerController->Player);

	if (!Player)
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend failed to get LocalPlayer!"));
		Result = EBlueprintResultSwitch::Type::OnFailure;
		return;
	}

	if (SessionInterface->SendSessionInviteToFriend(Player->GetControllerId(), GameSessionName, *FriendUniqueNetId.GetUniqueNetId()))
	{
		Result = EBlueprintResultSwitch::Type::OnSuccess;
		return;
	}

	Result = EBlueprintResultSwitch::Type::OnFailure;
	return;
}
void FPlayerMuteList::ClientMutePlayer(APlayerController* OwningPC, const FUniqueNetIdRepl& MuteId)
{
	const TSharedPtr<const FUniqueNetId>& PlayerIdToMute = MuteId.GetUniqueNetId();

	// Add to the filter list on clients (used for peer to peer voice)
	AddIdToMuteList(VoicePacketFilter, PlayerIdToMute);

	// Use the local player to determine the controller id
	ULocalPlayer* LP = Cast<ULocalPlayer>(OwningPC->Player);
	if (LP != NULL)
	{
		UWorld* World = OwningPC->GetWorld();
		IOnlineVoicePtr VoiceInt = Online::GetVoiceInterface(World);
		if (VoiceInt.IsValid())
		{
			// Have the voice subsystem mute this player
			VoiceInt->MuteRemoteTalker(LP->GetControllerId(), *PlayerIdToMute, false);
		}
	}
}
void UAdvancedFriendsLibrary::GetFriend(APlayerController *PlayerController, const FBPUniqueNetId FriendUniqueNetId, FBPFriendInfo &Friend)
{

	if (!PlayerController)
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriend Had a bad Player Controller!"));
		return;
	}

	if (!FriendUniqueNetId.IsValid())
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriend Had a bad UniqueNetId!"));
		return;
	}

	IOnlineFriendsPtr FriendsInterface = Online::GetFriendsInterface();

	if (!FriendsInterface.IsValid())
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriend Failed to get friends interface!"));
		return;
	}

	ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerController->Player);

	if (!Player)
	{
		UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriend failed to get LocalPlayer!"));
		return;
	}

	TSharedPtr<FOnlineFriend> fr = FriendsInterface->GetFriend(Player->GetControllerId(), *FriendUniqueNetId.GetUniqueNetId(), EFriendsLists::ToString(EFriendsLists::Type::Default));
	if (fr.IsValid())
	{
		Friend.DisplayName = fr->GetDisplayName();
		Friend.OnlineState = ((EBPOnlinePresenceState::Type)((int32)fr->GetPresence().Status.State));
		Friend.RealName = fr->GetRealName();
		Friend.UniqueNetId.SetUniqueNetId(fr->GetUserId());
		Friend.bIsPlayingSameGame = fr->GetPresence().bIsPlayingThisGame;
	}
}
void AMouseController::GetCameraRay(FVector& WorldOrigin, FVector& WorldDirection)
{
	ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
	FVector2D MousePosition;
	if (LocalPlayer)
	{
		if (!LocalPlayer->ViewportClient->GetMousePosition(MousePosition))
		{
			return;
		}
	}

	// Early out if we clicked on a HUD hitbox
	if (GetHUD() != NULL && GetHUD()->GetHitBoxAtCoordinates(MousePosition, true))
	{
		return;
	}

	if (LocalPlayer != NULL && LocalPlayer->ViewportClient != NULL && LocalPlayer->ViewportClient->Viewport != NULL)
	{
		// Create a view family for the game viewport
		FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
			LocalPlayer->ViewportClient->Viewport,
			GetWorld()->Scene,
			LocalPlayer->ViewportClient->EngineShowFlags)
			.SetRealtimeUpdate(true));


		// Calculate a view where the player is to update the streaming from the players start location
		FVector ViewLocation;
		FRotator ViewRotation;
		FSceneView* SceneView = LocalPlayer->CalcSceneView(&ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport);

		if (SceneView)
		{

			SceneView->DeprojectFVector2D(MousePosition, WorldOrigin, WorldDirection);
		}
	}
}
Beispiel #23
0
void ALPlayerState::InformAboutKill_Implementation(class ALPlayerState* KillerPlayerState, const UDamageType* KillerDamageType, class ALPlayerState* KilledPlayerState)
{
	// id can be null for bots
	if (KillerPlayerState->UniqueId.IsValid())
	{
		// Search for actual killer before calling OnKill()
		for (FConstPlayerControllerIterator It = GetWorld()->GetPlayerControllerIterator(); It; It++)
		{
			ALPlayerController* TestPC = Cast<ALPlayerController>(*It);
			if (TestPC && TestPC->IsLocalController())
			{
				// a local player may not have an ID if it was create with CreateDebugPlayer
				ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(TestPC->Player);
				TSharedPtr<FUniqueNetId> LocalID = LocalPlayer->GetCachedUniqueNetId();
				if (LocalID.IsValid() && *LocalPlayer->GetCachedUniqueNetId() == *KillerPlayerState->UniqueId)
				{
					//TestPC->OnKill();
				}
			}
		}
	}
}
Beispiel #24
0
ULocalPlayer* UGameInstance::CreateLocalPlayer(int32 ControllerId, FString& OutError, bool bSpawnActor)
{
	checkf(GetEngine()->LocalPlayerClass != NULL);

	ULocalPlayer* NewPlayer = NULL;
	int32 InsertIndex = INDEX_NONE;

	const int32 MaxSplitscreenPlayers = (GetGameViewportClient() != NULL) ? GetGameViewportClient()->MaxSplitscreenPlayers : 1;

	if (FindLocalPlayerFromControllerId( ControllerId ) != NULL)
	{
		OutError = FString::Printf(TEXT("A local player already exists for controller ID %d,"), ControllerId);
	}
	else if (LocalPlayers.Num() < MaxSplitscreenPlayers)
	{
		// If the controller ID is not specified then find the first available
		if (ControllerId < 0)
		{
			for (ControllerId = 0; ControllerId < MaxSplitscreenPlayers; ++ControllerId)
			{
				if (FindLocalPlayerFromControllerId( ControllerId ) == NULL)
				{
					break;
				}
			}
			check(ControllerId < MaxSplitscreenPlayers);
		}
		else if (ControllerId >= MaxSplitscreenPlayers)
		{
			UE_LOG(LogPlayerManagement, Warning, TEXT("Controller ID (%d) is unlikely to map to any physical device, so this player will not receive input"), ControllerId);
		}

		NewPlayer = NewObject<ULocalPlayer>(GetEngine(), GetEngine()->LocalPlayerClass);
		InsertIndex = AddLocalPlayer(NewPlayer, ControllerId);
		if (bSpawnActor && InsertIndex != INDEX_NONE && GetWorld() != NULL)
		{
			if (GetWorld()->GetNetMode() != NM_Client)
			{
				// server; spawn a new PlayerController immediately
				if (!NewPlayer->SpawnPlayActor("", OutError, GetWorld()))
				{
					RemoveLocalPlayer(NewPlayer);
					NewPlayer = NULL;
				}
			}
			else
			{
				// client; ask the server to let the new player join
				NewPlayer->SendSplitJoin();
			}
		}
	}
	else
	{
		OutError = FString::Printf(TEXT( "Maximum number of players (%d) already created.  Unable to create more."), MaxSplitscreenPlayers);
	}

	if (OutError != TEXT(""))
	{
		UE_LOG(LogPlayerManagement, Log, TEXT("UPlayer* creation failed with error: %s"), *OutError);
	}

	return NewPlayer;
}
Beispiel #25
0
void UGameEngine::Tick( float DeltaSeconds, bool bIdleMode )
{
	SCOPE_CYCLE_COUNTER(STAT_GameEngineTick);
	NETWORK_PROFILER(GNetworkProfiler.TrackFrameBegin());

	int32 LocalTickCycles=0;
	CLOCK_CYCLES(LocalTickCycles);
	
	// -----------------------------------------------------
	// Non-World related stuff
	// -----------------------------------------------------

	if( DeltaSeconds < 0.0f )
	{
#if (UE_BUILD_SHIPPING && WITH_EDITOR)
		// End users don't have access to the secure parts of UDN.  Regardless, they won't
		// need the warning because the game ships with AMD drivers that address the issue.
		UE_LOG(LogEngine, Fatal,TEXT("Negative delta time!"));
#else
		// Send developers to the support list thread.
		UE_LOG(LogEngine, Fatal,TEXT("Negative delta time! Please see https://udn.epicgames.com/lists/showpost.php?list=ue3bugs&id=4364"));
#endif
	}

	// Tick the module manager
	IHotReloadInterface* HotReload = IHotReloadInterface::GetPtr();
	if(HotReload != nullptr)
	{
		HotReload->Tick();
	}

	if (!IsRunningDedicatedServer() && !IsRunningCommandlet())
	{
		// Clean up the game viewports that have been closed.
		CleanupGameViewport();
	}

	// If all viewports closed, time to exit.
	if(GIsClient && GameViewport == NULL )
	{
		UE_LOG(LogEngine, Log,  TEXT("All Windows Closed") );
		FPlatformMisc::RequestExit( 0 );
		return;
	}

	if ( GameViewport != NULL )
	{
		// Decide whether to drop high detail because of frame rate.
		QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_SetDropDetail);
		GameViewport->SetDropDetail(DeltaSeconds);
	}

	// Update subsystems.
	{
		// This assumes that UObject::StaticTick only calls ProcessAsyncLoading.
		StaticTick(DeltaSeconds, !!GAsyncLoadingUseFullTimeLimit, GAsyncLoadingTimeLimit / 1000.f);
	}

	// -----------------------------------------------------
	// Begin ticking worlds
	// -----------------------------------------------------

	FName OriginalGWorldContext = NAME_None;
	for (int32 i=0; i < WorldList.Num(); ++i)
	{
		if (WorldList[i].World() == GWorld)
		{
			OriginalGWorldContext = WorldList[i].ContextHandle;
			break;
		}
	}

	for (int32 WorldIdx = 0; WorldIdx < WorldList.Num(); ++WorldIdx)
	{
		FWorldContext &Context = WorldList[WorldIdx];
		if (Context.World() == NULL)
		{
			continue;
		}

		GWorld = Context.World();

		// Tick all travel and Pending NetGames (Seamless, server, client)
		{
			QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_TickWorldTravel);
			TickWorldTravel(Context, DeltaSeconds);
		}

		if (!IsRunningDedicatedServer() && !IsRunningCommandlet())
		{
			QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_CheckCaptures);
			// Only update reflection captures in game once all 'always loaded' levels have been loaded
			// This won't work with actual level streaming though
			if (Context.World()->AreAlwaysLoadedLevelsLoaded())
			{
				// Update sky light first because it's considered direct lighting, sky diffuse will be visible in reflection capture indirect specular
				USkyLightComponent::UpdateSkyCaptureContents(Context.World());
				UReflectionCaptureComponent::UpdateReflectionCaptureContents(Context.World());
			}
		}

		if (!bIdleMode)
		{
			// Tick the world.
			GameCycles=0;
			CLOCK_CYCLES(GameCycles);
			Context.World()->Tick( LEVELTICK_All, DeltaSeconds );
			UNCLOCK_CYCLES(GameCycles);
		}

		// Issue cause event after first tick to provide a chance for the game to spawn the player and such.
		if( Context.World()->bWorldWasLoadedThisTick )
		{
			Context.World()->bWorldWasLoadedThisTick = false;
			
			const TCHAR* InitialExec = Context.LastURL.GetOption(TEXT("causeevent="),NULL);
			ULocalPlayer* GamePlayer = Context.OwningGameInstance ? Context.OwningGameInstance->GetFirstGamePlayer() : NULL;
			if( InitialExec && GamePlayer )
			{
				UE_LOG(LogEngine, Log, TEXT("Issuing initial cause event passed from URL: %s"), InitialExec);
				GamePlayer->Exec( GamePlayer->GetWorld(), *(FString("CAUSEEVENT ") + InitialExec), *GLog );
			}

			Context.World()->bTriggerPostLoadMap = true;
		}

		// Tick the viewports.
		if ( GameViewport != NULL && !bIdleMode )
		{
			SCOPE_CYCLE_COUNTER(STAT_GameViewportTick);
			GameViewport->Tick(DeltaSeconds);
		}
	
		UpdateTransitionType(Context.World());
	
		// fixme: this will only happen once due to the static bool, but still need to figure out how to handle this for multiple worlds
		if (FPlatformProperties::SupportsWindowedMode())
		{
			// Hide the splashscreen and show the game window
			static bool bFirstTime = true;
			if ( bFirstTime )
			{
				bFirstTime = false;
				FPlatformSplash::Hide();
				if ( GameViewportWindow.IsValid() )
				{
					GameViewportWindow.Pin()->ShowWindow();
					FSlateApplication::Get().RegisterGameViewport( GameViewportWidget.ToSharedRef() );
				}
			}
		}

		if (!bIdleMode && !IsRunningDedicatedServer() && !IsRunningCommandlet())
		{
			// Render everything.
			RedrawViewports();
		}

		// Block on async loading if requested.
		if (Context.World()->bRequestedBlockOnAsyncLoading)
		{
			BlockTillLevelStreamingCompleted(Context.World());
			Context.World()->bRequestedBlockOnAsyncLoading = false;
		}

		// streamingServer
		if( GIsServer == true )
		{
			SCOPE_CYCLE_COUNTER(STAT_UpdateLevelStreaming);
			Context.World()->UpdateLevelStreaming();
		}

		// Update Audio. This needs to occur after rendering as the rendering code updates the listener position.
		if (FAudioDevice* AudioDevice = Context.World()->GetAudioDevice())
		{
			AudioDevice->Update(!Context.World()->IsPaused());
		}

		if( GIsClient )
		{
			// IStreamingManager is updated outside of a world context. For now, assuming it needs to tick here, before possibly calling PostLoadMap. 
			// Will need to take another look when trying to support multiple worlds.

			// Update resource streaming after viewports have had a chance to update view information. Normal update.
			{
				QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_IStreamingManager);
				IStreamingManager::Get().Tick( DeltaSeconds );
			}

			if ( Context.World()->bTriggerPostLoadMap )
			{
				Context.World()->bTriggerPostLoadMap = false;

				// Turns off the loading movie (if it was turned on by LoadMap) and other post-load cleanup.
				QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_IStreamingManager);
				PostLoadMap();
			}
		}

		UNCLOCK_CYCLES(LocalTickCycles);
		TickCycles=LocalTickCycles;

		// See whether any map changes are pending and we requested them to be committed.
		QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_ConditionalCommitMapChange);
		ConditionalCommitMapChange(Context);
	}

	// ----------------------------
	//	End per-world ticking
	// ----------------------------

	// Restore original GWorld*. This will go away one day.
	if (OriginalGWorldContext != NAME_None)
	{
		QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_GetWorldContextFromHandleChecked);
		GWorld = GetWorldContextFromHandleChecked(OriginalGWorldContext).World();
	}

	// rendering thread commands
	{
		ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER(
			TickRenderingTimer,
			bool, bPauseRenderingRealtimeClock, GPauseRenderingRealtimeClock,
			float, DeltaTime, DeltaSeconds,
		{
			if(!bPauseRenderingRealtimeClock)
			{
				// Tick the GRenderingRealtimeClock, unless it's paused
				GRenderingRealtimeClock.Tick(DeltaTime);
			}

			GetRendererModule().TickRenderTargetPool();
		});
	}
void UAmethystGameInstance::HandleControllerPairingChanged(int GameUserIndex, const FUniqueNetId& PreviousUser, const FUniqueNetId& NewUser)
{
	if (CurrentState == AmethystGameInstanceState::WelcomeScreen)
	{
		// Don't care about pairing changes at welcome screen
		return;
	}

#if Amethyst_CONSOLE_UI && PLATFORM_XBOXONE
	if (IgnorePairingChangeForControllerId != -1 && GameUserIndex == IgnorePairingChangeForControllerId)
	{
		// We were told to ignores
		IgnorePairingChangeForControllerId = -1;	// Reset now so there there is no chance this remains in a bad state
		return;
	}

	if (PreviousUser.IsValid() && !NewUser.IsValid())
	{
		// Treat this as a disconnect or signout, which is handled somewhere else
		return;
	}

	if (!PreviousUser.IsValid() && NewUser.IsValid())
	{
		// Treat this as a signin
		ULocalPlayer * ControlledLocalPlayer = FindLocalPlayerFromControllerId(GameUserIndex);

		if (ControlledLocalPlayer != NULL && !ControlledLocalPlayer->GetCachedUniqueNetId().IsValid())
		{
			// If a player that previously selected "continue without saving" signs into this controller, move them back to welcome screen
			HandleSignInChangeMessaging();
		}

		return;
	}

	// Find the local player currently being controlled by this controller
	ULocalPlayer * ControlledLocalPlayer = FindLocalPlayerFromControllerId(GameUserIndex);

	// See if the newly assigned profile is in our local player list
	ULocalPlayer * NewLocalPlayer = FindLocalPlayerFromUniqueNetId(NewUser);

	// If the local player being controlled is not the target of the pairing change, then give them a chance 
	// to continue controlling the old player with this controller
	if (ControlledLocalPlayer != nullptr && ControlledLocalPlayer != NewLocalPlayer)
	{
		UAmethystGameViewportClient * AmethystViewport = Cast<UAmethystGameViewportClient>(GetGameViewportClient());

		if (AmethystViewport != nullptr)
		{
			AmethystViewport->ShowDialog(
				nullptr,
				EAmethystDialogType::Generic,
				NSLOCTEXT("ProfileMessages", "PairingChanged", "Your controller has been paired to another profile, would you like to switch to this new profile now? Selecting YES will sign out of the previous profile."),
				NSLOCTEXT("DialogButtons", "YES", "A - YES"),
				NSLOCTEXT("DialogButtons", "NO", "B - NO"),
				FOnClicked::CreateUObject(this, &UAmethystGameInstance::OnPairingUseNewProfile),
				FOnClicked::CreateUObject(this, &UAmethystGameInstance::OnPairingUsePreviousProfile)
				);
		}
	}
#endif
}
void UOffAxisGameViewportClient::Draw(FViewport* InViewport, FCanvas* SceneCanvas)
{
	//Valid SceneCanvas is required.  Make this explicit.
	check(SceneCanvas);

	FCanvas* DebugCanvas = InViewport->GetDebugCanvas();

	// Create a temporary canvas if there isn't already one.
	static FName CanvasObjectName(TEXT("CanvasObject"));
	UCanvas* CanvasObject = GetCanvasByName(CanvasObjectName);
	CanvasObject->Canvas = SceneCanvas;

	// Create temp debug canvas object
	static FName DebugCanvasObjectName(TEXT("DebugCanvasObject"));
	UCanvas* DebugCanvasObject = GetCanvasByName(DebugCanvasObjectName);
	DebugCanvasObject->Canvas = DebugCanvas;
	DebugCanvasObject->Init(InViewport->GetSizeXY().X, InViewport->GetSizeXY().Y, NULL);

	const bool bScaledToRenderTarget = GEngine->HMDDevice.IsValid() && GEngine->IsStereoscopic3D(InViewport);
	if (bScaledToRenderTarget)
	{
		// Allow HMD to modify screen settings
		GEngine->HMDDevice->UpdateScreenSettings(Viewport);
	}
	if (DebugCanvas)
	{
		DebugCanvas->SetScaledToRenderTarget(bScaledToRenderTarget);
	}
	if (SceneCanvas)
	{
		SceneCanvas->SetScaledToRenderTarget(bScaledToRenderTarget);
	}

	bool bUIDisableWorldRendering = false;
	FViewElementDrawer GameViewDrawer;

	// create the view family for rendering the world scene to the viewport's render target
	FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
		InViewport,
		GetWorld()->Scene,
		EngineShowFlags)
		.SetRealtimeUpdate(true));

	// Allow HMD to modify the view later, just before rendering
	if (GEngine->HMDDevice.IsValid() && GEngine->IsStereoscopic3D(InViewport))
	{
		ISceneViewExtension* HmdViewExt = GEngine->HMDDevice->GetViewExtension();
		if (HmdViewExt)
		{
			ViewFamily.ViewExtensions.Add(HmdViewExt);
			HmdViewExt->ModifyShowFlags(ViewFamily.EngineShowFlags);
		}
	}


	ESplitScreenType::Type SplitScreenConfig = GetCurrentSplitscreenConfiguration();
	EngineShowFlagOverride(ESFIM_Game, (EViewModeIndex)ViewModeIndex, ViewFamily.EngineShowFlags, NAME_None, SplitScreenConfig != ESplitScreenType::None);

	TMap<ULocalPlayer*, FSceneView*> PlayerViewMap;

	FAudioDevice* AudioDevice = GEngine->GetAudioDevice();
	bool bReverbSettingsFound = false;
	FReverbSettings ReverbSettings;
	class AAudioVolume* AudioVolume = nullptr;

	for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
	{
		APlayerController* PlayerController = *Iterator;
		if (PlayerController)
		{
			ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PlayerController->Player);
			if (LocalPlayer)
			{
				const bool bEnableStereo = GEngine->IsStereoscopic3D(InViewport);
				int32 NumViews = bEnableStereo ? 2 : 1;

				for (int i = 0; i < NumViews; ++i)
				{
					// Calculate the player's view information.
					FVector		ViewLocation;
					FRotator	ViewRotation;

					EStereoscopicPass PassType = !bEnableStereo ? eSSP_FULL : ((i == 0) ? eSSP_LEFT_EYE : eSSP_RIGHT_EYE);

					FSceneView* View = LocalPlayer->CalcSceneView(&ViewFamily, ViewLocation, ViewRotation, InViewport, &GameViewDrawer, PassType);

					if (mOffAxisMatrixSetted)
						UpdateProjectionMatrix(View, mOffAxisMatrix);

					if (View)
					{
						if (View->Family->EngineShowFlags.Wireframe)
						{
							// Wireframe color is emissive-only, and mesh-modifying materials do not use material substitution, hence...
							View->DiffuseOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f);
							View->SpecularOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f);
						}
						else if (View->Family->EngineShowFlags.OverrideDiffuseAndSpecular)
						{
							View->DiffuseOverrideParameter = FVector4(GEngine->LightingOnlyBrightness.R, GEngine->LightingOnlyBrightness.G, GEngine->LightingOnlyBrightness.B, 0.0f);
							View->SpecularOverrideParameter = FVector4(.1f, .1f, .1f, 0.0f);
						}
						else if (View->Family->EngineShowFlags.ReflectionOverride)
						{
							View->DiffuseOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f);
							View->SpecularOverrideParameter = FVector4(1, 1, 1, 0.0f);
							View->NormalOverrideParameter = FVector4(0, 0, 1, 0.0f);
							View->RoughnessOverrideParameter = FVector2D(0.0f, 0.0f);
						}


						if (!View->Family->EngineShowFlags.Diffuse)
						{
							View->DiffuseOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f);
						}

						if (!View->Family->EngineShowFlags.Specular)
						{
							View->SpecularOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f);
						}

						View->CameraConstrainedViewRect = View->UnscaledViewRect;

						// If this is the primary drawing pass, update things that depend on the view location
						if (i == 0)
						{
							// Save the location of the view.
							LocalPlayer->LastViewLocation = ViewLocation;

							PlayerViewMap.Add(LocalPlayer, View);

							// Update the listener.
							if (AudioDevice != NULL)
							{
								FVector Location;
								FVector ProjFront;
								FVector ProjRight;
								PlayerController->GetAudioListenerPosition(/*out*/ Location, /*out*/ ProjFront, /*out*/ ProjRight);

								FTransform ListenerTransform(FRotationMatrix::MakeFromXY(ProjFront, ProjRight));
								ListenerTransform.SetTranslation(Location);
								ListenerTransform.NormalizeRotation();

								bReverbSettingsFound = true;

								FReverbSettings PlayerReverbSettings;
								FInteriorSettings PlayerInteriorSettings;
								class AAudioVolume* PlayerAudioVolume = GetWorld()->GetAudioSettings(Location, &PlayerReverbSettings, &PlayerInteriorSettings);

								if (AudioVolume == nullptr || (PlayerAudioVolume != nullptr && PlayerAudioVolume->Priority > AudioVolume->Priority))
								{
									AudioVolume = PlayerAudioVolume;
									ReverbSettings = PlayerReverbSettings;
								}

								uint32 ViewportIndex = PlayerViewMap.Num() - 1;
								AudioDevice->SetListener(ViewportIndex, ListenerTransform, (View->bCameraCut ? 0.f : GetWorld()->GetDeltaSeconds()), PlayerAudioVolume, PlayerInteriorSettings);
							}

						}

						// Add view information for resource streaming.
						IStreamingManager::Get().AddViewInformation(View->ViewMatrices.ViewOrigin, View->ViewRect.Width(), View->ViewRect.Width() * View->ViewMatrices.ProjMatrix.M[0][0]);
						GetWorld()->ViewLocationsRenderedLastFrame.Add(View->ViewMatrices.ViewOrigin);
					}
				}
			}
		}
	}

	if (bReverbSettingsFound)
	{
		AudioDevice->SetReverbSettings(AudioVolume, ReverbSettings);
	}

	// Update level streaming.
	GetWorld()->UpdateLevelStreaming();

	// Draw the player views.
	if (!bDisableWorldRendering && !bUIDisableWorldRendering && PlayerViewMap.Num() > 0)
	{
		GetRendererModule().BeginRenderingViewFamily(SceneCanvas, &ViewFamily);
	}

	// Clear areas of the rendertarget (backbuffer) that aren't drawn over by the views.
	{
		// Find largest rectangle bounded by all rendered views.
		uint32 MinX = InViewport->GetSizeXY().X, MinY = InViewport->GetSizeXY().Y, MaxX = 0, MaxY = 0;
		uint32 TotalArea = 0;
		for (int32 ViewIndex = 0; ViewIndex < ViewFamily.Views.Num(); ++ViewIndex)
		{
			const FSceneView* View = ViewFamily.Views[ViewIndex];

			FIntRect UpscaledViewRect = View->UnscaledViewRect;

			MinX = FMath::Min<uint32>(UpscaledViewRect.Min.X, MinX);
			MinY = FMath::Min<uint32>(UpscaledViewRect.Min.Y, MinY);
			MaxX = FMath::Max<uint32>(UpscaledViewRect.Max.X, MaxX);
			MaxY = FMath::Max<uint32>(UpscaledViewRect.Max.Y, MaxY);
			TotalArea += FMath::TruncToInt(UpscaledViewRect.Width()) * FMath::TruncToInt(UpscaledViewRect.Height());
		}

		// To draw black borders around the rendered image (prevents artifacts from post processing passes that read outside of the image e.g. PostProcessAA)
		{
			int32 BlackBorders = 0; // FMath::Clamp(CVarSetBlackBordersEnabled.GetValueOnGameThread(), 0, 10);

			if (ViewFamily.Views.Num() == 1 && BlackBorders)
			{
				MinX += BlackBorders;
				MinY += BlackBorders;
				MaxX -= BlackBorders;
				MaxY -= BlackBorders;
				TotalArea = (MaxX - MinX) * (MaxY - MinY);
			}
		}

		// If the views don't cover the entire bounding rectangle, clear the entire buffer.
		if (ViewFamily.Views.Num() == 0 || TotalArea != (MaxX - MinX)*(MaxY - MinY) || bDisableWorldRendering)
		{
			SceneCanvas->DrawTile(0, 0, InViewport->GetSizeXY().X, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false);
		}
		else
		{
			// clear left
			if (MinX > 0)
			{
				SceneCanvas->DrawTile(0, 0, MinX, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false);
			}
			// clear right
			if (MaxX < (uint32)InViewport->GetSizeXY().X)
			{
				SceneCanvas->DrawTile(MaxX, 0, InViewport->GetSizeXY().X, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false);
			}
			// clear top
			if (MinY > 0)
			{
				SceneCanvas->DrawTile(MinX, 0, MaxX, MinY, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false);
			}
			// clear bottom
			if (MaxY < (uint32)InViewport->GetSizeXY().Y)
			{
				SceneCanvas->DrawTile(MinX, MaxY, MaxX, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false);
			}
		}
	}

	// Remove temporary debug lines.
	if (GetWorld()->LineBatcher != NULL)
	{
		GetWorld()->LineBatcher->Flush();
	}

	if (GetWorld()->ForegroundLineBatcher != NULL)
	{
		GetWorld()->ForegroundLineBatcher->Flush();
	}

	// Draw FX debug information.
	if (GetWorld()->FXSystem)
	{
		GetWorld()->FXSystem->DrawDebug(SceneCanvas);
	}

	// Render the UI.
	{
		//SCOPE_CYCLE_COUNTER(STAT_UIDrawingTime);

		// render HUD
		bool bDisplayedSubtitles = false;
		for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
		{
			APlayerController* PlayerController = *Iterator;
			if (PlayerController)
			{
				ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PlayerController->Player);
				if (LocalPlayer)
				{
					FSceneView* View = PlayerViewMap.FindRef(LocalPlayer);
					if (View != NULL)
					{
						// rendering to directly to viewport target
						FVector CanvasOrigin(FMath::TruncToFloat(View->UnscaledViewRect.Min.X), FMath::TruncToInt(View->UnscaledViewRect.Min.Y), 0.f);

						CanvasObject->Init(View->UnscaledViewRect.Width(), View->UnscaledViewRect.Height(), View);

						// Set the canvas transform for the player's view rectangle.
						SceneCanvas->PushAbsoluteTransform(FTranslationMatrix(CanvasOrigin));
						CanvasObject->ApplySafeZoneTransform();

						// Render the player's HUD.
						if (PlayerController->MyHUD)
						{
							//SCOPE_CYCLE_COUNTER(STAT_HudTime);

							DebugCanvasObject->SceneView = View;
							PlayerController->MyHUD->SetCanvas(CanvasObject, DebugCanvasObject);
							if (GEngine->IsStereoscopic3D(InViewport))
							{
								check(GEngine->StereoRenderingDevice.IsValid());
								GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_LEFT_EYE, SceneCanvas, CanvasObject, Viewport);
								PlayerController->MyHUD->PostRender();
								SceneCanvas->PopTransform();

								GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_RIGHT_EYE, SceneCanvas, CanvasObject, Viewport);
								PlayerController->MyHUD->PostRender();
								SceneCanvas->PopTransform();

								// Reset the canvas for rendering to the full viewport.
								CanvasObject->Reset();
								CanvasObject->SizeX = View->UnscaledViewRect.Width();
								CanvasObject->SizeY = View->UnscaledViewRect.Height();
								CanvasObject->SetView(NULL);
								CanvasObject->Update();
							}
							else
							{
								PlayerController->MyHUD->PostRender();
							}

							// Put these pointers back as if a blueprint breakpoint hits during HUD PostRender they can
							// have been changed
							CanvasObject->Canvas = SceneCanvas;
							DebugCanvasObject->Canvas = DebugCanvas;

							// A side effect of PostRender is that the playercontroller could be destroyed
							if (!PlayerController->IsPendingKill())
							{
								PlayerController->MyHUD->SetCanvas(NULL, NULL);
							}
						}

						if (DebugCanvas != NULL)
						{
							DebugCanvas->PushAbsoluteTransform(FTranslationMatrix(CanvasOrigin));
							UDebugDrawService::Draw(ViewFamily.EngineShowFlags, InViewport, View, DebugCanvas);
							DebugCanvas->PopTransform();
						}

						CanvasObject->PopSafeZoneTransform();
						SceneCanvas->PopTransform();

						// draw subtitles
						if (!bDisplayedSubtitles)
						{
							FVector2D MinPos(0.f, 0.f);
							FVector2D MaxPos(1.f, 1.f);
							GetSubtitleRegion(MinPos, MaxPos);

							uint32 SizeX = SceneCanvas->GetRenderTarget()->GetSizeXY().X;
							uint32 SizeY = SceneCanvas->GetRenderTarget()->GetSizeXY().Y;
							FIntRect SubtitleRegion(FMath::TruncToInt(SizeX * MinPos.X), FMath::TruncToInt(SizeY * MinPos.Y), FMath::TruncToInt(SizeX * MaxPos.X), FMath::TruncToInt(SizeY * MaxPos.Y));
							// We need a world to do this
							FSubtitleManager::GetSubtitleManager()->DisplaySubtitles(SceneCanvas, SubtitleRegion, GetWorld()->GetAudioTimeSeconds());
						}
					}
				}
			}
		}

		//ensure canvas has been flushed before rendering UI
		SceneCanvas->Flush_GameThread();
		if (DebugCanvas != NULL)
		{
			DebugCanvas->Flush_GameThread();
		}
		// Allow the viewport to render additional stuff
		PostRender(DebugCanvasObject);

		// Render the console.
		if (ViewportConsole)
		{
			if (GEngine->IsStereoscopic3D(InViewport))
			{
				GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_LEFT_EYE, DebugCanvas, DebugCanvasObject, Viewport);
				ViewportConsole->PostRender_Console(DebugCanvasObject);
#if !UE_BUILD_SHIPPING
				if (DebugCanvas != NULL && GEngine->HMDDevice.IsValid())
				{
					GEngine->HMDDevice->DrawDebug(DebugCanvasObject, eSSP_LEFT_EYE);
				}
#endif
				DebugCanvas->PopTransform();

				GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_RIGHT_EYE, DebugCanvas, DebugCanvasObject, Viewport);
				ViewportConsole->PostRender_Console(DebugCanvasObject);
#if !UE_BUILD_SHIPPING
				if (DebugCanvas != NULL && GEngine->HMDDevice.IsValid())
				{
					GEngine->HMDDevice->DrawDebug(DebugCanvasObject, eSSP_RIGHT_EYE);
				}
#endif
				DebugCanvas->PopTransform();

				// Reset the canvas for rendering to the full viewport.
				DebugCanvasObject->Reset();
				DebugCanvasObject->SizeX = Viewport->GetSizeXY().X;
				DebugCanvasObject->SizeY = Viewport->GetSizeXY().Y;
				DebugCanvasObject->SetView(NULL);
				DebugCanvasObject->Update();
			}
			else
			{
				ViewportConsole->PostRender_Console(DebugCanvasObject);
			}
		}
	}


	// Grab the player camera location and orientation so we can pass that along to the stats drawing code.
	FVector PlayerCameraLocation = FVector::ZeroVector;
	FRotator PlayerCameraRotation = FRotator::ZeroRotator;
	{
		for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
		{
			(*Iterator)->GetPlayerViewPoint(PlayerCameraLocation, PlayerCameraRotation);
		}
	}

	if (GEngine->IsStereoscopic3D(InViewport))
	{
		GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_LEFT_EYE, DebugCanvas, DebugCanvasObject, InViewport);
		DrawStatsHUD(GetWorld(), InViewport, DebugCanvas, DebugCanvasObject, DebugProperties, PlayerCameraLocation, PlayerCameraRotation);
		DebugCanvas->PopTransform();

		GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_RIGHT_EYE, DebugCanvas, DebugCanvasObject, InViewport);
		DrawStatsHUD(GetWorld(), InViewport, DebugCanvas, DebugCanvasObject, DebugProperties, PlayerCameraLocation, PlayerCameraRotation);
		DebugCanvas->PopTransform();

		// Reset the canvas for rendering to the full viewport.
		DebugCanvasObject->Reset();
		DebugCanvasObject->SizeX = Viewport->GetSizeXY().X;
		DebugCanvasObject->SizeY = Viewport->GetSizeXY().Y;
		DebugCanvasObject->SetView(NULL);
		DebugCanvasObject->Update();

#if !UE_BUILD_SHIPPING
		if (GEngine->HMDDevice.IsValid())
		{
			GEngine->HMDDevice->DrawDebug(DebugCanvasObject, eSSP_FULL);
		}
#endif
	}
	else
	{
		DrawStatsHUD(GetWorld(), InViewport, DebugCanvas, DebugCanvasObject, DebugProperties, PlayerCameraLocation, PlayerCameraRotation);
	}
}
void UPendingNetGame::NotifyControlMessage(UNetConnection* Connection, uint8 MessageType, class FInBunch& Bunch)
{
	check(Connection==NetDriver->ServerConnection);

#if !UE_BUILD_SHIPPING
	UE_LOG(LogNet, Verbose, TEXT("PendingLevel received: %s"), FNetControlMessageInfo::GetName(MessageType));
#endif

	// This client got a response from the server.
	switch (MessageType)
	{
		case NMT_Upgrade:
			// Report mismatch.
			uint32 RemoteNetworkVersion;
			FNetControlMessage<NMT_Upgrade>::Receive(Bunch, RemoteNetworkVersion);
			// Upgrade
			ConnectionError = NSLOCTEXT("Engine", "ClientOutdated", "The match you are trying to join is running an incompatible version of the game.  Please try upgrading your game version.").ToString();
			GEngine->BroadcastNetworkFailure(NULL, NetDriver, ENetworkFailure::OutdatedClient, ConnectionError);
			break;

		case NMT_Failure:
		{
			// our connection attempt failed for some reason, for example a synchronization mismatch (bad GUID, etc) or because the server rejected our join attempt (too many players, etc)
			// here we can further parse the string to determine the reason that the server closed our connection and present it to the user

			FString ErrorMsg;
			FNetControlMessage<NMT_Failure>::Receive(Bunch, ErrorMsg);
			if (ErrorMsg.IsEmpty())
			{
				ErrorMsg = NSLOCTEXT("NetworkErrors", "GenericPendingConnectionFailed", "Pending Connection Failed.").ToString();
			}
			
			// This error will be resolved in TickWorldTravel()
			ConnectionError = ErrorMsg;

			// Force close the session
			UE_LOG(LogNet, Log, TEXT("NetConnection::Close() [%s] [%s] [%s] from NMT_Failure %s"), 
				Connection->Driver ? *Connection->Driver->NetDriverName.ToString() : TEXT("NULL"),
				Connection->PlayerController ? *Connection->PlayerController->GetName() : TEXT("NoPC"),
				Connection->OwningActor ? *Connection->OwningActor->GetName() : TEXT("No Owner"),
				*ConnectionError);

			Connection->Close();
			break;
		}
		case NMT_Challenge:
		{
			// Challenged by server.
			FNetControlMessage<NMT_Challenge>::Receive(Bunch, Connection->Challenge);

			FURL PartialURL(URL);
			PartialURL.Host = TEXT("");
			PartialURL.Port = PartialURL.UrlConfig.DefaultPort; // HACK: Need to fix URL parsing 
			for (int32 i = URL.Op.Num() - 1; i >= 0; i--)
			{
				if (URL.Op[i].Left(5) == TEXT("game="))
				{
					URL.Op.RemoveAt(i);
				}
			}

			FUniqueNetIdRepl UniqueIdRepl;

			ULocalPlayer* LocalPlayer = GEngine->GetFirstGamePlayer(this);
			if (LocalPlayer)
			{
				// Send the player nickname if available
				FString OverrideName = LocalPlayer->GetNickname();
				if (OverrideName.Len() > 0)
				{
					PartialURL.AddOption(*FString::Printf(TEXT("Name=%s"), *OverrideName));
				}

				// Send any game-specific url options for this player
				FString GameUrlOptions = LocalPlayer->GetGameLoginOptions();
				if (GameUrlOptions.Len() > 0)
				{
					PartialURL.AddOption(*FString::Printf(TEXT("%s"), *GameUrlOptions));
				}

				// Send the player unique Id at login
				UniqueIdRepl = LocalPlayer->GetPreferredUniqueNetId();
			}
			
			Connection->ClientResponse = TEXT("0");
			FString URLString(PartialURL.ToString());
			FNetControlMessage<NMT_Login>::Send(Connection, Connection->ClientResponse, URLString, UniqueIdRepl);
			NetDriver->ServerConnection->FlushNet();
			break;
		}
		case NMT_Welcome:
		{
			// Server accepted connection.
			FString GameName;
			FString RedirectURL;

			FNetControlMessage<NMT_Welcome>::Receive(Bunch, URL.Map, GameName, RedirectURL);

			//GEngine->NetworkRemapPath(this, URL.Map);

			UE_LOG(LogNet, Log, TEXT("Welcomed by server (Level: %s, Game: %s)"), *URL.Map, *GameName);

			// extract map name and options
			{
				FURL DefaultURL;
				FURL TempURL( &DefaultURL, *URL.Map, TRAVEL_Partial );
				URL.Map = TempURL.Map;
				URL.RedirectURL = RedirectURL;
				URL.Op.Append(TempURL.Op);
			}

			if (GameName.Len() > 0)
			{
				URL.AddOption(*FString::Printf(TEXT("game=%s"), *GameName));
			}

			// Send out netspeed now that we're connected
			FNetControlMessage<NMT_Netspeed>::Send(Connection, Connection->CurrentNetSpeed);

			// We have successfully connected.
			bSuccessfullyConnected = true;
			break;
		}
		case NMT_NetGUIDAssign:
		{
			FNetworkGUID NetGUID;
			FString Path;
			FNetControlMessage<NMT_NetGUIDAssign>::Receive(Bunch, NetGUID, Path);
			NetDriver->ServerConnection->PackageMap->ResolvePathAndAssignNetGUID(NetGUID, Path);
			break;
		}
		default:
			UE_LOG(LogNet, Log, TEXT(" --- Unknown/unexpected message for pending level"));
			break;
	}
}
void UUpdateManager::StartPatchCheck()
{
	ensure(ChecksEnabled());

	UGameInstance* GameInstance = GetGameInstance();
	check(GameInstance);
	bool bStarted = false;

	SetUpdateState(EUpdateState::CheckingForPatch);

	IOnlineSubsystem* OnlineSubConsole = IOnlineSubsystem::GetByPlatform();
	if (OnlineSubConsole)
	{
		IOnlineIdentityPtr OnlineIdentityConsole = OnlineSubConsole->GetIdentityInterface();
		if (OnlineIdentityConsole.IsValid())
		{
			ULocalPlayer* LP = GameInstance->GetFirstGamePlayer();
			if (LP != nullptr)
			{
				const int32 ControllerId = LP->GetControllerId();
				TSharedPtr<const FUniqueNetId> UserId = OnlineIdentityConsole->GetUniquePlayerId(ControllerId);
				if (UserId.IsValid())
				{
					bStarted = true;
					OnlineIdentityConsole->GetUserPrivilege(*UserId,
						EUserPrivileges::CanPlayOnline, IOnlineIdentity::FOnGetUserPrivilegeCompleteDelegate::CreateUObject(this, &ThisClass::OnCheckForPatchComplete, true));
				}
				else
				{
					UE_LOG(LogHotfixManager, Warning, TEXT("No valid platform user id when starting patch check!"));
				}
			}
			else
			{
				UE_LOG(LogHotfixManager, Warning, TEXT("No local player to perform check!"));
			}
		}
	}
	else
	{
		if (GameInstance->IsDedicatedServerInstance())
		{
			bStarted = true;
			PatchCheckComplete(EPatchCheckResult::NoPatchRequired);
		}
		else
		{
			UWorld* World = GetWorld();
			IOnlineIdentityPtr IdentityInt = Online::GetIdentityInterface(World);
			if (IdentityInt.IsValid())
			{
				ULocalPlayer* LP = GameInstance->GetFirstGamePlayer();
				if (LP != nullptr)
				{
					const int32 ControllerId = LP->GetControllerId();
					TSharedPtr<const FUniqueNetId> UserId = IdentityInt->GetUniquePlayerId(ControllerId);
					if (!bInitialUpdateFinished && !UserId.IsValid())
					{
						// Invalid user for "before title/login" check, underlying code doesn't need a valid user currently
						UserId = IdentityInt->CreateUniquePlayerId(TEXT("InvalidUser"));
					}

					if (UserId.IsValid())
					{
						bStarted = true;
						IdentityInt->GetUserPrivilege(*UserId,
							EUserPrivileges::CanPlayOnline, IOnlineIdentity::FOnGetUserPrivilegeCompleteDelegate::CreateUObject(this, &ThisClass::OnCheckForPatchComplete, false));
					}
					else
					{
						UE_LOG(LogHotfixManager, Warning, TEXT("No valid user id when starting patch check!"));
					}
				}
				else
				{
					UE_LOG(LogHotfixManager, Warning, TEXT("No local player to perform check!"));
				}
			}
		}
	}

	if (!bStarted)
	{
		// Any failure to call GetUserPrivilege will result in completing the flow via this path
		PatchCheckComplete(EPatchCheckResult::PatchCheckFailure);
	}
}
Beispiel #30
0
void UGameEngine::Tick( float DeltaSeconds, bool bIdleMode )
{
	SCOPE_CYCLE_COUNTER(STAT_GameEngineTick);
	NETWORK_PROFILER(GNetworkProfiler.TrackFrameBegin());

	int32 LocalTickCycles=0;
	CLOCK_CYCLES(LocalTickCycles);
	
	// -----------------------------------------------------
	// Non-World related stuff
	// -----------------------------------------------------

	if( DeltaSeconds < 0.0f )
	{
#if (UE_BUILD_SHIPPING && WITH_EDITOR)
		// End users don't have access to the secure parts of UDN.  Regardless, they won't
		// need the warning because the game ships with AMD drivers that address the issue.
		UE_LOG(LogEngine, Fatal,TEXT("Negative delta time!"));
#else
		// Send developers to the support list thread.
		UE_LOG(LogEngine, Fatal,TEXT("Negative delta time! Please see https://udn.epicgames.com/lists/showpost.php?list=ue3bugs&id=4364"));
#endif
	}

	// Tick allocator
	if( GMalloc != NULL )
	{
		GMalloc->Tick( DeltaSeconds );
	}

	// Tick the module manager
	FModuleManager::Get().Tick();

	if (!IsRunningDedicatedServer() && !IsRunningCommandlet())
	{
		// Clean up the game viewports that have been closed.
		CleanupGameViewport();
	}

	// If all viewports closed, time to exit.
	if(GIsClient && GameViewport == NULL )
	{
		UE_LOG(LogEngine, Log,  TEXT("All Windows Closed") );
		FPlatformMisc::RequestExit( 0 );
		return;
	}

	if ( GameViewport != NULL )
	{
		// Decide whether to drop high detail because of frame rate.
		GameViewport->SetDropDetail(DeltaSeconds);
	}

	// Update subsystems.
	{
		// This assumes that UObject::StaticTick only calls ProcessAsyncLoading.
		StaticTick( DeltaSeconds );
	}

	// -----------------------------------------------------
	// Begin ticking worlds
	// -----------------------------------------------------

	int32 OriginalGWorldContext = INDEX_NONE;
	for (int32 i=0; i < WorldList.Num(); ++i)
	{
		if (WorldList[i].World() == GWorld)
		{
			OriginalGWorldContext = WorldList[i].ContextHandle;
			break;
		}
	}

	bool WorldWasPaused = false;

	for (int32 WorldIdx = 0; WorldIdx < WorldList.Num(); ++WorldIdx)
	{
		FWorldContext &Context = WorldList[WorldIdx];
		if (Context.World() == NULL)
		{
			continue;
		}

		WorldWasPaused |= Context.World()->IsPaused();

		GWorld = Context.World();

		// Tick all travel and Pending NetGames (Seamless, server, client)
		TickWorldTravel(Context, DeltaSeconds);

		if (!IsRunningDedicatedServer() && !IsRunningCommandlet())
		{
			// Only update reflection captures in game once all 'always loaded' levels have been loaded
			// This won't work with actual level streaming though
			if (Context.World()->AreAlwaysLoadedLevelsLoaded())
			{
				// Update sky light first because it's considered direct lighting, sky diffuse will be visible in reflection capture indirect specular
				USkyLightComponent::UpdateSkyCaptureContents(Context.World());
				UReflectionCaptureComponent::UpdateReflectionCaptureContents(Context.World());
			}
		}

		if (!bIdleMode)
		{
			// Tick the world.
			GameCycles=0;
			CLOCK_CYCLES(GameCycles);
			Context.World()->Tick( LEVELTICK_All, DeltaSeconds );
			UNCLOCK_CYCLES(GameCycles);
		}

		// Issue cause event after first tick to provide a chance for the game to spawn the player and such.
		if( Context.World()->bWorldWasLoadedThisTick )
		{
			Context.World()->bWorldWasLoadedThisTick = false;
			
			const TCHAR* InitialExec = Context.LastURL.GetOption(TEXT("causeevent="),NULL);
			ULocalPlayer* GamePlayer = Context.GamePlayers.Num() > 0 ? Context.GamePlayers[0] : NULL;
			if( InitialExec && GamePlayer )
			{
				UE_LOG(LogEngine, Log, TEXT("Issuing initial cause event passed from URL: %s"), InitialExec);
				GamePlayer->Exec( GamePlayer->GetWorld(), *(FString("CAUSEEVENT ") + InitialExec), *GLog );
			}

			Context.World()->bTriggerPostLoadMap = true;
		}

		// Tick the viewports.
		if ( GameViewport != NULL && !bIdleMode )
		{
			SCOPE_CYCLE_COUNTER(STAT_GameViewportTick);
			GameViewport->Tick(DeltaSeconds);
		}
	
		UpdateTransitionType(Context.World());
	
		// fixme: this will only happen once due to the static bool, but still need to figure out how to handle this for multiple worlds
		if (FPlatformProperties::SupportsWindowedMode())
		{
			// Hide the splashscreen and show the game window
			static bool bFirstTime = true;
			if ( bFirstTime )
			{
				bFirstTime = false;
				FPlatformSplash::Hide();
				if ( GameViewportWindow.IsValid() )
				{
					GameViewportWindow.Pin()->ShowWindow();
					FSlateApplication::Get().RegisterGameViewport( GameViewportWidget.ToSharedRef() );
				}
			}
		}

		if (!bIdleMode && !IsRunningDedicatedServer() && !IsRunningCommandlet())
		{
			// Render everything.
			RedrawViewports();
		}

		// Block on async loading if requested.
		if( Context.World()->bRequestedBlockOnAsyncLoading )
		{
			// Only perform work if there is anything to do. This ensures we are not syncronizing with the GPU
			// and suspending the device needlessly.
			bool bWorkToDo = IsAsyncLoading();
			if (!bWorkToDo)
			{
				Context.World()->UpdateLevelStreaming();
				bWorkToDo = Context.World()->IsVisibilityRequestPending();
			}
			if (bWorkToDo)
			{
				// tell clients to do the same so they don't fall behind
				for( FConstPlayerControllerIterator Iterator = Context.World()->GetPlayerControllerIterator(); Iterator; ++Iterator )
				{
					APlayerController* PlayerController = *Iterator;
					UNetConnection* Conn = Cast<UNetConnection>(PlayerController->Player);
					if (Conn != NULL && Conn->GetUChildConnection() == NULL)
					{
						// call the event to replicate the call
						PlayerController->ClientSetBlockOnAsyncLoading();
						// flush the connection to make sure it gets sent immediately
						Conn->FlushNet(true);
					}
				}

				FStreamingPause::GameThreadWantsToSuspendRendering( GameViewport ? GameViewport->Viewport : NULL );

				// Flushes level streaming requests, blocking till completion.
				Context.World()->FlushLevelStreaming();

				FStreamingPause::GameThreadWantsToResumeRendering();
			}
			Context.World()->bRequestedBlockOnAsyncLoading = false;
		}

		// streamingServer
		if( GIsServer == true )
		{
			SCOPE_CYCLE_COUNTER(STAT_UpdateLevelStreaming);
			Context.World()->UpdateLevelStreaming();
		}

		// Update Audio. This needs to occur after rendering as the rendering code updates the listener position.
		if( GetAudioDevice() )
		{
			GetAudioDevice()->Update( !Context.World()->IsPaused() );
		}

	

		if( GIsClient )
		{
			// GStreamingManager is updated outside of a world context. For now, assuming it needs to tick here, before possibly calling PostLoadMap. 
			// Will need to take another look when trying to support multiple worlds.

			// Update resource streaming after viewports have had a chance to update view information. Normal update.
			GStreamingManager->Tick( DeltaSeconds );

			if ( Context.World()->bTriggerPostLoadMap )
			{
				Context.World()->bTriggerPostLoadMap = false;

				// Turns off the loading movie (if it was turned on by LoadMap) and other post-load cleanup.
				PostLoadMap();
			}
		}

		UNCLOCK_CYCLES(LocalTickCycles);
		TickCycles=LocalTickCycles;

		// See whether any map changes are pending and we requested them to be committed.
		ConditionalCommitMapChange(Context);
	}

	// ----------------------------
	//	End per-world ticking
	// ----------------------------

	// Restore original GWorld*. This will go away one day.
	if (OriginalGWorldContext != INDEX_NONE)
	{
		GWorld = WorldContextFromHandle(OriginalGWorldContext).World();
	}

	// tell renderer about GWorld->IsPaused(), before rendering
	{
		ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(
			SetPaused,
			bool, bGamePaused, WorldWasPaused,
		{
			GRenderingRealtimeClock.SetGamePaused(bGamePaused);
		});
	}