diff --git a/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedGameSession.h b/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedGameSession.h new file mode 100644 index 0000000..f36e574 --- /dev/null +++ b/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedGameSession.h @@ -0,0 +1,70 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "CoreMinimal.h" +#include "Engine/Engine.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "Engine/GameInstance.h" +#include "GameFramework/GameModeBase.h" +#include "GameFramework/GameSession.h" + +//#include "UObjectIterator.h" + +#include "AdvancedGameSession.generated.h" + + + + +/** + A quick wrapper around the game session to add a partial ban implementation. Just bans for the duration of the current session +*/ +UCLASS(config = Game, notplaceable) +class AAdvancedGameSession : public AGameSession +{ + GENERATED_UCLASS_BODY() + +public: + + UPROPERTY(Transient) + TMap BanList; + + virtual bool BanPlayer(class APlayerController* BannedPlayer, const FText& BanReason) + { + + if (APlayerState* PlayerState = (BannedPlayer != NULL) ? BannedPlayer->PlayerState : NULL) + { + FUniqueNetIdRepl UniqueNetID = PlayerState->GetUniqueId(); + bool bWasKicked = KickPlayer(BannedPlayer, BanReason); + + if (bWasKicked) + { + BanList.Add(UniqueNetID, BanReason); + } + + return bWasKicked; + } + + return false; + } + + // This should really be handled in the game mode asking game session, but I didn't want to force a custom game session AND game mode + // If done in the game mode, we could check prior to actually spooling up any player information in ApproveLogin + virtual void PostLogin(APlayerController* NewPlayer) override + { + if (APlayerState* PlayerState = (NewPlayer != NULL) ? NewPlayer->PlayerState : NULL) + { + FUniqueNetIdRepl UniqueNetID = PlayerState->GetUniqueId(); + + if (BanList.Contains(UniqueNetID)) + { + KickPlayer(NewPlayer, BanList[UniqueNetID]); + } + } + } +}; + +AAdvancedGameSession::AAdvancedGameSession(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +} \ No newline at end of file diff --git a/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedSessionsLibrary.h b/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedSessionsLibrary.h index 6e673f3..7ae831d 100644 --- a/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedSessionsLibrary.h +++ b/AdvancedSessions/Source/AdvancedSessions/Classes/AdvancedSessionsLibrary.h @@ -14,6 +14,9 @@ #include "Engine/GameInstance.h" #include "Interfaces/OnlineSessionInterface.h" +#include "GameFramework/GameModeBase.h" +#include "GameFramework/GameSession.h" + //#include "UObjectIterator.h" #include "AdvancedSessionsLibrary.generated.h" @@ -28,6 +31,17 @@ class UAdvancedSessionsLibrary : public UBlueprintFunctionLibrary { GENERATED_BODY() public: + //********* Session Admin Functions *************// + + // Kick a player from the currently active game session, only available on the server + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions", meta = (WorldContext = "WorldContextObject")) + static bool KickPlayer(UObject* WorldContextObject, APlayerController* PlayerToKick, FText KickReason); + + // Ban a player from the currently active game session, only available on the server + // Note that the default gamesession class does not implement an actual ban list and just kicks when this is called + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions", meta = (WorldContext = "WorldContextObject")) + static bool BanPlayer(UObject* WorldContextObject, APlayerController* PlayerToBan, FText BanReason); + //********* Session Search Functions *************// // Adds or modifies session settings in an existing array depending on if they exist already or not diff --git a/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedSessionsLibrary.cpp b/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedSessionsLibrary.cpp index ff46f39..caf1cf2 100644 --- a/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedSessionsLibrary.cpp +++ b/AdvancedSessions/Source/AdvancedSessions/Private/AdvancedSessionsLibrary.cpp @@ -6,6 +6,43 @@ //General Log DEFINE_LOG_CATEGORY(AdvancedSessionsLog); + +bool UAdvancedSessionsLibrary::KickPlayer(UObject* WorldContextObject, APlayerController* PlayerToKick, FText KickReason) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + + if (World) + { + if (AGameModeBase* GameMode = World->GetAuthGameMode()) + { + if (GameMode->GameSession) + { + return GameMode->GameSession->KickPlayer(PlayerToKick, KickReason); + } + } + } + + return false; +} + +bool UAdvancedSessionsLibrary::BanPlayer(UObject* WorldContextObject, APlayerController* PlayerToBan, FText BanReason) +{ + UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull); + + if (World) + { + if (AGameModeBase* GameMode = World->GetAuthGameMode()) + { + if (GameMode->GameSession) + { + return GameMode->GameSession->BanPlayer(PlayerToBan, BanReason); + } + } + } + + return false; +} + bool UAdvancedSessionsLibrary::IsValidSession(const FBlueprintSessionResult & SessionResult) { return SessionResult.OnlineResult.IsValid();