Skip to content

Instantly share code, notes, and snippets.

@v1vendi
Created September 27, 2022 14:15
Show Gist options
  • Save v1vendi/64a2e819c3b67c8bc9d03c007a7bfbf3 to your computer and use it in GitHub Desktop.
Save v1vendi/64a2e819c3b67c8bc9d03c007a7bfbf3 to your computer and use it in GitHub Desktop.

Revisions

  1. v1vendi created this gist Sep 27, 2022.
    85 changes: 85 additions & 0 deletions GameLiftGameModeExample.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,85 @@
    // Copyright Illia Komsa 2022. All rights reserved.
    #include "GameFramework/GameModeBase.h"
    #include "GameFramework/PlayerState.h"
    #include "Kismet/GameplayStatics.h"
    #include "GameLiftGameModeExample.generated.h"

    /**
    * An example PlayerSession class, that adds property to store PlayerSessionId
    */
    UCLASS(Abstract)
    class AGameLiftPlayerStateExample : public APlayerState
    {
    GENERATED_BODY()
    public:
    #if WITH_GAMELIFT
    UPROPERTY()
    FString PlayerSessionId;
    #endif
    };

    /**
    * An example GameMode class to show how you should integrate the GameLiftGameModeComponent to your GameMode
    */
    UCLASS(Abstract)
    class AGameLiftGameModeExample : public AGameModeBase
    {
    GENERATED_BODY()
    public:
    AGameLiftGameModeExample(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get())
    : AGameModeBase(ObjectInitializer)
    {
    MyGameLiftComponent = ObjectInitializer.CreateDefaultSubobject<UGameLiftGameModeComponent>(this, TEXT("GameLiftComponent"));
    }

    virtual void PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage) override;
    virtual void Logout(AController* Exiting);
    virtual FString InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueId, const FString& Options, const FString& Portal);
    private:
    UGameLiftGameModeComponent* MyGameLiftComponent;
    };

    // Before player is logged in to server, we need to check whether they are present in the GameLift GameSession, otherwise fail login
    void AGameLiftGameModeExample::PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage)
    {
    Super::PreLogin(Options, Address, UniqueId, ErrorMessage);

    #if WITH_GAMELIFT
    const FString& PlayerSessionId = UGameplayStatics::ParseOption(Options, "PlayerSessionId");
    const FString& PlayerId = UGameplayStatics::ParseOption(Options, "PlayerId");

    MyGameLiftComponent->AcceptPlayerSessionIfAuthorized(PlayerSessionId, PlayerId, ErrorMessage);
    #endif
    }

    // Before player logs out, we need to remove them from GameLift GameSession, so they can join another.
    // We might not need it if a player disconnects before match end and can reconnect later
    void AGameLiftGameModeExample::Logout(AController* Exiting)
    {
    #if WITH_GAMELIFT
    if (AGameLiftPlayerStateExample* PlayerState = Cast<AGameLiftPlayerStateExample>(NewPlayerController->PlayerState))
    {
    FString PlayerSessionId = PlayerState->PlayerSessionId;
    MyGameLiftComponent->RemovePlayerSession(PlayerSessionId);
    }
    #endif

    Super::Logout(Exiting);
    }

    // After successful login we should store player's PlayerSessionId in their PlayerState, so we can use it later for removing the PlayerSession
    FString AGameLiftGameModeExample::InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueId, const FString& Options, const FString& Portal)
    {
    FString ErrorMessage = Super::InitNewPlayer(NewPlayerController, UniqueId, Options, Portal);

    #if WITH_GAMELIFT
    const FString& PlayerSessionId = UGameplayStatics::ParseOption(Options, "PlayerSessionId");

    if (AGameLiftPlayerStateExample* PlayerState = Cast<AGameLiftPlayerStateExample>(NewPlayerController->PlayerState))
    {
    PlayerState->PlayerSessionId = *PlayerSessionId;
    }
    #endif

    return ErrorMessage;
    }
    28 changes: 28 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,28 @@
    # GameLiftServerSetup plugin for Unreal Engine

    ## What is this plugin used for?

    This plugin contains C++ Component class for your GameMode, that simplifies integration of AWS Gamelift SDK with you UnrealEngine game servers

    ## What does the component do?

    - Registers game server with AWS Gamelift
    - Shuts down game server, when GameLift sends signal to Terminate
    - Outputs GameLift log to STDOUT
    - Provides methods to:
    * send server health status to AWS
    * validate, whether a new player can play in this GameSession
    * remove player from GameSession


    ## To start using the plugin:

    - Download GameLiftServerSDK plugin for UnrealEngine from https://docs.aws.amazon.com/gamelift/latest/developerguide/integration-engines-setup-unreal.html and install to your Unreal Engine project
    - Copy `Spurce/ThirdParty/GameLiftServerSDK` to `Plugins/GameLiftServerSDK/ThirdParty` instead of compiling binaries yourself. The plugin contains precompiled binaries for Win64 and Linux
    - Add `GameLiftServerSDK` and `GameLiftServerSetup` plugins to your project via Plugin Browser or in `_YourProject_.uproject`
    - Add `GameLiftServerSetup` module to `_YourProject_.build.cs`
    - Add `GameLiftGameModeComponent` to your GameMode
    - Add FString variable to PlayerState to store their PlayerSessionId
    - Add component's methods calls to `GameMode::PreLogin` and `GameMode::Logout`

    An example of integration is in `./Source/Example/GameLiftGameModeExample.cpp` and also in this gist