diff --git a/Game/Config/DefaultSpatialGDKSettings.ini b/Game/Config/DefaultSpatialGDKSettings.ini index d25367ba..3df8e344 100644 --- a/Game/Config/DefaultSpatialGDKSettings.ini +++ b/Game/Config/DefaultSpatialGDKSettings.ini @@ -29,4 +29,4 @@ DefaultWorkerType=(WorkerTypeName="UnrealWorker") bEnableOffloading=False ActorGroups=() ServerWorkerTypes=("UnrealWorker") - +ServicesRegion=Default diff --git a/Game/Content/Characters/BP_Base_Character.uasset b/Game/Content/Characters/BP_Base_Character.uasset index 906734a2..d717bd29 100644 Binary files a/Game/Content/Characters/BP_Base_Character.uasset and b/Game/Content/Characters/BP_Base_Character.uasset differ diff --git a/Game/Content/Characters/BP_FPS_Character.uasset b/Game/Content/Characters/BP_FPS_Character.uasset index af2d1787..40063f90 100644 Binary files a/Game/Content/Characters/BP_FPS_Character.uasset and b/Game/Content/Characters/BP_FPS_Character.uasset differ diff --git a/Game/Content/GameMode/BP_PlayerState.uasset b/Game/Content/GameMode/BP_PlayerState.uasset index 17798b82..d74295e2 100644 Binary files a/Game/Content/GameMode/BP_PlayerState.uasset and b/Game/Content/GameMode/BP_PlayerState.uasset differ diff --git a/Game/Source/GDKShooter/Private/Controllers/GDKPlayerController.cpp b/Game/Source/GDKShooter/Private/Controllers/GDKPlayerController.cpp index db1f5ad7..7e6258ef 100644 --- a/Game/Source/GDKShooter/Private/Controllers/GDKPlayerController.cpp +++ b/Game/Source/GDKShooter/Private/Controllers/GDKPlayerController.cpp @@ -43,19 +43,6 @@ AGDKPlayerController::AGDKPlayerController() } -void AGDKPlayerController::BeginPlay() -{ - Super::BeginPlay(); - - if (PlayerState) - { - if (UPlayerPublisher* PlayerPublisher = Cast(GetWorld()->GetGameState()->GetComponentByClass(UPlayerPublisher::StaticClass()))) - { - PlayerPublisher->PublishPlayer(PlayerState, EPlayerProgress::Connected); - } - } -} - void AGDKPlayerController::Tick(float DeltaTime) { Super::Tick(DeltaTime); diff --git a/Game/Source/GDKShooter/Private/Deployments/DeploymentsPlayerController.cpp b/Game/Source/GDKShooter/Private/Deployments/DeploymentsPlayerController.cpp index c4b30128..b2367f5f 100644 --- a/Game/Source/GDKShooter/Private/Deployments/DeploymentsPlayerController.cpp +++ b/Game/Source/GDKShooter/Private/Deployments/DeploymentsPlayerController.cpp @@ -4,6 +4,7 @@ #include "SpatialGameInstance.h" #include "TimerManager.h" +#include "SpatialGDKSettings.h" #include "SpatialWorkerConnection.h" #include "GDKLogging.h" @@ -15,79 +16,36 @@ void ADeploymentsPlayerController::BeginPlay() bShowMouseCursor = true; - QueryPIT(); -} + USpatialGameInstance* SpatialGameInstance = GetGameInstance(); + SpatialWorkerConnection = SpatialGameInstance->GetSpatialWorkerConnection(); -void ADeploymentsPlayerController::EndPlay(const EEndPlayReason::Type Reason) -{ - GetWorld()->GetTimerManager().ClearAllTimersForObject(this); -} - -void OnLoginTokens(void* UserData, const Worker_Alpha_LoginTokensResponse* LoginTokens) -{ - ADeploymentsPlayerController* contoller = static_cast(UserData); - if (LoginTokens->status.code == WORKER_CONNECTION_STATUS_CODE_SUCCESS) - { - UE_LOG(LogGDK, Log, TEXT("Success: Login Token Count %d"), LoginTokens->login_token_count); - contoller->Populate(LoginTokens); - } - else + if (SpatialWorkerConnection == nullptr) { - UE_LOG(LogGDK, Log, TEXT("Failure: Error %s"), UTF8_TO_TCHAR(LoginTokens->status.detail)); + // We might not be using spatial networking in which case SpatialWorkerConnection will not exist so we should just return + return; } -} -void OnPlayerIdentityToken(void* UserData, const Worker_Alpha_PlayerIdentityTokenResponse* PIToken) -{ - if (PIToken->status.code == WORKER_CONNECTION_STATUS_CODE_SUCCESS) - { - UE_LOG(LogGDK, Log, TEXT("Success: Received PIToken: %s"), UTF8_TO_TCHAR(PIToken->player_identity_token)); - ADeploymentsPlayerController* controller = static_cast(UserData); - controller->LatestPITokenData = PIToken->player_identity_token; - controller->LatestPIToken = UTF8_TO_TCHAR(PIToken->player_identity_token); - - if (!controller->GetWorld()->GetTimerManager().IsTimerActive(controller->QueryDeploymentsTimer)) + FString SpatialWorkerType = SpatialGameInstance->GetSpatialWorkerType().ToString(); + SpatialWorkerConnection->RegisterOnLoginTokensCallback([this](const Worker_Alpha_LoginTokensResponse* Deployments){ + Populate(Deployments); + if (!GetWorld()->GetTimerManager().IsTimerActive(QueryDeploymentsTimer)) { - controller->GetWorld()->GetTimerManager().SetTimer(controller->QueryDeploymentsTimer, controller, &ADeploymentsPlayerController::QueryDeployments, 5.0f, true, 0.0f); + GetWorld()->GetTimerManager().SetTimer(QueryDeploymentsTimer, this, &ADeploymentsPlayerController::ScheduleRefreshDeployments, 10.0f, true, 0.0f); } - } - else + return true; + }); + + if (GetDefault()->bUseDevelopmentAuthenticationFlow) { - UE_LOG(LogGDK, Log, TEXT("Failure: Error %s"), UTF8_TO_TCHAR(PIToken->status.detail)); - ADeploymentsPlayerController* controller = static_cast(UserData); - - if (controller->GetWorld()->GetTimerManager().IsTimerActive(controller->QueryDeploymentsTimer)) - { - controller->GetWorld()->GetTimerManager().ClearTimer(controller->QueryDeploymentsTimer); - } + SpatialWorkerConnection->Connect(true, 0); } } -void ADeploymentsPlayerController::QueryDeployments() -{ - Worker_Alpha_LoginTokensRequest* LTParams = new Worker_Alpha_LoginTokensRequest(); - LTParams->player_identity_token = LatestPITokenData; - LTParams->worker_type = "UnrealClient"; - Worker_Alpha_LoginTokensResponseFuture* LTFuture = Worker_Alpha_CreateDevelopmentLoginTokensAsync("locator.improbable.io", 444, LTParams); - Worker_Alpha_LoginTokensResponseFuture_Get(LTFuture, nullptr, this, OnLoginTokens); -} - -void ADeploymentsPlayerController::QueryPIT() +void ADeploymentsPlayerController::EndPlay(const EEndPlayReason::Type Reason) { - Worker_Alpha_PlayerIdentityTokenRequest* PITParams = new Worker_Alpha_PlayerIdentityTokenRequest(); - // Replace this string with a dev auth token, see docs for information on how to generate one of these - PITParams->development_authentication_token = "REPLACE ME"; - PITParams->player_id = "Player Id"; - PITParams->display_name = ""; - PITParams->metadata = ""; - PITParams->use_insecure_connection = false; - - Worker_Alpha_PlayerIdentityTokenResponseFuture* PITFuture = Worker_Alpha_CreateDevelopmentPlayerIdentityTokenAsync("locator.improbable.io", 444, PITParams); - - if (PITFuture != nullptr) - { - Worker_Alpha_PlayerIdentityTokenResponseFuture_Get(PITFuture, nullptr, this, OnPlayerIdentityToken); - } + if (SpatialWorkerConnection != nullptr) + SpatialWorkerConnection->RegisterOnLoginTokensCallback([](const Worker_Alpha_LoginTokensResponse* Deployments){return false;}); + GetWorld()->GetTimerManager().ClearAllTimersForObject(this); } FDeploymentInfo Parse(const Worker_Alpha_LoginTokenDetails LoginToken) @@ -137,12 +95,19 @@ void ADeploymentsPlayerController::Populate(const Worker_Alpha_LoginTokensRespon void ADeploymentsPlayerController::JoinDeployment(const FString& LoginToken) { + if (SpatialWorkerConnection == nullptr) + { + UE_LOG(LogGDK, Error, TEXT("Failure: failed to Join Deployment caused by SpatialWorkerConnection is nullptr")); + return; + } + + const FLocatorConfig& LocatorConfig = SpatialWorkerConnection->LocatorConfig; FURL TravelURL; - TravelURL.Host = TEXT("locator.improbable.io"); + TravelURL.Host = LocatorConfig.LocatorHost; TravelURL.AddOption(TEXT("locator")); - TravelURL.AddOption(*FString::Printf(TEXT("playeridentity=%s"), *LatestPIToken)); + TravelURL.AddOption(*FString::Printf(TEXT("playeridentity=%s"), *LocatorConfig.PlayerIdentityToken)); TravelURL.AddOption(*FString::Printf(TEXT("login=%s"), *LoginToken)); - + OnLoadingStarted.Broadcast(); ClientTravel(TravelURL.ToString(), TRAVEL_Absolute, false); @@ -152,3 +117,9 @@ void ADeploymentsPlayerController::SetLoadingScreen(UUserWidget* LoadingScreen) { GetGameInstance()->GetGameViewportClient()->AddViewportWidgetContent(LoadingScreen->TakeWidget()); } + +void ADeploymentsPlayerController::ScheduleRefreshDeployments() +{ + if (SpatialWorkerConnection != nullptr) + SpatialWorkerConnection->RequestDeploymentLoginTokens(); +} diff --git a/Game/Source/GDKShooter/Private/UI/GDKWidget.cpp b/Game/Source/GDKShooter/Private/UI/GDKWidget.cpp index ee279e09..4d493077 100644 --- a/Game/Source/GDKShooter/Private/UI/GDKWidget.cpp +++ b/Game/Source/GDKShooter/Private/UI/GDKWidget.cpp @@ -4,6 +4,7 @@ #include "Components/ControllerEventsComponent.h" #include "Components/GDKMovementComponent.h" #include "Components/HealthComponent.h" +#include "EngineClasses/SpatialGameInstance.h" #include "Game/Components/LobbyTimerComponent.h" #include "Game/Components/MatchTimerComponent.h" #include "Game/Components/PlayerCountingComponent.h" @@ -106,6 +107,11 @@ void UGDKWidget::LeaveGame(const FString& TargetMap) FURL TravelURL; TravelURL.Map = *TargetMap; + if (USpatialGameInstance* GameInstance = Cast(GetGameInstance())) + { + GameInstance->GetSpatialWorkerConnection()->DestroyConnection(); + } + GetOwningPlayer()->ClientTravel(TravelURL.ToString(), TRAVEL_Absolute, false /*bSeamless*/); } diff --git a/Game/Source/GDKShooter/Public/Controllers/GDKPlayerController.h b/Game/Source/GDKShooter/Public/Controllers/GDKPlayerController.h index 4c404433..7f784996 100644 --- a/Game/Source/GDKShooter/Public/Controllers/GDKPlayerController.h +++ b/Game/Source/GDKShooter/Public/Controllers/GDKPlayerController.h @@ -19,7 +19,6 @@ class GDKSHOOTER_API AGDKPlayerController : public APlayerController public: AGDKPlayerController(); - virtual void BeginPlay() override; virtual void Tick(float DeltaTime) override; FPawnEvent& OnPawn() { return PawnEvent; } diff --git a/Game/Source/GDKShooter/Public/Deployments/DeploymentsPlayerController.h b/Game/Source/GDKShooter/Public/Deployments/DeploymentsPlayerController.h index ff493e69..830b0ce5 100644 --- a/Game/Source/GDKShooter/Public/Deployments/DeploymentsPlayerController.h +++ b/Game/Source/GDKShooter/Public/Deployments/DeploymentsPlayerController.h @@ -9,6 +9,8 @@ #include "DeploymentsPlayerController.generated.h" +class USpatialWorkerConnection; + USTRUCT(BlueprintType) struct FDeploymentInfo { GENERATED_BODY() @@ -51,19 +53,15 @@ class GDKSHOOTER_API ADeploymentsPlayerController : public APlayerController FString LatestPIToken; const char * LatestPITokenData; - void QueryDeployments(); - FTimerHandle QueryDeploymentsTimer; + USpatialWorkerConnection* SpatialWorkerConnection = nullptr; UFUNCTION(BlueprintCallable) void JoinDeployment(const FString& LoginToken); UFUNCTION(BlueprintCallable) void SetLoadingScreen(UUserWidget* LoadingScreen); - -private: - - void QueryPIT(); - +private: + void ScheduleRefreshDeployments(); }; diff --git a/Game/Source/GDKShooter/Public/Game/Components/PlayerPublisher.h b/Game/Source/GDKShooter/Public/Game/Components/PlayerPublisher.h index 638c6d6b..3b581a80 100644 --- a/Game/Source/GDKShooter/Public/Game/Components/PlayerPublisher.h +++ b/Game/Source/GDKShooter/Public/Game/Components/PlayerPublisher.h @@ -24,6 +24,7 @@ class GDKSHOOTER_API UPlayerPublisher : public UActorComponent GENERATED_BODY() public: + UFUNCTION(BlueprintCallable) void PublishPlayer(APlayerState* PlayerState, EPlayerProgress Progress) { PlayerEvent.Broadcast(PlayerState, Progress); } UPROPERTY(BlueprintAssignable) diff --git a/README.md b/README.md index ace8a4ca..9d815ec1 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ - **LICENSE:** Use of the contents of this repository is subject to the [license](LICENSE.md) -The SpatialOS Game Development Kit (GDK) for Unreal is an Unreal Engine fork and plugin with associated projects. It gives you the features of [SpatialOS](https://spatialos.improbable.io/docs/reference/latest), within the familiar workflows and APIs of Unreal Engine. For more information, please see the GDK's [documentation website](https://docs.improbable.io/unreal/latest). +The SpatialOS Game Development Kit (GDK) for Unreal is an Unreal Engine fork and plugin with associated projects. It gives you the features of [SpatialOS](https://documentation.improbable.io/spatialos-overview/docs), within the familiar workflows and APIs of Unreal Engine. For more information, see the GDK's [documentation website](https://documentation.improbable.io/gdk-for-unreal/docs). -> The SpatialOS GDK for Unreal is in alpha. It is ready to use for development of single-server games, but not recommended for public releases. We are committed to rapid development of the GDK to provide a performant release - for information on this, see our [development roadmap](https://github.com/spatialos/UnrealGDK/projects/1) and [Unreal features support](https://docs.improbable.io/unreal/latest/unreal-features-support) pages, and contact us via our forums, or on Discord. +> To understand the feature-completeness, stability, performance, and support levels you can expect from the GDK, see the [product maturity lifecycle page](https://documentation.improbable.io/gdk-for-unreal/docs/product-maturity-lifecycle). For more information, visit the [development roadmap](https://github.com/spatialos/UnrealGDK/projects/1) and [Unreal features support](https://documentation.improbable.io/gdk-for-unreal/docs/unreal-features-support) pages, and contact us via our forums, or on Discord. This is the repository for the Example Project, an example shooter game that uses the GDK. @@ -18,11 +18,11 @@ In addition to the Example Project, the GDK also contains: * [The GDK plugin](https://github.com/spatialos/UnrealGDK) ## About the Example Project -The Example Project contains gameplay and assets that are representative of a basic first-person shooter running on SpatialOS. If you want to make your own project from scratch, use the Starter Template by following the [Starter Template guide](https://docs.improbable.io/unreal/alpha/content/get-started/gdk-template) in the GDK for Unreal documentation. +The Example Project contains gameplay and assets that are representative of a basic first-person shooter running on SpatialOS. If you want to make your own project from scratch, use the Starter Template by following the [Starter Template guide](https://documentation.improbable.io/gdk-for-unreal/docs/sample-projects-starter-template-introduction) in the GDK for Unreal documentation. -For setup instructions, follow the [Example Project guide](https://docs.improbable.io/unreal/latest/content/get-started/example-project/exampleproject-intro) in the GDK for Unreal documentation. +For setup instructions, follow the [Example Project guide](https://documentation.improbable.io/gdk-for-unreal/docs/sample-projects-example-project-introduction) in the GDK for Unreal documentation. -For more information, see the [SpatialOS GDK for Unreal documentation](https://docs.improbable.io/unreal/latest/). +For more information, see the [SpatialOS GDK for Unreal documentation](https://documentation.improbable.io/gdk-for-unreal/docs). #### Game controls @@ -55,4 +55,4 @@ We have released the GDK for Unreal this early in development because we want yo We are not currently accepting public contributions. However, we are accepting [issues](https://github.com/spatialos/UnrealGDK/issues) and we do want your feedback. -© 2019 Improbable +© 2020 Improbable diff --git a/spatial/spatialos.json b/spatial/spatialos.json index e5e5f760..e0c2a608 100644 --- a/spatial/spatialos.json +++ b/spatial/spatialos.json @@ -1,11 +1,11 @@ { "name": "your_project_name_here", "project_version": "0.0.1", - "sdk_version": "14.1.0", + "sdk_version": "14.5.0", "dependencies": [ { "name": "standard_library", - "version": "14.1.0" + "version": "14.5.0" } ] }