commit 84e42243435ad2631249888e4e854f0d2b733122 Author: mordentral Date: Thu Dec 17 08:56:07 2015 -0500 FirstCommitdf diff --git a/AdvancedSessions.uplugin b/AdvancedSessions.uplugin new file mode 100644 index 0000000..f596ea8 --- /dev/null +++ b/AdvancedSessions.uplugin @@ -0,0 +1,21 @@ +{ + "FileVersion" : 3, + + "FriendlyName" : "Advanced Sessions", + "Version" : 1.9, + "VersionName": "1.9", + "EngineVersion" : 1579795, + "Description" : "Adds new blueprint functions to handle more advanced session operations.", + "Category" : "Advanced Sessions Plugin", + "CreatedBy" : "Joshua Statzer", + "CreatedByURL" : "N/A", + + "Modules" : + [ + { + "Name" : "AdvancedSessions", + "Type" : "RunTime", + "LoadingPhase" : "PreDefault" + } + ] +} \ No newline at end of file diff --git a/Resources/Icon128.png b/Resources/Icon128.png new file mode 100644 index 0000000..8e2f1f1 Binary files /dev/null and b/Resources/Icon128.png differ diff --git a/Source/AdvancedSessions/AdvancedSessions.Build.cs b/Source/AdvancedSessions/AdvancedSessions.Build.cs new file mode 100644 index 0000000..7e2fed6 --- /dev/null +++ b/Source/AdvancedSessions/AdvancedSessions.Build.cs @@ -0,0 +1,14 @@ +using UnrealBuildTool; +using System.IO; + +public class AdvancedSessions : ModuleRules +{ + public AdvancedSessions(TargetInfo Target) + { + PrivateIncludePaths.AddRange(new string[] { "AdvancedSessions/Private" }); + PublicIncludePaths.AddRange(new string[] { "AdvancedSessions/Public" }); + + PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "OnlineSubsystem","CoreUObject", "OnlineSubsystemUtils", "Networking", "Sockets" }); + PrivateDependencyModuleNames.AddRange(new string[] { "OnlineSubsystem", "Sockets", "Networking"}); + } +} \ No newline at end of file diff --git a/Source/AdvancedSessions/Classes/AdvancedFriendsGameInstance.h b/Source/AdvancedSessions/Classes/AdvancedFriendsGameInstance.h new file mode 100644 index 0000000..4f41194 --- /dev/null +++ b/Source/AdvancedSessions/Classes/AdvancedFriendsGameInstance.h @@ -0,0 +1,109 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "OnlineSubSystemHeader.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "OnlineFriendsInterface.h" +#include "OnlineUserInterface.h" +#include "OnlineMessageInterface.h" +#include "OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +#include "OnlineSessionInterface.h" +#include "OnlineSessionSettings.h" +#include "UObjectIterator.h" +#include "AdvancedFriendsInterface.h" + +#include "AdvancedFriendsGameInstance.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedFriendsInterfaceLog, Log, All); + +UCLASS() +class UAdvancedFriendsGameInstance : public UGameInstance +{ + GENERATED_BODY() +public: + + UAdvancedFriendsGameInstance(const FObjectInitializer& ObjectInitializer); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedFriendsInterface) + bool bCallFriendInterfaceEventsOnPlayerControllers; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedFriendsInterface) + bool bCallVoiceInterfaceEventsOnPlayerControllers; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedVoiceInterface) + bool bEnableTalkingStatusDelegate; + + //virtual void PostLoad() override; + virtual void Shutdown() override; + virtual void Init() override; + + //*** Session invite accepted by local ***// + FOnSessionUserInviteAcceptedDelegate SessionInviteAcceptedDelegate; + FDelegateHandle SessionInviteAcceptedDelegateHandle; + + void OnSessionInviteAcceptedMaster(const bool bWasSuccessful, int32 LocalPlayer, TSharedPtr PersonInviting, const FOnlineSessionSearchResult& SessionToJoin); + + // After a session invite has been accepted by the local player this event is triggered, call JoinSession on the session result to join it + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends") + void OnSessionInviteAccepted(int32 LocalPlayerNum, FBPUniqueNetId PersonInviting, const FBlueprintSessionResult& SessionToJoin); + + + // After a voice status has changed this event is triggered if the bEnableTalkingStatusDelegate property is true + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedVoice") + void OnPlayerTalkingStateChanged(FBPUniqueNetId PlayerId, bool bIsTalking); + + void OnPlayerTalkingStateChangedMaster(TSharedRef PlayerId, bool bIsTalking); + + FOnPlayerTalkingStateChangedDelegate PlayerTalkingStateChangedDelegate; + FDelegateHandle PlayerTalkingStateChangedDelegateHandle; + + //*** Session Invite Received From Friend ***// + // REMOVED BECAUSE IT NEVER GETS CALLED + /*FOnSessionInviteReceivedDelegate SessionInviteReceivedDelegate; + FDelegateHandle SessionInviteReceivedDelegateHandle; + + void OnSessionInviteReceivedMaster(const FUniqueNetId &InvitedPlayer, const FUniqueNetId &FriendInviting, const FOnlineSessionSearchResult& Session); + + // After a session invite has been sent from a friend this event is triggered, call JoinSession on the session result to join it + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends") + void OnSessionInviteReceived(const FBPUniqueNetId &InvitedPlayer, const FBPUniqueNetId &FriendInviting, const FBlueprintSessionResult &Session); + */ + + //*** Friend Invite Accepted ***// + /*FOnInviteAcceptedDelegate FriendInviteAcceptedDelegate; + FDelegateHandle FriendInviteAcceptedDelegateHandle; + + void OnFriendInviteAcceptedDelegateMaster(const FUniqueNetId& LocalPlayer, const FUniqueNetId &PlayerInvited); + + // After a session invite has been accepted by a friend this event is triggered + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends") + void OnFriendInviteAccepted(const FBPUniqueNetId &InvitedPlayer, const FBPUniqueNetId &PlayerInvited); + */ + + //*** Friend Invite Rejected ***// + /*FOnInviteRejectedDelegate SessionInviteRejectedByFriendDelegate; + FDelegateHandle InviteRejectedByFriendDelegateHandle; + + void OnFriendInviteRejectedDelegateMaster(const FUniqueNetId& LocalPlayer, const FUniqueNetId &PlayerDeclined); + + // After a friend invite has been rejected this event is triggered + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends") + void OnFriendInviteRejected(const FBPUniqueNetId &InvitedPlayer, const FBPUniqueNetId &PlayerDeclined); + */ + + //*** Removed By Friend ***// + /*FOnFriendRemovedDelegate RemovedByFriendDelegate; + FDelegateHandle RemovedByFriendDelegateHandle; + + void OnRemovedByFriendDelegateMaster(const FUniqueNetId& LocalPlayer, const FUniqueNetId &FriendRemoved); + + // After a friend removed the player this event is triggered + UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends") + void OnRemovedByFriend(const FBPUniqueNetId &InvitedPlayer, const FBPUniqueNetId &FriendRemoved);*/ +}; + diff --git a/Source/AdvancedSessions/Classes/AdvancedFriendsInterface.h b/Source/AdvancedSessions/Classes/AdvancedFriendsInterface.h new file mode 100644 index 0000000..a985d38 --- /dev/null +++ b/Source/AdvancedSessions/Classes/AdvancedFriendsInterface.h @@ -0,0 +1,44 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "OnlineSubSystemHeader.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "OnlineFriendsInterface.h" +#include "OnlineUserInterface.h" +#include "OnlineMessageInterface.h" +#include "OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +#include "OnlineSessionInterface.h" +#include "OnlineSessionSettings.h" +#include "UObjectIterator.h" +#include "BlueprintDataDefinitions.h" +#include "AdvancedFriendsInterface.generated.h" + + +UINTERFACE(MinimalAPI) +class UAdvancedFriendsInterface : public UInterface +{ + GENERATED_UINTERFACE_BODY() +}; + +class IAdvancedFriendsInterface +{ + GENERATED_IINTERFACE_BODY() +public: + + // Called when the designated LocalUser has accepted a session invite, use JoinSession on result to connect + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "OnSessionInviteAccepted")) + void OnSessionInviteAccepted(FBPUniqueNetId PersonInviting, const FBlueprintSessionResult& SearchResult); + + // Called when the designated LocalUser has accepted a session invite, use JoinSession on result to connect + UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "OnPlayerVoiceStateChanged")) + void OnPlayerVoiceStateChanged(FBPUniqueNetId PlayerId, bool bIsTalking); + + // REMOVED BECAUSE IT WAS NEVER BEING CALLED + // Called when the designated LocalUser has received a session invite, use JoinSession on result to connect + //UFUNCTION(BlueprintImplementableEvent, meta = (FriendlyName = "OnSessionInviteReceived")) + //void OnSessionInviteReceived(const FBPUniqueNetId &FriendInviting, const FBlueprintSessionResult &Session); + +}; diff --git a/Source/AdvancedSessions/Classes/AdvancedFriendsLibrary.h b/Source/AdvancedSessions/Classes/AdvancedFriendsLibrary.h new file mode 100644 index 0000000..f834b2e --- /dev/null +++ b/Source/AdvancedSessions/Classes/AdvancedFriendsLibrary.h @@ -0,0 +1,56 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "OnlineSubSystemHeader.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "OnlineFriendsInterface.h" +#include "OnlineUserInterface.h" +#include "OnlineMessageInterface.h" +#include "OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +#include "OnlineSessionInterface.h" + +#include "UObjectIterator.h" + +#include "AdvancedFriendsLibrary.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedFriendsLog, Log, All); + + +UCLASS() +class UAdvancedFriendsLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + + //********* Friend List Functions *************// + + // Sends an Invite to the current online session to a list of friends + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|FriendsList", meta = (ExpandEnumAsExecs = "Result")) + static void SendSessionInviteToFriends(APlayerController *PlayerController, const TArray &Friends, TEnumAsByte &Result); + + // Sends an Invite to the current online session to a friend + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|FriendsList", meta = (ExpandEnumAsExecs = "Result")) + static void SendSessionInviteToFriend(APlayerController *PlayerController, const FBPUniqueNetId &FriendUniqueNetId, TEnumAsByte &Result); + + // Get a friend from the previously read/saved friends list (Must Call GetFriends first for this to return anything) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|FriendsList") + static void GetFriend(APlayerController *PlayerController, const FBPUniqueNetId FriendUniqueNetId, FBPFriendInfo &Friend); + + // Get the previously read/saved friends list (Must Call GetFriends first for this to return anything) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|FriendsList") + static void GetStoredFriendsList(APlayerController *PlayerController, TArray &FriendsList); + + // Get the previously read/saved recent players list (Must Call GetRecentPlayers first for this to return anything) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|RecentPlayersList") + static void GetStoredRecentPlayersList(FBPUniqueNetId UniqueNetId, TArray &PlayersList); + + // Check if a UniqueNetId is a friend + UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|FriendsList") + static void IsAFriend(APlayerController *PlayerController, const FBPUniqueNetId UniqueNetId, bool &IsFriend); + +}; diff --git a/Source/AdvancedSessions/Classes/AdvancedSessionsLibrary.h b/Source/AdvancedSessions/Classes/AdvancedSessionsLibrary.h new file mode 100644 index 0000000..021f064 --- /dev/null +++ b/Source/AdvancedSessions/Classes/AdvancedSessionsLibrary.h @@ -0,0 +1,143 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "OnlineSubSystemHeader.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "OnlineFriendsInterface.h" +#include "OnlineUserInterface.h" +#include "OnlineMessageInterface.h" +#include "OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +#include "OnlineSessionInterface.h" + +#include "UObjectIterator.h" + +#include "AdvancedSessionsLibrary.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedSessionsLog, Log, All); + + +UCLASS() +class UAdvancedSessionsLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + //********* Session Search Functions *************// + + // Adds or modifies session settings in an existing array depending on if they exist already or not + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo") + static void AddOrModifyExtraSettings(const TArray & SettingsArray, const TArray & NewOrChangedSettings, TArray & ModifiedSettingsArray); + + // Get an array of the session settings from a session search result + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo") + static void GetExtraSettings(FBlueprintSessionResult SessionResult, TArray & ExtraSettings); + + // Get the current session state + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo") + static void GetSessionState(TEnumAsByte &SessionState); + + // Get the current session settings + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "Result")) + static void GetSessionSettings(int32 &NumConnections, bool &bIsLAN, bool &bIsDedicated, bool &bIsAnticheatEnabled, int32 &BuildUniqueID, TArray &ExtraSettings, TEnumAsByte &Result); + + // Check if someone is in the current session + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo") + static void IsPlayerInSession(const FBPUniqueNetId &PlayerToCheck, bool &bIsInSession); + + // Make a literal session search parameter + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionsSearchSetting MakeLiteralSessionSearchProperty(FSessionPropertyKeyPair SessionSearchProperty, EOnlineComparisonOpRedux::Type ComparisonOp); + + + //********* Session Information Functions ***********// + + // Get the Unique Current Build ID + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo") + static void GetCurrentUniqueBuildID(int32 &UniqueBuildId); + + // Get the Unique Build ID from a session search result + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo") + static void GetUniqueBuildID(FBlueprintSessionResult SessionResult, int32 &UniqueBuildId); + + // Get session custom information key/value as Byte (For Enums) + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult")) + static void GetSessionPropertyByte(const TArray & ExtraSettings, FName SettingName, TEnumAsByte &SearchResult, uint8 &SettingValue); + + // Get session custom information key/value as Bool + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult")) + static void GetSessionPropertyBool(const TArray & ExtraSettings, FName SettingName, TEnumAsByte &SearchResult, bool &SettingValue); + + // Get session custom information key/value as String + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult")) + static void GetSessionPropertyString(const TArray & ExtraSettings, FName SettingName, TEnumAsByte &SearchResult, FString &SettingValue); + + // Get session custom information key/value as Int + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult")) + static void GetSessionPropertyInt(const TArray & ExtraSettings, FName SettingName, TEnumAsByte &SearchResult, int32 &SettingValue); + + // Get session custom information key/value as Float + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult")) + static void GetSessionPropertyFloat(const TArray & ExtraSettings, FName SettingName, TEnumAsByte &SearchResult, float &SettingValue); + + + // Make a literal session custom information key/value pair from Byte (For Enums) + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionPropertyKeyPair MakeLiteralSessionPropertyByte(FName Key, uint8 Value); + + // Make a literal session custom information key/value pair from Bool + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionPropertyKeyPair MakeLiteralSessionPropertyBool(FName Key, bool Value); + + // Make a literal session custom information key/value pair from String + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionPropertyKeyPair MakeLiteralSessionPropertyString(FName Key, FString Value); + + // Make a literal session custom information key/value pair from Int + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionPropertyKeyPair MakeLiteralSessionPropertyInt(FName Key, int32 Value); + + // Make a literal session custom information key/value pair from Float + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals") + static FSessionPropertyKeyPair MakeLiteralSessionPropertyFloat(FName Key, float Value); + + + //******* Player ID functions *********// + + // Get the unique net id of a network player attached to the given controller + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerID") + static void GetUniqueNetID(APlayerController *PlayerController, FBPUniqueNetId &UniqueNetId); + + // Check if a UniqueNetId is a friend + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|UniqueNetId") + static void UniqueNetIdToString(const FBPUniqueNetId &UniqueNetId, FString &String); + + //******** Player Name Functions **********// + + // Get the player name of a network player attached to the given controller + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerName") + static void GetPlayerName(APlayerController *PlayerController, FString &PlayerName); + + // Set the player name of a network player attached to the given controller + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|PlayerInfo|PlayerName") + static void SetPlayerName(APlayerController *PlayerController, FString PlayerName); + + //********** Misc Player Info Functions *********// + + // Get the number of network players + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|Misc") + static void GetNumberOfNetworkPlayers(int32 &NumNetPlayers); + + // Get the network player index of the given controller + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|Misc") + static void GetNetPlayerIndex(APlayerController *PlayerController, int32 &NetPlayerIndex); + + // Checks if the stated session subsystem is active + UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|Misc") + static bool HasOnlineSubsystem(FName SubSystemName); + + +}; diff --git a/Source/AdvancedSessions/Classes/AdvancedVoiceLibrary.h b/Source/AdvancedSessions/Classes/AdvancedVoiceLibrary.h new file mode 100644 index 0000000..76d37bc --- /dev/null +++ b/Source/AdvancedSessions/Classes/AdvancedVoiceLibrary.h @@ -0,0 +1,96 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once +#include "OnlineSubSystemHeader.h" +#include "Kismet/BlueprintFunctionLibrary.h" +#include "Online.h" +#include "OnlineSubsystem.h" +#include "VoiceInterface.h" +//#include "OnlineFriendsInterface.h" +//#include "OnlineUserInterface.h" +//#include "OnlineMessageInterface.h" +//#include "OnlinePresenceInterface.h" +#include "Engine/GameInstance.h" +//#include "OnlineSessionInterface.h" + +#include "UObjectIterator.h" + +#include "AdvancedVoiceLibrary.generated.h" + + +//General Advanced Sessions Log +DECLARE_LOG_CATEGORY_EXTERN(AdvancedVoiceLog, Log, All); + + +UCLASS() +class UAdvancedVoiceLibrary : public UBlueprintFunctionLibrary +{ + GENERATED_BODY() +public: + + //********* Voice Library Functions *************// + + // Get if a headset is present for the specified local user + UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo") + static void IsHeadsetPresent(bool & bHasHeadset, uint8 LocalPlayerNum = 0); + + // Starts networked voice, allows push to talk in coordination with StopNetworkedVoice + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice") + static void StartNetworkedVoice(uint8 LocalPlayerNum = 0); + + // Stops networked voice, allows push to talk in coordination with StartNetworkedVoice + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice") + static void StopNetworkedVoice(uint8 LocalPlayerNum = 0); + + // Registers a local player as someone interested in voice data + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice") + static bool RegisterLocalTalker(uint8 LocalPlayerNum = 0); + + // Registers all signed in players as local talkers + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice") + static void RegisterAllLocalTalkers(); + + // UnRegisters local player as a local talker + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice") + static void UnRegisterLocalTalker(uint8 LocalPlayerNum = 0); + + // UnRegisters all signed in players as local talkers + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice") + static void UnRegisterAllLocalTalkers(); + + // Registers a remote player as a talker + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice") + static bool RegisterRemoteTalker(const FBPUniqueNetId& UniqueNetId); + + // UnRegisters a remote player as a talker + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice") + static bool UnRegisterRemoteTalker(const FBPUniqueNetId& UniqueNetId); + + // UnRegisters all remote players as talkers + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice") + static void RemoveAllRemoteTalkers(); + + // Returns whether a local player is currently talking + UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo") + static bool IsLocalPlayerTalking(uint8 LocalPlayerNum); + + // Returns whether a remote player is currently talking + UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo") + static bool IsRemotePlayerTalking(const FBPUniqueNetId& UniqueNetId); + + // Returns whether a player is muted for the specified local player + UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo") + static bool IsPlayerMuted(uint8 LocalUserNumChecking, const FBPUniqueNetId& UniqueNetId); + + // Mutes the player associated with the uniquenetid for the specified local player, if IsSystemWide is true then it will attempt to mute globally for the player + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice") + static bool MuteRemoteTalker(uint8 LocalUserNum, const FBPUniqueNetId& UniqueNetId, bool bIsSystemWide = false); + + // UnMutes the player associated with the uniquenetid for the specified local player, if IsSystemWide is true then it will attempt to unmute globally for the player + UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice") + static bool UnMuteRemoteTalker(uint8 LocalUserNum, const FBPUniqueNetId& UniqueNetId, bool bIsSystemWide = false); + + // Gets the number of local talkers for this system + UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo") + static void GetNumLocalTalkers(int32 & NumLocalTalkers); +}; diff --git a/Source/AdvancedSessions/Classes/CancelFindSessionsCallbackProxy.h b/Source/AdvancedSessions/Classes/CancelFindSessionsCallbackProxy.h new file mode 100644 index 0000000..afabc6f --- /dev/null +++ b/Source/AdvancedSessions/Classes/CancelFindSessionsCallbackProxy.h @@ -0,0 +1,44 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "OnlineSessionInterface.h" +#include "CancelFindSessionsCallbackProxy.generated.h" + +UCLASS(MinimalAPI) +class UCancelFindSessionsCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when there is a successful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there is an unsuccessful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + // Cancels finding sessions + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedSessions") + static UCancelFindSessionsCallbackProxy* CancelFindSessions(UObject* WorldContextObject, class APlayerController* PlayerController); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when the operation completes, calls out to the public success/failure callbacks + void OnCompleted(bool bWasSuccessful); + +private: + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The delegate executed by the online subsystem + FOnCancelFindSessionsCompleteDelegate Delegate; + + // Handle to the registered OnDestroySessionComplete delegate + FDelegateHandle DelegateHandle; + + // The world context object in which this call is taking place + UObject* WorldContextObject; +}; diff --git a/Source/AdvancedSessions/Classes/CreateSessionCallbackProxyAdvanced.h b/Source/AdvancedSessions/Classes/CreateSessionCallbackProxyAdvanced.h new file mode 100644 index 0000000..944b5c5 --- /dev/null +++ b/Source/AdvancedSessions/Classes/CreateSessionCallbackProxyAdvanced.h @@ -0,0 +1,67 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "OnlineSubSystemHeader.h" + +#include "CreateSessionCallbackProxyAdvanced.generated.h" + +UCLASS(MinimalAPI) +class UCreateSessionCallbackProxyAdvanced : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the session was created successfully + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there was an error creating the session + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + // Creates a session with the default online subsystem with advanced optional inputs + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject",AutoCreateRefTerm="ExtraSettings"), Category = "Online|AdvancedSessions") + static UCreateSessionCallbackProxyAdvanced* CreateAdvancedSession(UObject* WorldContextObject, const TArray &ExtraSettings, class APlayerController* PlayerController = NULL, int32 PublicConnections = 100, bool bUseLAN = false, bool bAllowInvites = true, bool bIsDedicatedServer = false); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when session creation completes, calls StartSession + void OnCreateCompleted(FName SessionName, bool bWasSuccessful); + + // Internal callback when session creation completes, calls StartSession + void OnStartCompleted(FName SessionName, bool bWasSuccessful); + + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The delegate executed by the online subsystem + FOnCreateSessionCompleteDelegate CreateCompleteDelegate; + + // The delegate executed by the online subsystem + FOnStartSessionCompleteDelegate StartCompleteDelegate; + + // Handles to the registered delegates above + FDelegateHandle CreateCompleteDelegateHandle; + FDelegateHandle StartCompleteDelegateHandle; + + // Number of public connections + int NumPublicConnections; + + // Whether or not to search LAN + bool bUseLAN; + + // Whether or not to allow invites + bool bAllowInvites; + + // Whether this is a dedicated server or not + bool bDedicatedServer; + + // Store extra settings + TArray ExtraSettings; + + // The world context object in which this call is taking place + UObject* WorldContextObject; +}; + diff --git a/Source/AdvancedSessions/Classes/EndSessionCallbackProxy.h b/Source/AdvancedSessions/Classes/EndSessionCallbackProxy.h new file mode 100644 index 0000000..b9b6ece --- /dev/null +++ b/Source/AdvancedSessions/Classes/EndSessionCallbackProxy.h @@ -0,0 +1,44 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "OnlineSessionInterface.h" +#include "EndSessionCallbackProxy.generated.h" + +UCLASS(MinimalAPI) +class UEndSessionCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when there is a successful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there is an unsuccessful destroy + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + // Ends the current session + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedSessions") + static UEndSessionCallbackProxy* EndSession(UObject* WorldContextObject, class APlayerController* PlayerController); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when the operation completes, calls out to the public success/failure callbacks + void OnCompleted(FName SessionName, bool bWasSuccessful); + +private: + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The delegate executed by the online subsystem + FOnEndSessionCompleteDelegate Delegate; + + // Handle to the registered OnDestroySessionComplete delegate + FDelegateHandle DelegateHandle; + + // The world context object in which this call is taking place + UObject* WorldContextObject; +}; diff --git a/Source/AdvancedSessions/Classes/FindFriendSessionCallbackProxy.h b/Source/AdvancedSessions/Classes/FindFriendSessionCallbackProxy.h new file mode 100644 index 0000000..ccca32f --- /dev/null +++ b/Source/AdvancedSessions/Classes/FindFriendSessionCallbackProxy.h @@ -0,0 +1,50 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "OnlineSubSystemHeader.h" + +#include "FindFriendSessionCallbackProxy.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(AdvancedFindFriendSessionLog, Log, All); + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintFindFriendSessionDelegate, const FBlueprintSessionResult&, SessionInfo); + +UCLASS(MinimalAPI) +class UFindFriendSessionCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the friends list successfully was retrieved + UPROPERTY(BlueprintAssignable) + FBlueprintFindFriendSessionDelegate OnSuccess; + + // Called when there was an error retrieving the friends list + UPROPERTY(BlueprintAssignable) + FBlueprintFindFriendSessionDelegate OnFailure; + + // Attempts to get the current session that a friend is in + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedFriends") + static UFindFriendSessionCallbackProxy* FindFriendSession(UObject* WorldContextObject, APlayerController *PlayerController, const FBPUniqueNetId &FriendUniqueNetId); + + virtual void Activate() override; + +private: + // Internal callback when the friends list is retrieved + void OnFindFriendSessionCompleted(int32 LocalPlayer, bool bWasSuccessful, const FOnlineSessionSearchResult& SessionInfo); + + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The UniqueNetID of the person to invite + FBPUniqueNetId cUniqueNetId; + + // The delegate to call on completion + FOnFindFriendSessionCompleteDelegate OnFindFriendSessionCompleteDelegate; + + // Handles to the registered delegates above + FDelegateHandle FindFriendSessionCompleteDelegateHandle; + + // The world context object in which this call is taking place + UObject* WorldContextObject; +}; + diff --git a/Source/AdvancedSessions/Classes/FindSessionsCallbackProxyAdvanced.h b/Source/AdvancedSessions/Classes/FindSessionsCallbackProxyAdvanced.h new file mode 100644 index 0000000..09c914c --- /dev/null +++ b/Source/AdvancedSessions/Classes/FindSessionsCallbackProxyAdvanced.h @@ -0,0 +1,78 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "OnlineSessionInterface.h" +#include "OnlineSubSystemHeader.h" +#include "FindSessionsCallbackProxy.h" +#include "FindSessionsCallbackProxyAdvanced.generated.h" + +UCLASS(MinimalAPI) +class UFindSessionsCallbackProxyAdvanced : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when there is a successful query + UPROPERTY(BlueprintAssignable) + FBlueprintFindSessionsResultDelegate OnSuccess; + + // Called when there is an unsuccessful query + UPROPERTY(BlueprintAssignable) + FBlueprintFindSessionsResultDelegate OnFailure; + + // Searches for advertised sessions with the default online subsystem and includes an array of filters + UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject", AutoCreateRefTerm="Filters"), Category = "Online|AdvancedSessions") + static UFindSessionsCallbackProxyAdvanced* FindSessionsAdvanced(UObject* WorldContextObject, class APlayerController* PlayerController, int32 MaxResults, bool bUseLAN, const TArray &Filters); + + static bool CompareVariants(const FVariantData &A, const FVariantData &B, EOnlineComparisonOpRedux::Type Comparator); + + // Filters an array of session results by the given search parameters, returns a new array with the filtered results + UFUNCTION(BluePrintCallable, meta = (Category = "Online|AdvancedSessions")) + static void FilterSessionResults(const TArray &SessionResults, const TArray &Filters, TArray &FilteredResults); + + // Removed, the default built in versions work fine in the normal FindSessionsCallbackProxy + /*UFUNCTION(BlueprintPure, Category = "Online|Session") + static int32 GetPingInMs(const FBlueprintSessionResult& Result); + + UFUNCTION(BlueprintPure, Category = "Online|Session") + static FString GetServerName(const FBlueprintSessionResult& Result); + + UFUNCTION(BlueprintPure, Category = "Online|Session") + static int32 GetCurrentPlayers(const FBlueprintSessionResult& Result); + + UFUNCTION(BlueprintPure, Category = "Online|Session") + static int32 GetMaxPlayers(const FBlueprintSessionResult& Result);*/ + + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when the session search completes, calls out to the public success/failure callbacks + void OnCompleted(bool bSuccess); + +private: + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The delegate executed by the online subsystem + FOnFindSessionsCompleteDelegate Delegate; + + // Handle to the registered OnFindSessionsComplete delegate + FDelegateHandle DelegateHandle; + + // Object to track search results + TSharedPtr SearchObject; + + // Whether or not to search LAN + bool bUseLAN; + + // Maximum number of results to return + int MaxResults; + + // Store extra settings + TArray SearchSettings; + + // The world context object in which this call is taking place + UObject* WorldContextObject; +}; diff --git a/Source/AdvancedSessions/Classes/GetFriendsCallbackProxy.h b/Source/AdvancedSessions/Classes/GetFriendsCallbackProxy.h new file mode 100644 index 0000000..1dfadbf --- /dev/null +++ b/Source/AdvancedSessions/Classes/GetFriendsCallbackProxy.h @@ -0,0 +1,48 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "OnlineSubSystemHeader.h" + +#include "GetFriendsCallbackProxy.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(AdvancedGetFriendsLog, Log, All); + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintGetFriendsListDelegate, const TArray&, Results); + +UCLASS(MinimalAPI) +class UGetFriendsCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the friends list successfully was retrieved + UPROPERTY(BlueprintAssignable) + FBlueprintGetFriendsListDelegate OnSuccess; + + // Called when there was an error retrieving the friends list + UPROPERTY(BlueprintAssignable) + FBlueprintGetFriendsListDelegate OnFailure; + + // Gets the players list of friends from the OnlineSubsystem and returns it, can be retrieved later with GetStoredFriendsList + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedFriends") + static UGetFriendsCallbackProxy* GetAndStoreFriendsList(UObject* WorldContextObject, class APlayerController* PlayerController); + + virtual void Activate() override; + +private: + // Internal callback when the friends list is retrieved + void OnReadFriendsListCompleted(int32 LocalUserNum, bool bWasSuccessful, const FString& ListName, const FString& ErrorString); + + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The delegate executed + FOnReadFriendsListComplete FriendListReadCompleteDelegate; + + // The Type of friends list to get + // Removed because all but the facebook interfaces don't even currently support anything but the default friends list. + //EBPFriendsLists::Type FriendListToGet; + + // The world context object in which this call is taking place + UObject* WorldContextObject; +}; + diff --git a/Source/AdvancedSessions/Classes/GetRecentPlayersCallbackProxy.h b/Source/AdvancedSessions/Classes/GetRecentPlayersCallbackProxy.h new file mode 100644 index 0000000..aaa2897 --- /dev/null +++ b/Source/AdvancedSessions/Classes/GetRecentPlayersCallbackProxy.h @@ -0,0 +1,49 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "OnlineSubSystemHeader.h" + +#include "GetRecentPlayersCallbackProxy.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(AdvancedGetRecentPlayersLog, Log, All); + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintGetRecentPlayersDelegate, const TArray&, Results); + +UCLASS(MinimalAPI) +class UGetRecentPlayersCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the friends list successfully was retrieved + UPROPERTY(BlueprintAssignable) + FBlueprintGetRecentPlayersDelegate OnSuccess; + + // Called when there was an error retrieving the friends list + UPROPERTY(BlueprintAssignable) + FBlueprintGetRecentPlayersDelegate OnFailure; + + // Gets the list of recent players from the OnlineSubsystem and returns it, can be retrieved later with GetStoredRecentPlayersList, can fail if no recent players are found + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedFriends") + static UGetRecentPlayersCallbackProxy* GetAndStoreRecentPlayersList(UObject* WorldContextObject, const FBPUniqueNetId &UniqueNetId); + + virtual void Activate() override; + +private: + // Internal callback when the friends list is retrieved + void OnQueryRecentPlayersCompleted(const FUniqueNetId &UserID, const FString &Namespace, bool bWasSuccessful, const FString& ErrorString); + // Handle to the registered OnFindSessionsComplete delegate + FDelegateHandle DelegateHandle; + + // The player controller triggering things + //TWeakObjectPtr PlayerControllerWeakPtr; + + // The UniqueNetID of the person to get recent players for + FBPUniqueNetId cUniqueNetId; + + // The delegate executed + FOnQueryRecentPlayersCompleteDelegate QueryRecentPlayersCompleteDelegate; + + // The world context object in which this call is taking place + UObject* WorldContextObject; +}; + diff --git a/Source/AdvancedSessions/Classes/SendFriendInviteCallbackProxy.h b/Source/AdvancedSessions/Classes/SendFriendInviteCallbackProxy.h new file mode 100644 index 0000000..323de53 --- /dev/null +++ b/Source/AdvancedSessions/Classes/SendFriendInviteCallbackProxy.h @@ -0,0 +1,48 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "OnlineSubSystemHeader.h" + +#include "SendFriendInviteCallbackProxy.generated.h" + +DECLARE_LOG_CATEGORY_EXTERN(AdvancedSendFriendInviteLog, Log, All); + +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBlueprintSendFriendInviteDelegate); + +UCLASS(MinimalAPI) +class USendFriendInviteCallbackProxy : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the friends list successfully was retrieved + UPROPERTY(BlueprintAssignable) + FBlueprintSendFriendInviteDelegate OnSuccess; + + // Called when there was an error retrieving the friends list + UPROPERTY(BlueprintAssignable) + FBlueprintSendFriendInviteDelegate OnFailure; + + // Adds a friend who is using the defined UniqueNetId, some interfaces do now allow this function to be called (INCLUDING STEAM) + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedFriends") + static USendFriendInviteCallbackProxy* SendFriendInvite(UObject* WorldContextObject, APlayerController *PlayerController, const FBPUniqueNetId &UniqueNetIDInvited); + + virtual void Activate() override; + +private: + // Internal callback when the friends list is retrieved + void OnSendInviteComplete(int32 LocalPlayerNum, bool bWasSuccessful, const FUniqueNetId &InvitedPlayer, const FString &ListName, const FString &ErrorString); + + + // The player controller triggering things + TWeakObjectPtr PlayerControllerWeakPtr; + + // The UniqueNetID of the person to invite + FBPUniqueNetId cUniqueNetId; + + // The delegate to call on completion + FOnSendInviteComplete OnSendInviteCompleteDelegate; + + // The world context object in which this call is taking place + UObject* WorldContextObject; +}; + diff --git a/Source/AdvancedSessions/Classes/UpdateSessionCallbackProxyAdvanced.h b/Source/AdvancedSessions/Classes/UpdateSessionCallbackProxyAdvanced.h new file mode 100644 index 0000000..e447b80 --- /dev/null +++ b/Source/AdvancedSessions/Classes/UpdateSessionCallbackProxyAdvanced.h @@ -0,0 +1,63 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#pragma once + +#include "OnlineSubSystemHeader.h" + +#include "UpdateSessionCallbackProxyAdvanced.generated.h" + +UCLASS(MinimalAPI) +class UUpdateSessionCallbackProxyAdvanced : public UOnlineBlueprintCallProxyBase +{ + GENERATED_UCLASS_BODY() + + // Called when the session was updated successfully + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnSuccess; + + // Called when there was an error updating the session + UPROPERTY(BlueprintAssignable) + FEmptyOnlineDelegate OnFailure; + + // Creates a session with the default online subsystem with advanced optional inputs + UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject",AutoCreateRefTerm="ExtraSettings"), Category = "Online|AdvancedSessions") + static UUpdateSessionCallbackProxyAdvanced* UpdateSession(UObject* WorldContextObject, int32 PublicConnections, bool bUseLAN, bool bAllowInvites, bool bAllowJoinInProgress, const TArray &ExtraSettings, bool bRefreshOnlineData = true, bool bIsDedicatedServer = false); + + // UOnlineBlueprintCallProxyBase interface + virtual void Activate() override; + // End of UOnlineBlueprintCallProxyBase interface + +private: + // Internal callback when session creation completes, calls StartSession + void OnUpdateCompleted(FName SessionName, bool bWasSuccessful); + + // The delegate executed by the online subsystem + FOnUpdateSessionCompleteDelegate OnUpdateSessionCompleteDelegate; + + // Handles to the registered delegates above + FDelegateHandle OnUpdateSessionCompleteDelegateHandle; + + // Number of public connections + int NumPublicConnections; + + // Whether or not to search LAN + bool bUseLAN; + + // Whether or not to allow invites + bool bAllowInvites; + + // Store extra settings + TArray ExtraSettings; + + // Whether to update the online data + bool bRefreshOnlineData; + + // Allow joining in progress + bool bAllowJoinInProgress; + + // Update whether this is a dedicated server or not + bool bDedicatedServer; + + // The world context object in which this call is taking place + UObject* WorldContextObject; +}; + diff --git a/Source/AdvancedSessions/Private/AdvancedFriendsGameInstance.cpp b/Source/AdvancedSessions/Private/AdvancedFriendsGameInstance.cpp new file mode 100644 index 0000000..8d632a2 --- /dev/null +++ b/Source/AdvancedSessions/Private/AdvancedFriendsGameInstance.cpp @@ -0,0 +1,196 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "OnlineSubSystemHeader.h" +#include "AdvancedFriendsGameInstance.h" + +//General Log +DEFINE_LOG_CATEGORY(AdvancedFriendsInterfaceLog); + +UAdvancedFriendsGameInstance::UAdvancedFriendsGameInstance(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , SessionInviteAcceptedDelegate(FOnSessionUserInviteAcceptedDelegate::CreateUObject(this, &ThisClass::OnSessionInviteAcceptedMaster)) + , bCallFriendInterfaceEventsOnPlayerControllers(true) + , PlayerTalkingStateChangedDelegate(FOnPlayerTalkingStateChangedDelegate::CreateUObject(this, &ThisClass::OnPlayerTalkingStateChangedMaster)) + , bEnableTalkingStatusDelegate(true) + , bCallVoiceInterfaceEventsOnPlayerControllers(true) +{ +} + +void UAdvancedFriendsGameInstance::Shutdown() +{ + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(); + + if (!SessionInterface.IsValid()) + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsGameInstance Failed to get session system!")); + //return; + } + else + { + // Clear all of the delegate handles here + SessionInterface->ClearOnSessionUserInviteAcceptedDelegate_Handle(SessionInviteAcceptedDelegateHandle); + + } + + + if (bEnableTalkingStatusDelegate) + { + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (VoiceInterface.IsValid()) + { + VoiceInterface->ClearOnPlayerTalkingStateChangedDelegate_Handle(PlayerTalkingStateChangedDelegateHandle); + } + else + { + + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get voice interface!")); + } + } + + Super::Shutdown(); +} + +void UAdvancedFriendsGameInstance::Init() +{ + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface();//OnlineSub->GetSessionInterface(); + + if (SessionInterface.IsValid()) + { + // Currently doesn't store a handle or assign a delegate to any local player beyond the first.....should handle? + // Thought about directly handling it but friends for multiple players probably isn't required + // Iterating through the local player TArray only works if it has had players assigned to it, most of the online interfaces don't support + // Multiple logins either (IE: Steam) + SessionInviteAcceptedDelegateHandle = SessionInterface->AddOnSessionUserInviteAcceptedDelegate_Handle(SessionInviteAcceptedDelegate); + + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get session interface!")); + //return; + } + + // Beginning work on the voice interface + if (bEnableTalkingStatusDelegate) + { + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (VoiceInterface.IsValid()) + { + PlayerTalkingStateChangedDelegateHandle = VoiceInterface->AddOnPlayerTalkingStateChangedDelegate_Handle(PlayerTalkingStateChangedDelegate); + } + else + { + + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get voice interface!")); + } + } + + Super::Init(); +} + +/*void UAdvancedFriendsGameInstance::PostLoad() +{ + Super::PostLoad(); +}*/ + + +// Removed because it never gets called by the online subsystems +/*void UAdvancedFriendsGameInstance::OnSessionInviteReceivedMaster(const FUniqueNetId &InvitedPlayer, const FUniqueNetId &FriendInviting, const FOnlineSessionSearchResult& Session) +{ + // Just call the blueprint event to let the user handle this + + FBPUniqueNetId IP, FI; + + IP.SetUniqueNetId(&InvitedPlayer); + + FI.SetUniqueNetId(&FriendInviting); + + FBlueprintSessionResult BPS; + BPS.OnlineResult = Session; + OnSessionInviteReceived(IP,FI,BPS); + + TArray& PlayerArray = GetWorld()->GetGameState()->PlayerArray; + const TArray&ControllerArray = this->GetLocalPlayers(); + + for (int i = 0; i < ControllerArray.Num(); i++) + { + if (*PlayerArray[ControllerArray[i]->PlayerController->NetPlayerIndex]->UniqueId.GetUniqueNetId().Get() == InvitedPlayer) + { + //Run the Event specific to the actor, if the actor has the interface, otherwise ignore + if (ControllerArray[i]->PlayerController->GetClass()->ImplementsInterface(UAdvancedFriendsInterface::StaticClass())) + { + IAdvancedFriendsInterface::Execute_OnSessionInviteReceived(ControllerArray[i]->PlayerController, FI, BPS); + } + break; + } + } +}*/ + +void UAdvancedFriendsGameInstance::OnPlayerTalkingStateChangedMaster(TSharedRef PlayerId, bool bIsTalking) +{ + FBPUniqueNetId PlayerTalking; + PlayerTalking.SetUniqueNetId(PlayerId); + OnPlayerTalkingStateChanged(PlayerTalking, bIsTalking); + + if (bCallVoiceInterfaceEventsOnPlayerControllers) + { + APlayerController* Player = NULL; + + for (const ULocalPlayer* LPlayer : LocalPlayers) + { + Player = UGameplayStatics::GetPlayerController(GetWorld(), LPlayer->GetControllerId()); + + if (Player != NULL) + { + //Run the Event specific to the actor, if the actor has the interface, otherwise ignore + if (Player->GetClass()->ImplementsInterface(UAdvancedFriendsInterface::StaticClass())) + { + IAdvancedFriendsInterface::Execute_OnPlayerVoiceStateChanged(Player, PlayerTalking, bIsTalking); + } + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get a controller with the specified index in OnVoiceStateChanged!")); + } + } + } +} + +void UAdvancedFriendsGameInstance::OnSessionInviteAcceptedMaster(const bool bWasSuccessful, int32 LocalPlayer, TSharedPtr PersonInviting, const FOnlineSessionSearchResult& SessionToJoin) +{ + if (bWasSuccessful) + { + if (SessionToJoin.IsValid()) + { + + FBlueprintSessionResult BluePrintResult; + BluePrintResult.OnlineResult = SessionToJoin; + + FBPUniqueNetId PInviting; + PInviting.SetUniqueNetId(PersonInviting); + + OnSessionInviteAccepted(LocalPlayer,PInviting, BluePrintResult); + + APlayerController* Player = UGameplayStatics::GetPlayerController(GetWorld(), LocalPlayer); + + IAdvancedFriendsInterface* TheInterface = NULL; + + if (Player != NULL) + { + //Run the Event specific to the actor, if the actor has the interface, otherwise ignore + if (Player->GetClass()->ImplementsInterface(UAdvancedFriendsInterface::StaticClass())) + { + IAdvancedFriendsInterface::Execute_OnSessionInviteAccepted(Player,PInviting, BluePrintResult); + } + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get a controller with the specified index in OnSessionInviteAccepted!")); + } + } + else + { + UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Return a bad search result in OnSessionInviteAccepted!")); + } + } +} \ No newline at end of file diff --git a/Source/AdvancedSessions/Private/AdvancedFriendsInterface.cpp b/Source/AdvancedSessions/Private/AdvancedFriendsInterface.cpp new file mode 100644 index 0000000..0468aa1 --- /dev/null +++ b/Source/AdvancedSessions/Private/AdvancedFriendsInterface.cpp @@ -0,0 +1,9 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "OnlineSubSystemHeader.h" +#include "AdvancedFriendsInterface.h" + + +UAdvancedFriendsInterface::UAdvancedFriendsInterface(const class FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) +{ +} diff --git a/Source/AdvancedSessions/Private/AdvancedFriendsLibrary.cpp b/Source/AdvancedSessions/Private/AdvancedFriendsLibrary.cpp new file mode 100644 index 0000000..1ed58ba --- /dev/null +++ b/Source/AdvancedSessions/Private/AdvancedFriendsLibrary.cpp @@ -0,0 +1,251 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "OnlineSubSystemHeader.h" +#include "AdvancedFriendsLibrary.h" + +//General Log +DEFINE_LOG_CATEGORY(AdvancedFriendsLog); + +void UAdvancedFriendsLibrary::SendSessionInviteToFriends(APlayerController *PlayerController, const TArray &Friends, TEnumAsByte &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(PlayerController->Player); + + if (!Player) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend failed to get LocalPlayer!")); + Result = EBlueprintResultSwitch::Type::OnFailure; + return; + } + + TArray> List; + for (int i = 0; i < Friends.Num(); i++) + { + TSharedRef val(Friends[i].UniqueNetId.ToSharedRef()); + //TSharedRef 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::SendSessionInviteToFriend(APlayerController *PlayerController, const FBPUniqueNetId &FriendUniqueNetId, TEnumAsByte &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(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 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(PlayerController->Player); + + if (!Player) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriend failed to get LocalPlayer!")); + return; + } + + TSharedPtr 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 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(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 UAdvancedFriendsLibrary::GetStoredRecentPlayersList(FBPUniqueNetId UniqueNetId, TArray &PlayersList) +{ + IOnlineFriendsPtr FriendsInterface = Online::GetFriendsInterface(); + + if (!FriendsInterface.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetRecentPlayersList Failed to get friends interface!")); + return; + } + + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetRecentPlayersList Failed was given an invalid UniqueNetId!")); + return; + } + + TArray< TSharedRef > PlayerList; + + // For now getting all namespaces + FriendsInterface->GetRecentPlayers(*(UniqueNetId.GetUniqueNetId()),"", PlayerList); + + for (int32 i = 0; i < PlayerList.Num(); i++) + { + TSharedRef Player = PlayerList[i]; + FBPOnlineRecentPlayer BPF; + BPF.DisplayName = Player->GetDisplayName(); + BPF.RealName = Player->GetRealName(); + BPF.UniqueNetId.SetUniqueNetId(Player->GetUserId()); + PlayersList.Add(BPF); + } +} + +void UAdvancedFriendsLibrary::GetStoredFriendsList(APlayerController *PlayerController, TArray &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(PlayerController->Player); + + if (!Player) + { + UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriendsList Failed to get LocalPlayer!")); + return; + } + + + TArray< TSharedRef > FriendList; + FriendsInterface->GetFriendsList(Player->GetControllerId(), EFriendsLists::ToString((EFriendsLists::Type::Default)), FriendList); + + for (int32 i = 0; i < FriendList.Num(); i++) + { + TSharedRef 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()); + FriendsList.Add(BPF); + } +} \ No newline at end of file diff --git a/Source/AdvancedSessions/Private/AdvancedSessions.cpp b/Source/AdvancedSessions/Private/AdvancedSessions.cpp new file mode 100644 index 0000000..e6630a8 --- /dev/null +++ b/Source/AdvancedSessions/Private/AdvancedSessions.cpp @@ -0,0 +1,13 @@ +//#include "StandAlonePrivatePCH.h" +#include "OnlineSubSystemHeader.h" +#include "AdvancedSessions.h" + +void AdvancedSessions::StartupModule() +{ +} + +void AdvancedSessions::ShutdownModule() +{ +} + +IMPLEMENT_MODULE(AdvancedSessions, AdvancedSessions) \ No newline at end of file diff --git a/Source/AdvancedSessions/Private/AdvancedSessions.h b/Source/AdvancedSessions/Private/AdvancedSessions.h new file mode 100644 index 0000000..c2cbeec --- /dev/null +++ b/Source/AdvancedSessions/Private/AdvancedSessions.h @@ -0,0 +1,12 @@ +#pragma once + +#include "OnlineSubSystemHeader.h" +#include "ModuleManager.h" + +class AdvancedSessions : public IModuleInterface +{ +public: + /** IModuleInterface implementation */ + void StartupModule(); + void ShutdownModule(); +}; \ No newline at end of file diff --git a/Source/AdvancedSessions/Private/AdvancedSessionsLibrary.cpp b/Source/AdvancedSessions/Private/AdvancedSessionsLibrary.cpp new file mode 100644 index 0000000..be629bf --- /dev/null +++ b/Source/AdvancedSessions/Private/AdvancedSessionsLibrary.cpp @@ -0,0 +1,397 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "OnlineSubSystemHeader.h" +#include "AdvancedSessionsLibrary.h" + +//General Log +DEFINE_LOG_CATEGORY(AdvancedSessionsLog); + +void UAdvancedSessionsLibrary::GetCurrentUniqueBuildID(int32 &UniqueBuildId) +{ + UniqueBuildId = GetBuildUniqueId(); +} + +void UAdvancedSessionsLibrary::GetUniqueBuildID(FBlueprintSessionResult SessionResult, int32 &UniqueBuildId) +{ + UniqueBuildId = SessionResult.OnlineResult.Session.SessionSettings.BuildUniqueId; +} + +void UAdvancedSessionsLibrary::AddOrModifyExtraSettings(const TArray & SettingsArray, const TArray & NewOrChangedSettings, TArray & ModifiedSettingsArray) +{ + ModifiedSettingsArray = SettingsArray; + + bool bFoundSetting = false; + // For each new setting + for (const FSessionPropertyKeyPair& Setting : NewOrChangedSettings) + { + bFoundSetting = false; + + for (FSessionPropertyKeyPair itr : ModifiedSettingsArray) + { + // Manually comparing the keys + if (itr.Key == Setting.Key) + { + bFoundSetting = true; + itr.Data = Setting.Data; + } + } + + // If it was not found, add to the array instead + if (!bFoundSetting) + { + ModifiedSettingsArray.Add(Setting); + } + } + +} + +void UAdvancedSessionsLibrary::GetExtraSettings(FBlueprintSessionResult SessionResult, TArray & ExtraSettings) +{ + FSessionPropertyKeyPair NewSetting; + for (auto& Elem : SessionResult.OnlineResult.Session.SessionSettings.Settings) + { + NewSetting.Key = Elem.Key; + NewSetting.Data = Elem.Value.Data; + ExtraSettings.Add(NewSetting); + } +} + +void UAdvancedSessionsLibrary::GetSessionState(TEnumAsByte &SessionState) +{ + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(); + + if (!SessionInterface.IsValid()) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetSessionState couldn't get the session interface!")); + return; + } + + SessionState = ((EBPOnlineSessionState::Type)SessionInterface->GetSessionState(GameSessionName)); +} + +void UAdvancedSessionsLibrary::GetSessionSettings(int32 &NumConnections, bool &bIsLAN, bool &bIsDedicated, bool &bIsAnticheatEnabled, int32 &BuildUniqueID, TArray &ExtraSettings, TEnumAsByte &Result) +{ + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(); + + if (!SessionInterface.IsValid()) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetSessionSettings couldn't get the session interface!")); + Result = EBlueprintResultSwitch::Type::OnFailure; + return; + } + + FOnlineSessionSettings* settings = SessionInterface->GetSessionSettings(GameSessionName); + if (!settings) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetSessionSettings couldn't get the session settings!")); + Result = EBlueprintResultSwitch::Type::OnFailure; + return; + } + BuildUniqueID = settings->BuildUniqueId; + NumConnections = settings->NumPublicConnections; + bIsLAN = settings->bIsLANMatch; + bIsDedicated = settings->bIsDedicated; + bIsAnticheatEnabled = settings->bAntiCheatProtected; + + FSessionPropertyKeyPair NewSetting; + + for (auto& Elem : settings->Settings) + { + NewSetting.Key = Elem.Key; + NewSetting.Data = Elem.Value.Data; + ExtraSettings.Add(NewSetting); + } + + Result = EBlueprintResultSwitch::Type::OnSuccess; +} + +void UAdvancedSessionsLibrary::IsPlayerInSession(const FBPUniqueNetId &PlayerToCheck, bool &bIsInSession) +{ + IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(); + + if (!SessionInterface.IsValid()) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("IsPlayerInSession couldn't get the session interface!")); + bIsInSession = false; + return; + } + + bIsInSession = SessionInterface->IsPlayerInSession(GameSessionName, *PlayerToCheck.GetUniqueNetId()); +} + +FSessionsSearchSetting UAdvancedSessionsLibrary::MakeLiteralSessionSearchProperty(FSessionPropertyKeyPair SessionSearchProperty, EOnlineComparisonOpRedux::Type ComparisonOp) +{ + FSessionsSearchSetting setting; + setting.PropertyKeyPair = SessionSearchProperty; + setting.ComparisonOp = ComparisonOp; + + return setting; +} + +FSessionPropertyKeyPair UAdvancedSessionsLibrary::MakeLiteralSessionPropertyByte(FName Key, uint8 Value) +{ + FSessionPropertyKeyPair Prop; + Prop.Key = Key; + Prop.Data.SetValue((int32)Value); + return Prop; +} + +FSessionPropertyKeyPair UAdvancedSessionsLibrary::MakeLiteralSessionPropertyBool(FName Key, bool Value) +{ + FSessionPropertyKeyPair Prop; + Prop.Key = Key; + Prop.Data.SetValue(Value); + return Prop; +} + +FSessionPropertyKeyPair UAdvancedSessionsLibrary::MakeLiteralSessionPropertyString(FName Key, FString Value) +{ + FSessionPropertyKeyPair Prop; + Prop.Key = Key; + Prop.Data.SetValue(Value); + return Prop; +} + +FSessionPropertyKeyPair UAdvancedSessionsLibrary::MakeLiteralSessionPropertyInt(FName Key, int32 Value) +{ + FSessionPropertyKeyPair Prop; + Prop.Key = Key; + Prop.Data.SetValue(Value); + return Prop; +} + +FSessionPropertyKeyPair UAdvancedSessionsLibrary::MakeLiteralSessionPropertyFloat(FName Key, float Value) +{ + FSessionPropertyKeyPair Prop; + Prop.Key = Key; + Prop.Data.SetValue(Value); + return Prop; +} + +void UAdvancedSessionsLibrary::GetSessionPropertyByte(const TArray & ExtraSettings, FName SettingName, TEnumAsByte &SearchResult, uint8 &SettingValue) +{ + for (FSessionPropertyKeyPair itr : ExtraSettings) + { + if (itr.Key == SettingName) + { + if (itr.Data.GetType() == EOnlineKeyValuePairDataType::Int32) + { + int32 Val; + itr.Data.GetValue(Val); + SettingValue = (uint8)(Val); + SearchResult = ESessionSettingSearchResult::Type::Found; + } + else + { + SearchResult = ESessionSettingSearchResult::Type::WrongType; + } + return; + } + } + + SearchResult = ESessionSettingSearchResult::Type::NotFound; + return; +} + +void UAdvancedSessionsLibrary::GetSessionPropertyBool(const TArray & ExtraSettings, FName SettingName, TEnumAsByte &SearchResult, bool &SettingValue) +{ + for (FSessionPropertyKeyPair itr : ExtraSettings) + { + if (itr.Key == SettingName) + { + if (itr.Data.GetType() == EOnlineKeyValuePairDataType::Bool) + { + itr.Data.GetValue(SettingValue); + SearchResult = ESessionSettingSearchResult::Type::Found; + } + else + { + SearchResult = ESessionSettingSearchResult::Type::WrongType; + } + return; + } + } + + SearchResult = ESessionSettingSearchResult::Type::NotFound; + return; +} + +void UAdvancedSessionsLibrary::GetSessionPropertyString(const TArray & ExtraSettings, FName SettingName, TEnumAsByte &SearchResult, FString &SettingValue) +{ + for (FSessionPropertyKeyPair itr : ExtraSettings) + { + if (itr.Key == SettingName) + { + if (itr.Data.GetType() == EOnlineKeyValuePairDataType::String) + { + itr.Data.GetValue(SettingValue); + SearchResult = ESessionSettingSearchResult::Type::Found; + } + else + { + SearchResult = ESessionSettingSearchResult::Type::WrongType; + } + return; + } + } + + SearchResult = ESessionSettingSearchResult::Type::NotFound; + return; +} + +void UAdvancedSessionsLibrary::GetSessionPropertyInt(const TArray & ExtraSettings, FName SettingName, TEnumAsByte &SearchResult, int32 &SettingValue) +{ + for (FSessionPropertyKeyPair itr : ExtraSettings) + { + if (itr.Key == SettingName) + { + if (itr.Data.GetType() == EOnlineKeyValuePairDataType::Int32) + { + itr.Data.GetValue(SettingValue); + SearchResult = ESessionSettingSearchResult::Type::Found; + } + else + { + SearchResult = ESessionSettingSearchResult::Type::WrongType; + } + return; + } + } + + SearchResult = ESessionSettingSearchResult::Type::NotFound; + return; +} + +void UAdvancedSessionsLibrary::GetSessionPropertyFloat(const TArray & ExtraSettings, FName SettingName, TEnumAsByte &SearchResult, float &SettingValue) +{ + for (FSessionPropertyKeyPair itr : ExtraSettings) + { + if (itr.Key == SettingName) + { + if (itr.Data.GetType() == EOnlineKeyValuePairDataType::Float) + { + itr.Data.GetValue(SettingValue); + SearchResult = ESessionSettingSearchResult::Type::Found; + } + else + { + SearchResult = ESessionSettingSearchResult::Type::WrongType; + } + return; + } + } + + SearchResult = ESessionSettingSearchResult::Type::NotFound; + return; +} + + +bool UAdvancedSessionsLibrary::HasOnlineSubsystem(FName SubSystemName) +{ + return((IOnlineSubsystem::Get(SubSystemName) != NULL)); +} + +void UAdvancedSessionsLibrary::GetNetPlayerIndex(APlayerController *PlayerController, int32 &NetPlayerIndex) +{ + if (!PlayerController) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetNetPlayerIndex received a bad PlayerController!")); + NetPlayerIndex = 0; + return; + } + + NetPlayerIndex = PlayerController->NetPlayerIndex; + return; +} + +void UAdvancedSessionsLibrary::UniqueNetIdToString(const FBPUniqueNetId& UniqueNetId, FString &String) +{ + const FUniqueNetId * ID = UniqueNetId.GetUniqueNetId(); + + if ( !ID ) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("UniqueNetIdToString received a bad UniqueNetId!")); + String = "ERROR, BAD UNIQUE NET ID"; + } + + String = ID->ToString(); +} + + +void UAdvancedSessionsLibrary::GetUniqueNetID(APlayerController *PlayerController, FBPUniqueNetId &UniqueNetId) +{ + if (!PlayerController) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetUniqueNetIdFromController received a bad PlayerController!")); + return; + } + + if (APlayerState* PlayerState = (PlayerController != NULL) ? PlayerController->PlayerState : NULL) + { + UniqueNetId.SetUniqueNetId(PlayerState->UniqueId.GetUniqueNetId()); + if (!UniqueNetId.IsValid()) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetUniqueNetIdFromController couldn't get the player uniquenetid!")); + } + return; + } +} + +void UAdvancedSessionsLibrary::SetPlayerName(APlayerController *PlayerController, FString PlayerName) +{ + if (!PlayerController) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("SetLocalPlayerNameFromController Bad Player Controller!")); + return; + } + + if (APlayerState* PlayerState = (PlayerController != NULL) ? PlayerController->PlayerState : NULL) + { + PlayerState->SetPlayerName(PlayerName); + return; + } + else + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("SetLocalPlayerNameFromController had a bad player state!")); + } +} + +void UAdvancedSessionsLibrary::GetPlayerName(APlayerController *PlayerController, FString &PlayerName) +{ + if (!PlayerController) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetLocalPlayerNameFromController Bad Player Controller!")); + return; + } + + if (APlayerState* PlayerState = (PlayerController != NULL) ? PlayerController->PlayerState : NULL) + { + PlayerName = PlayerState->PlayerName; + return; + } + else + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetLocalPlayerNameFromController had a bad player state!")); + } +} + +void UAdvancedSessionsLibrary::GetNumberOfNetworkPlayers(int32 &NumNetPlayers) +{ + //Get an actor to GetWorld() from + TObjectIterator Itr; + if (!Itr) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetNumberOfNetworkPlayers Failed to get iterator!")); + return; + } + //~~~~~~~~~~~~ + + //Get World + UWorld* TheWorld = Itr->GetWorld(); + if (!TheWorld) + { + UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetNumberOfNetworkPlayers Failed to get World()!")); + return; + } + TArray& PlayerArray = (TheWorld->GetGameState()->PlayerArray); + NumNetPlayers = PlayerArray.Num(); +} diff --git a/Source/AdvancedSessions/Private/AdvancedVoiceLibrary.cpp b/Source/AdvancedSessions/Private/AdvancedVoiceLibrary.cpp new file mode 100644 index 0000000..fc1b7ea --- /dev/null +++ b/Source/AdvancedSessions/Private/AdvancedVoiceLibrary.cpp @@ -0,0 +1,218 @@ +// Fill out your copyright notice in the Description page of Project Settings. +#include "OnlineSubSystemHeader.h" +#include "AdvancedVoiceLibrary.h" + +//General Log +DEFINE_LOG_CATEGORY(AdvancedVoiceLog); + +void UAdvancedVoiceLibrary::IsHeadsetPresent(bool & bHasHeadset, uint8 LocalPlayerNum) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + bHasHeadset = false; + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Check For Headset couldn't get the voice interface!")); + return; + } + + bHasHeadset = VoiceInterface->IsHeadsetPresent(LocalPlayerNum); +} + +void UAdvancedVoiceLibrary::StartNetworkedVoice(uint8 LocalPlayerNum) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Start Networked Voice couldn't get the voice interface!")); + return; + } + + VoiceInterface->StartNetworkedVoice(LocalPlayerNum); +} + +void UAdvancedVoiceLibrary::StopNetworkedVoice(uint8 LocalPlayerNum) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Start Networked Voice couldn't get the voice interface!")); + return; + } + + VoiceInterface->StopNetworkedVoice(LocalPlayerNum); +} + +bool UAdvancedVoiceLibrary::RegisterLocalTalker(uint8 LocalPlayerNum) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Register Local Talker couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->RegisterLocalTalker(LocalPlayerNum); +} + +void UAdvancedVoiceLibrary::RegisterAllLocalTalkers() +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Register Local Talkers couldn't get the voice interface!")); + return; + } + + VoiceInterface->RegisterLocalTalkers(); +} + + +void UAdvancedVoiceLibrary::UnRegisterLocalTalker(uint8 LocalPlayerNum) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Unregister Local Talker couldn't get the voice interface!")); + return; + } + + VoiceInterface->UnregisterLocalTalker(LocalPlayerNum); +} + +void UAdvancedVoiceLibrary::UnRegisterAllLocalTalkers() +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("UnRegister All Local Talkers couldn't get the voice interface!")); + return; + } + + VoiceInterface->UnregisterLocalTalkers(); +} + +bool UAdvancedVoiceLibrary::RegisterRemoteTalker(const FBPUniqueNetId& UniqueNetId) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Register Remote Talker couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->RegisterRemoteTalker(*UniqueNetId.GetUniqueNetId()); +} + +bool UAdvancedVoiceLibrary::UnRegisterRemoteTalker(const FBPUniqueNetId& UniqueNetId) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("UnRegister Remote Talker couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->UnregisterRemoteTalker(*UniqueNetId.GetUniqueNetId()); +} + +void UAdvancedVoiceLibrary::RemoveAllRemoteTalkers() +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Remove All Remote Talkers couldn't get the voice interface!")); + return; + } + + VoiceInterface->RemoveAllRemoteTalkers(); +} + +bool UAdvancedVoiceLibrary::IsLocalPlayerTalking(uint8 LocalPlayerNum) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Is Local Player Talking couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->IsLocalPlayerTalking(LocalPlayerNum); +} + +bool UAdvancedVoiceLibrary::IsRemotePlayerTalking(const FBPUniqueNetId& UniqueNetId) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Is Remote Player Talking couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->IsRemotePlayerTalking(*UniqueNetId.GetUniqueNetId()); +} + +bool UAdvancedVoiceLibrary::IsPlayerMuted(uint8 LocalUserNumChecking, const FBPUniqueNetId& UniqueNetId) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Is Player Muted couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->IsMuted(LocalUserNumChecking, *UniqueNetId.GetUniqueNetId()); +} + +bool UAdvancedVoiceLibrary::MuteRemoteTalker(uint8 LocalUserNum, const FBPUniqueNetId& UniqueNetId, bool bIsSystemWide) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Mute Remote Talker couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->MuteRemoteTalker(LocalUserNum, *UniqueNetId.GetUniqueNetId(), bIsSystemWide); +} + +bool UAdvancedVoiceLibrary::UnMuteRemoteTalker(uint8 LocalUserNum, const FBPUniqueNetId& UniqueNetId, bool bIsSystemWide) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Unmute Remote Talker couldn't get the voice interface!")); + return false; + } + + return VoiceInterface->UnmuteRemoteTalker(LocalUserNum, *UniqueNetId.GetUniqueNetId(), bIsSystemWide); +} + + +void UAdvancedVoiceLibrary::GetNumLocalTalkers(int32 & NumLocalTalkers) +{ + IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(); + + if (!VoiceInterface.IsValid()) + { + NumLocalTalkers = 0; + UE_LOG(AdvancedVoiceLog, Warning, TEXT("Unmute Remote Talker couldn't get the voice interface!")); + return; + } + + NumLocalTalkers = VoiceInterface->GetNumLocalTalkers(); +} \ No newline at end of file diff --git a/Source/AdvancedSessions/Private/BlueprintDataDefinitions.h b/Source/AdvancedSessions/Private/BlueprintDataDefinitions.h new file mode 100644 index 0000000..c5beb8b --- /dev/null +++ b/Source/AdvancedSessions/Private/BlueprintDataDefinitions.h @@ -0,0 +1,328 @@ +#pragma once + +#include "Engine.h" +#include "Core.h" +#include "OnlineSessionInterface.h" +#include "OnlineSessionSettings.h" +#include "OnlineDelegateMacros.h" +#include "OnlineSubsystem.h" +#include "OnlineSubsystemImpl.h" +#include "OnlineSubsystemUtils.h" +#include "OnlineSubsystemUtilsModule.h" +#include "ModuleManager.h" +#include "OnlineSubsystemUtilsClasses.h" +#include "BlueprintDataDefinitions.generated.h" + + +UENUM() +namespace ESessionSettingSearchResult +{ + enum Type + { + // Found the setting + Found, + + // Did not find the setting + NotFound, + + // Was not the correct ype + WrongType + }; +} + +// This makes a lot of the blueprint functions cleaner +UENUM() +namespace EBlueprintResultSwitch +{ + enum Type + { + // On Success + OnSuccess, + + // On Failure + OnFailure + }; +} + + +// Wanted this to be switchable in the editor +UENUM(BlueprintType) +namespace EBPOnlinePresenceState +{ + enum Type + { + Online, + Offline, + Away, + ExtendedAway, + DoNotDisturb, + Chat + }; +} + +UENUM(BlueprintType) +namespace EBPOnlineSessionState +{ + enum Type + { + /** An online session has not been created yet */ + NoSession, + /** An online session is in the process of being created */ + Creating, + /** Session has been created but the session hasn't started (pre match lobby) */ + Pending, + /** Session has been asked to start (may take time due to communication with backend) */ + Starting, + /** The current session has started. Sessions with join in progress disabled are no longer joinable */ + InProgress, + /** The session is still valid, but the session is no longer being played (post match lobby) */ + Ending, + /** The session is closed and any stats committed */ + Ended, + /** The session is being destroyed */ + Destroying + }; +} + +// Boy oh boy is this a dirty hack, but I can't figure out a good way to do it otherwise at the moment +// The UniqueNetId is an abstract class so I can't exactly re-initialize it to make a shared pointer on some functions +// So I made the blueprintable UniqueNetID into a dual variable struct with access functions and I am converting the const var for the pointer +// I really need to re-think this later +USTRUCT(BlueprintType) +struct FBPUniqueNetId +{ + GENERATED_USTRUCT_BODY() + +private: + bool bUseDirectPointer; + + +public: + TSharedPtr UniqueNetId; + const FUniqueNetId * UniqueNetIdPtr; + + void SetUniqueNetId(const TSharedPtr &ID) + { + bUseDirectPointer = false; + UniqueNetIdPtr = nullptr; + UniqueNetId = ID; + } + + void SetUniqueNetId(const FUniqueNetId *ID) + { + bUseDirectPointer = true; + UniqueNetIdPtr = ID; + } + + bool IsValid() const + { + if (bUseDirectPointer && UniqueNetIdPtr != nullptr) + { + return true; + } + else if (UniqueNetId.IsValid()) + { + return true; + } + else + return false; + + } + + const FUniqueNetId* GetUniqueNetId() const + { + if (bUseDirectPointer && UniqueNetIdPtr != nullptr) + { + // No longer converting to non const as all functions now pass const UniqueNetIds + return /*const_cast*/(UniqueNetIdPtr); + } + else if (UniqueNetId.IsValid()) + { + return UniqueNetId.Get(); + } + else + return nullptr; + } + + FBPUniqueNetId() + { + bUseDirectPointer = false; + UniqueNetIdPtr = nullptr; + } +}; + +USTRUCT(BluePrintType) +struct FBPOnlineUser +{ + GENERATED_USTRUCT_BODY() + +public: + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FBPUniqueNetId UniqueNetId; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FString DisplayName; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FString RealName; +}; + +USTRUCT(BluePrintType) +struct FBPOnlineRecentPlayer : public FBPOnlineUser +{ + GENERATED_USTRUCT_BODY() + +public: + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FString LastSeen; +}; + +USTRUCT(BlueprintType) +struct FBPFriendInfo +{ + GENERATED_USTRUCT_BODY() + +public: + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FString DisplayName; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FString RealName; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + TEnumAsByte OnlineState; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + FBPUniqueNetId UniqueNetId; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend") + bool bIsPlayingSameGame; +}; + +/** The types of comparison operations for a given search query */ +// Used to compare session properties +UENUM(BlueprintType) +namespace EOnlineComparisonOpRedux +{ + enum Type + { + Equals, + NotEquals, + GreaterThan, + GreaterThanEquals, + LessThan, + LessThanEquals, + }; +} + + +// Used to store session properties before converting to FVariantData +USTRUCT(BlueprintType) +struct FSessionPropertyKeyPair +{ + GENERATED_USTRUCT_BODY() + + FName Key; + FVariantData Data; +}; + + +// Sent to the FindSessionsAdvanced to filter the end results +USTRUCT(BlueprintType) +struct FSessionsSearchSetting +{ + GENERATED_USTRUCT_BODY() + //UPROPERTY() + + + // Had to make a copy of this to account for the original not being exposed to blueprints + /** How is this session setting compared on the backend searches */ + TEnumAsByte ComparisonOp; + + // The key pair to search for + FSessionPropertyKeyPair PropertyKeyPair; +}; + +// Couldn't use the default one as it is not exposed to other modules, had to re-create it here +// Helper class for various methods to reduce the call hierarchy +struct FOnlineSubsystemBPCallHelperAdvanced +{ +public: + FOnlineSubsystemBPCallHelperAdvanced(const TCHAR* CallFunctionContext, UWorld* World, FName SystemName = NAME_None) + : OnlineSub(Online::GetSubsystem(World, SystemName)) + , FunctionContext(CallFunctionContext) + { + if (OnlineSub == nullptr) + { + FFrame::KismetExecutionMessage(*FString::Printf(TEXT("%s - Invalid or uninitialized OnlineSubsystem"), FunctionContext), ELogVerbosity::Warning); + } + } + + void QueryIDFromPlayerController(APlayerController* PlayerController) + { + UserID.Reset(); + //return const_cast(UniqueNetIdPtr); + if (APlayerState* PlayerState = (PlayerController != NULL) ? PlayerController->PlayerState : NULL) + { + UserID = PlayerState->UniqueId.GetUniqueNetId(); + if (!UserID.IsValid()) + { + FFrame::KismetExecutionMessage(*FString::Printf(TEXT("%s - Cannot map local player to unique net ID"), FunctionContext), ELogVerbosity::Warning); + } + } + else + { + FFrame::KismetExecutionMessage(*FString::Printf(TEXT("%s - Invalid player state"), FunctionContext), ELogVerbosity::Warning); + } + } + + + bool IsValid() const + { + return UserID.IsValid() && (OnlineSub != nullptr); + } + +public: + //TSharedPtr& GetUniqueNetId() + TSharedPtr UserID; + IOnlineSubsystem* const OnlineSub; + const TCHAR* FunctionContext; +}; +class FOnlineSearchSettingsEx : public FOnlineSearchSettings +{ + /** + * Sets a key value pair combination that defines a search parameter + * + * @param Key key for the setting + * @param Value value of the setting + * @param InType type of comparison + */ +public: + + void HardSet(FName Key, const FVariantData& Value, EOnlineComparisonOpRedux::Type CompOp) + { + FOnlineSessionSearchParam* SearchParam = SearchParams.Find(Key); + + EOnlineComparisonOp::Type op; + + switch (CompOp) + { + case EOnlineComparisonOpRedux::Equals: op = EOnlineComparisonOp::Equals; break; + case EOnlineComparisonOpRedux::GreaterThan: op = EOnlineComparisonOp::GreaterThan; break; + case EOnlineComparisonOpRedux::GreaterThanEquals: op = EOnlineComparisonOp::GreaterThanEquals; break; + case EOnlineComparisonOpRedux::LessThan: op = EOnlineComparisonOp::LessThan; break; + case EOnlineComparisonOpRedux::LessThanEquals: op = EOnlineComparisonOp::LessThanEquals; break; + case EOnlineComparisonOpRedux::NotEquals: op = EOnlineComparisonOp::NotEquals; break; + default: op = EOnlineComparisonOp::Equals; break; + } + + if (SearchParam) + { + SearchParam->Data = Value; + SearchParam->ComparisonOp = op; + } + else + { + FOnlineSessionSearchParam searchSetting((int)0, op); + searchSetting.Data = Value; + SearchParams.Add(Key, searchSetting); + } + } +}; + +#define INVALID_INDEX -1 \ No newline at end of file diff --git a/Source/AdvancedSessions/Private/CancelFindSessionsCallbackProxy.cpp b/Source/AdvancedSessions/Private/CancelFindSessionsCallbackProxy.cpp new file mode 100644 index 0000000..4d6d86d --- /dev/null +++ b/Source/AdvancedSessions/Private/CancelFindSessionsCallbackProxy.cpp @@ -0,0 +1,71 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. + +#include "OnlineSubSystemHeader.h" +#include "CancelFindSessionsCallbackProxy.h" + +////////////////////////////////////////////////////////////////////////// +// UCancelFindSessionsCallbackProxy + +UCancelFindSessionsCallbackProxy::UCancelFindSessionsCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , Delegate(FOnCancelFindSessionsCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted)) +{ +} + +UCancelFindSessionsCallbackProxy* UCancelFindSessionsCallbackProxy::CancelFindSessions(UObject* WorldContextObject, class APlayerController* PlayerController) +{ + UCancelFindSessionsCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UCancelFindSessionsCallbackProxy::Activate() +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("CancelFindSessions"), GEngine->GetWorldFromContextObject(WorldContextObject)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + DelegateHandle = Sessions->AddOnCancelFindSessionsCompleteDelegate_Handle(Delegate); + Sessions->CancelFindSessions(); + + // OnCompleted will get called, nothing more to do now + return; + } + else + { + FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning); + } + } + + // Fail immediately + OnFailure.Broadcast(); +} + +void UCancelFindSessionsCallbackProxy::OnCompleted(bool bWasSuccessful) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("CancelFindSessionsCallback"), GEngine->GetWorldFromContextObject(WorldContextObject)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnCancelFindSessionsCompleteDelegate_Handle(DelegateHandle); + } + } + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + } + else + { + OnFailure.Broadcast(); + } +} diff --git a/Source/AdvancedSessions/Private/CreateSessionCallbackProxyAdvanced.cpp b/Source/AdvancedSessions/Private/CreateSessionCallbackProxyAdvanced.cpp new file mode 100644 index 0000000..f6e237c --- /dev/null +++ b/Source/AdvancedSessions/Private/CreateSessionCallbackProxyAdvanced.cpp @@ -0,0 +1,135 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "OnlineSubSystemHeader.h" +#include "CreateSessionCallbackProxyAdvanced.h" + +////////////////////////////////////////////////////////////////////////// +// UCreateSessionCallbackProxyAdvanced + +UCreateSessionCallbackProxyAdvanced::UCreateSessionCallbackProxyAdvanced(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , CreateCompleteDelegate(FOnCreateSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnCreateCompleted)) + , StartCompleteDelegate(FOnStartSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnStartCompleted)) + , NumPublicConnections(1) +{ +} + +UCreateSessionCallbackProxyAdvanced* UCreateSessionCallbackProxyAdvanced::CreateAdvancedSession(UObject* WorldContextObject, const TArray &ExtraSettings, class APlayerController* PlayerController, int32 PublicConnections, bool bUseLAN, bool bAllowInvites, bool bIsDedicatedServer) +{ + UCreateSessionCallbackProxyAdvanced* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->NumPublicConnections = PublicConnections; + Proxy->bUseLAN = bUseLAN; + Proxy->WorldContextObject = WorldContextObject; + Proxy->bAllowInvites = bAllowInvites; + Proxy->ExtraSettings = ExtraSettings; + Proxy->bDedicatedServer = bIsDedicatedServer; + + return Proxy; +} + +void UCreateSessionCallbackProxyAdvanced::Activate() +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("CreateSession"), GEngine->GetWorldFromContextObject(WorldContextObject)); + + if (PlayerControllerWeakPtr.IsValid() ) + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.OnlineSub != nullptr) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + CreateCompleteDelegateHandle = Sessions->AddOnCreateSessionCompleteDelegate_Handle(CreateCompleteDelegate); + + FOnlineSessionSettings Settings; + Settings.NumPublicConnections = NumPublicConnections; + Settings.bShouldAdvertise = true; + Settings.bAllowJoinInProgress = true; + Settings.bIsLANMatch = bUseLAN; + Settings.bUsesPresence = true; + Settings.bAllowJoinViaPresence = true; + Settings.bIsDedicated = bDedicatedServer; + + // These are about the only changes over the standard Create Sessions Node + Settings.bAllowInvites = bAllowInvites; + + FOnlineSessionSetting ExtraSetting; + for (int i = 0; i < ExtraSettings.Num(); i++) + { + ExtraSetting.Data = ExtraSettings[i].Data; + // ViaOnlineServiceAndPing + ExtraSetting.AdvertisementType = EOnlineDataAdvertisementType::ViaOnlineService; + Settings.Settings.Add(ExtraSettings[i].Key, ExtraSetting); + } + + + if (PlayerControllerWeakPtr.IsValid() && Helper.UserID.IsValid()) + Sessions->CreateSession(*Helper.UserID, GameSessionName, Settings); + else + Sessions->CreateSession(NULL, GameSessionName, Settings); + + // OnCreateCompleted will get called, nothing more to do now + return; + } + else + { + FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning); + } + } + + // Fail immediately + OnFailure.Broadcast(); +} + +void UCreateSessionCallbackProxyAdvanced::OnCreateCompleted(FName SessionName, bool bWasSuccessful) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("CreateSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject)); + //Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.OnlineSub != nullptr) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnCreateSessionCompleteDelegate_Handle(CreateCompleteDelegateHandle); + + if (bWasSuccessful) + { + StartCompleteDelegateHandle = Sessions->AddOnStartSessionCompleteDelegate_Handle(StartCompleteDelegate); + Sessions->StartSession(GameSessionName); + + // OnStartCompleted will get called, nothing more to do now + return; + } + } + } + + if (!bWasSuccessful) + { + OnFailure.Broadcast(); + } +} + +void UCreateSessionCallbackProxyAdvanced::OnStartCompleted(FName SessionName, bool bWasSuccessful) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("StartSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.OnlineSub != nullptr) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnStartSessionCompleteDelegate_Handle(StartCompleteDelegateHandle); + } + } + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + } + else + { + OnFailure.Broadcast(); + } +} diff --git a/Source/AdvancedSessions/Private/EndSessionCallbackProxy.cpp b/Source/AdvancedSessions/Private/EndSessionCallbackProxy.cpp new file mode 100644 index 0000000..73caee6 --- /dev/null +++ b/Source/AdvancedSessions/Private/EndSessionCallbackProxy.cpp @@ -0,0 +1,79 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. + +#include "OnlineSubSystemHeader.h" +#include "EndSessionCallbackProxy.h" + +////////////////////////////////////////////////////////////////////////// +// UEndSessionCallbackProxy + +UEndSessionCallbackProxy::UEndSessionCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , Delegate(FOnEndSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted)) +{ +} + +UEndSessionCallbackProxy* UEndSessionCallbackProxy::EndSession(UObject* WorldContextObject, class APlayerController* PlayerController) +{ + UEndSessionCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UEndSessionCallbackProxy::Activate() +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("EndSession"), GEngine->GetWorldFromContextObject(WorldContextObject)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + FNamedOnlineSession* Session = Sessions->GetNamedSession(GameSessionName); + if (Session && + Session->SessionState == EOnlineSessionState::InProgress) + { + DelegateHandle = Sessions->AddOnEndSessionCompleteDelegate_Handle(Delegate); + Sessions->EndSession(GameSessionName); + } + else + { + OnSuccess.Broadcast(); + } + // OnCompleted will get called, nothing more to do now + return; + } + else + { + FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning); + } + } + + // Fail immediately + OnFailure.Broadcast(); +} + +void UEndSessionCallbackProxy::OnCompleted(FName SessionName, bool bWasSuccessful) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("EndSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnEndSessionCompleteDelegate_Handle(DelegateHandle); + } + } + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + } + else + { + OnFailure.Broadcast(); + } +} diff --git a/Source/AdvancedSessions/Private/FindFriendSessionCallbackProxy.cpp b/Source/AdvancedSessions/Private/FindFriendSessionCallbackProxy.cpp new file mode 100644 index 0000000..89524a5 --- /dev/null +++ b/Source/AdvancedSessions/Private/FindFriendSessionCallbackProxy.cpp @@ -0,0 +1,88 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "OnlineSubSystemHeader.h" +#include "FindFriendSessionCallbackProxy.h" + +////////////////////////////////////////////////////////////////////////// +// UGetRecentPlayersCallbackProxy +DEFINE_LOG_CATEGORY(AdvancedFindFriendSessionLog); + +UFindFriendSessionCallbackProxy::UFindFriendSessionCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , OnFindFriendSessionCompleteDelegate(FOnFindFriendSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnFindFriendSessionCompleted)) +{ +} + +UFindFriendSessionCallbackProxy* UFindFriendSessionCallbackProxy::FindFriendSession(UObject* WorldContextObject, APlayerController *PlayerController, const FBPUniqueNetId &FriendUniqueNetId) +{ + UFindFriendSessionCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->cUniqueNetId = FriendUniqueNetId; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UFindFriendSessionCallbackProxy::Activate() +{ + if (!cUniqueNetId.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed received a bad UniqueNetId!")); + FBlueprintSessionResult EmptyResult; + OnFailure.Broadcast(EmptyResult); + return; + } + + if (!PlayerControllerWeakPtr.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed received a bad playercontroller!")); + FBlueprintSessionResult EmptyResult; + OnFailure.Broadcast(EmptyResult); + return; + } + + IOnlineSessionPtr Sessions = Online::GetSessionInterface(); + + if (Sessions.IsValid()) + { + ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + if (!Player) + { + // Fail immediately + UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed couldn't cast to ULocalPlayer!")); + FBlueprintSessionResult EmptyResult; + OnFailure.Broadcast(EmptyResult); + return; + } + + FindFriendSessionCompleteDelegateHandle = Sessions->AddOnFindFriendSessionCompleteDelegate_Handle(Player->GetControllerId(), OnFindFriendSessionCompleteDelegate); + + Sessions->FindFriendSession(Player->GetControllerId(),*cUniqueNetId.GetUniqueNetId()); + return; + } + // Fail immediately + FBlueprintSessionResult EmptyResult; + OnFailure.Broadcast(EmptyResult); +} + +void UFindFriendSessionCallbackProxy::OnFindFriendSessionCompleted(int32 LocalPlayer, bool bWasSuccessful, const FOnlineSessionSearchResult& SessionInfo) +{ + IOnlineSessionPtr Sessions = Online::GetSessionInterface(); + + if (Sessions.IsValid()) + Sessions->ClearOnFindFriendSessionCompleteDelegate_Handle(LocalPlayer, FindFriendSessionCompleteDelegateHandle); + + if ( bWasSuccessful ) + { + FBlueprintSessionResult Result; + Result.OnlineResult = SessionInfo; + OnSuccess.Broadcast(Result); + } + else + { + UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed")); + FBlueprintSessionResult EmptyResult; + OnFailure.Broadcast(EmptyResult); + } +} diff --git a/Source/AdvancedSessions/Private/FindSessionsCallbackProxyAdvanced.cpp b/Source/AdvancedSessions/Private/FindSessionsCallbackProxyAdvanced.cpp new file mode 100644 index 0000000..aa1c61c --- /dev/null +++ b/Source/AdvancedSessions/Private/FindSessionsCallbackProxyAdvanced.cpp @@ -0,0 +1,317 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. + +#include "OnlineSubSystemHeader.h" +#include "FindSessionsCallbackProxyAdvanced.h" + +////////////////////////////////////////////////////////////////////////// +// UFindSessionsCallbackProxyAdvanced + + +UFindSessionsCallbackProxyAdvanced::UFindSessionsCallbackProxyAdvanced(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , Delegate(FOnFindSessionsCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted)) + , bUseLAN(false) +{ +} + +UFindSessionsCallbackProxyAdvanced* UFindSessionsCallbackProxyAdvanced::FindSessionsAdvanced(UObject* WorldContextObject, class APlayerController* PlayerController, int MaxResults, bool bUseLAN, const TArray &Filters) +{ + UFindSessionsCallbackProxyAdvanced* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->bUseLAN = bUseLAN; + Proxy->MaxResults = MaxResults; + Proxy->WorldContextObject = WorldContextObject; + Proxy->SearchSettings = Filters; + return Proxy; +} + +void UFindSessionsCallbackProxyAdvanced::Activate() +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("FindSessions"), GEngine->GetWorldFromContextObject(WorldContextObject)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + DelegateHandle = Sessions->AddOnFindSessionsCompleteDelegate_Handle(Delegate); + + SearchObject = MakeShareable(new FOnlineSessionSearch); + SearchObject->MaxSearchResults = MaxResults; + SearchObject->bIsLanQuery = bUseLAN; + //SearchObject->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals); + + // Create temp filter variable, because I had to re-define a blueprint version of this, it is required. + FOnlineSearchSettingsEx tem; + tem.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals); + + // Filter results + if (SearchSettings.Num() > 0) + { + for (int i = 0; i < SearchSettings.Num(); i++) + { + // Function that was added to make directly adding a FVariant possible + tem.HardSet(SearchSettings[i].PropertyKeyPair.Key, SearchSettings[i].PropertyKeyPair.Data, SearchSettings[i].ComparisonOp); + } + } + + // Copy the derived temp variable over to it's base class + SearchObject->QuerySettings = tem; + + Sessions->FindSessions(*Helper.UserID, SearchObject.ToSharedRef()); + + // OnQueryCompleted will get called, nothing more to do now + return; + } + else + { + FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning); + } + } + + // Fail immediately + TArray Results; + OnFailure.Broadcast(Results); +} + +void UFindSessionsCallbackProxyAdvanced::OnCompleted(bool bSuccess) +{ + FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("FindSessionsCallback"), GEngine->GetWorldFromContextObject(WorldContextObject)); + Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get()); + + if (Helper.IsValid()) + { + auto Sessions = Helper.OnlineSub->GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnFindSessionsCompleteDelegate_Handle(DelegateHandle); + } + } + + TArray Results; + + if (bSuccess && SearchObject.IsValid()) + { + // Just log the results for now, will need to add a blueprint-compatible search result struct + for (auto& Result : SearchObject->SearchResults) + { + /* bool bAddResult = true; + + // Filter results + if (SearchSettings.Num() > 0) + { + FOnlineSessionSetting * setting; + for (int i = 0; i < SearchSettings.Num(); i++) + { + setting = Result.Session.SessionSettings.Settings.Find(SearchSettings[i].PropertyKeyPair.Key); + + // Couldn't find this key + if (!setting) + continue; + + if (!CompareVariants(setting->Data, SearchSettings[i].PropertyKeyPair.Data, SearchSettings[i].ComparisonOp)) + { + bAddResult = false; + break; + } + } + }*/ + + //if (bAddResult) + //{ + FString ResultText = FString::Printf(TEXT("Found a session. Ping is %d"), Result.PingInMs); + + FFrame::KismetExecutionMessage(*ResultText, ELogVerbosity::Log); + + FBlueprintSessionResult BPResult; + BPResult.OnlineResult = Result; + Results.Add(BPResult); + //} + } + OnSuccess.Broadcast(Results); + } + else + { + OnFailure.Broadcast(Results); + } +} + + +void UFindSessionsCallbackProxyAdvanced::FilterSessionResults(const TArray &SessionResults, const TArray &Filters, TArray &FilteredResults) +{ + for (int j = 0; j < SessionResults.Num(); j++) + { + bool bAddResult = true; + + // Filter results + if (Filters.Num() > 0) + { + const FOnlineSessionSetting * setting; + for (int i = 0; i < Filters.Num(); i++) + { + setting = SessionResults[j].OnlineResult.Session.SessionSettings.Settings.Find(Filters[i].PropertyKeyPair.Key); + + // Couldn't find this key + if (!setting) + continue; + + if (!CompareVariants(setting->Data, Filters[i].PropertyKeyPair.Data, Filters[i].ComparisonOp)) + { + bAddResult = false; + break; + } + } + } + + if (bAddResult) + FilteredResults.Add(SessionResults[j]); + } + + return; +} + + +bool UFindSessionsCallbackProxyAdvanced::CompareVariants(const FVariantData &A, const FVariantData &B, EOnlineComparisonOpRedux::Type Comparator) +{ + if (A.GetType() != B.GetType()) + return false; + + switch (A.GetType()) + { + case EOnlineKeyValuePairDataType::Bool: + { + bool bA, bB; + A.GetValue(bA); + B.GetValue(bB); + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + default: + return false;break; + } + } + case EOnlineKeyValuePairDataType::Double: + { + double bA, bB; + A.GetValue(bA); + B.GetValue(bB); + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + case EOnlineComparisonOpRedux::GreaterThanEquals: + return (bA == bB || bA > bB); break; + case EOnlineComparisonOpRedux::LessThanEquals: + return (bA == bB || bA < bB); break; + case EOnlineComparisonOpRedux::GreaterThan: + return bA > bB; break; + case EOnlineComparisonOpRedux::LessThan: + return bA < bB; break; + default: + return false; break; + } + } + case EOnlineKeyValuePairDataType::Float: + { + float tbA, tbB; + double bA, bB; + A.GetValue(tbA); + B.GetValue(tbB); + bA = (double)tbA; + bB = (double)tbB; + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + case EOnlineComparisonOpRedux::GreaterThanEquals: + return (bA == bB || bA > bB); break; + case EOnlineComparisonOpRedux::LessThanEquals: + return (bA == bB || bA < bB); break; + case EOnlineComparisonOpRedux::GreaterThan: + return bA > bB; break; + case EOnlineComparisonOpRedux::LessThan: + return bA < bB; break; + default: + return false; break; + } + } + case EOnlineKeyValuePairDataType::Int32: + { + int32 bA, bB; + A.GetValue(bA); + B.GetValue(bB); + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + case EOnlineComparisonOpRedux::GreaterThanEquals: + return (bA == bB || bA > bB); break; + case EOnlineComparisonOpRedux::LessThanEquals: + return (bA == bB || bA < bB); break; + case EOnlineComparisonOpRedux::GreaterThan: + return bA > bB; break; + case EOnlineComparisonOpRedux::LessThan: + return bA < bB; break; + default: + return false; break; + } + } + case EOnlineKeyValuePairDataType::Int64: + { + uint64 bA, bB; + A.GetValue(bA); + B.GetValue(bB); + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + case EOnlineComparisonOpRedux::GreaterThanEquals: + return (bA == bB || bA > bB); break; + case EOnlineComparisonOpRedux::LessThanEquals: + return (bA == bB || bA < bB); break; + case EOnlineComparisonOpRedux::GreaterThan: + return bA > bB; break; + case EOnlineComparisonOpRedux::LessThan: + return bA < bB; break; + default: + return false; break; + } + } + + case EOnlineKeyValuePairDataType::String: + { + FString bA, bB; + A.GetValue(bA); + B.GetValue(bB); + switch (Comparator) + { + case EOnlineComparisonOpRedux::Equals: + return bA == bB; break; + case EOnlineComparisonOpRedux::NotEquals: + return bA != bB; break; + default: + return false; break; + } + } + + case EOnlineKeyValuePairDataType::Empty: + case EOnlineKeyValuePairDataType::Blob: + default: + return false; break; + } + + + +} \ No newline at end of file diff --git a/Source/AdvancedSessions/Private/GetFriendsCallbackProxy.cpp b/Source/AdvancedSessions/Private/GetFriendsCallbackProxy.cpp new file mode 100644 index 0000000..b43fb69 --- /dev/null +++ b/Source/AdvancedSessions/Private/GetFriendsCallbackProxy.cpp @@ -0,0 +1,81 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "OnlineSubSystemHeader.h" +#include "GetFriendsCallbackProxy.h" + +////////////////////////////////////////////////////////////////////////// +// UGetFriendsCallbackProxy +DEFINE_LOG_CATEGORY(AdvancedGetFriendsLog); + +UGetFriendsCallbackProxy::UGetFriendsCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , FriendListReadCompleteDelegate(FOnReadFriendsListComplete::CreateUObject(this, &ThisClass::OnReadFriendsListCompleted)) +{ +} + +UGetFriendsCallbackProxy* UGetFriendsCallbackProxy::GetAndStoreFriendsList(UObject* WorldContextObject, class APlayerController* PlayerController) +{ + UGetFriendsCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UGetFriendsCallbackProxy::Activate() +{ + if (!PlayerControllerWeakPtr.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedGetFriendsLog, Warning, TEXT("GetFriends Failed received a bad player controller!")); + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); + return; + } + + IOnlineFriendsPtr Friends = Online::GetFriendsInterface(); + if (Friends.IsValid()) + { + ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + Friends->ReadFriendsList(Player->GetControllerId(), EFriendsLists::ToString((EFriendsLists::Type::Default)), FriendListReadCompleteDelegate); + return; + } + + // Fail immediately + TArray EmptyArray; + + OnFailure.Broadcast(EmptyArray); +} + +void UGetFriendsCallbackProxy::OnReadFriendsListCompleted(int32 LocalUserNum, bool bWasSuccessful, const FString& ListName, const FString& ErrorString) +{ + if (bWasSuccessful) + { + IOnlineFriendsPtr Friends = Online::GetFriendsInterface(); + if (Friends.IsValid()) + { + ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + TArray FriendsListOut; + TArray< TSharedRef > FriendList; + Friends->GetFriendsList(LocalUserNum, ListName, FriendList); + + for (int32 i = 0; i < FriendList.Num(); i++) + { + TSharedRef 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()); + FriendsListOut.Add(BPF); + } + + OnSuccess.Broadcast(FriendsListOut); + } + } + else + { + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); + } +} diff --git a/Source/AdvancedSessions/Private/GetRecentPlayersCallbackProxy.cpp b/Source/AdvancedSessions/Private/GetRecentPlayersCallbackProxy.cpp new file mode 100644 index 0000000..5df45e3 --- /dev/null +++ b/Source/AdvancedSessions/Private/GetRecentPlayersCallbackProxy.cpp @@ -0,0 +1,85 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "OnlineSubSystemHeader.h" +#include "GetRecentPlayersCallbackProxy.h" + +////////////////////////////////////////////////////////////////////////// +// UGetRecentPlayersCallbackProxy +DEFINE_LOG_CATEGORY(AdvancedGetRecentPlayersLog); + +UGetRecentPlayersCallbackProxy::UGetRecentPlayersCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , QueryRecentPlayersCompleteDelegate(FOnQueryRecentPlayersCompleteDelegate::CreateUObject(this, &ThisClass::OnQueryRecentPlayersCompleted)) +{ +} + +UGetRecentPlayersCallbackProxy* UGetRecentPlayersCallbackProxy::GetAndStoreRecentPlayersList(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId) +{ + UGetRecentPlayersCallbackProxy* Proxy = NewObject(); + Proxy->cUniqueNetId = UniqueNetId; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void UGetRecentPlayersCallbackProxy::Activate() +{ + if (!cUniqueNetId.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedGetRecentPlayersLog, Warning, TEXT("GetRecentPlayers Failed received a bad UniqueNetId!")); + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); + return; + } + + IOnlineFriendsPtr Friends = Online::GetFriendsInterface(); + if (Friends.IsValid()) + { + DelegateHandle = Friends->AddOnQueryRecentPlayersCompleteDelegate_Handle(QueryRecentPlayersCompleteDelegate); + + // Testing with null namespace + Friends->QueryRecentPlayers(*(cUniqueNetId.GetUniqueNetId()), ""); + return; + } + // Fail immediately + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); +} + +void UGetRecentPlayersCallbackProxy::OnQueryRecentPlayersCompleted(const FUniqueNetId &UserID, const FString &Namespace, bool bWasSuccessful, const FString& ErrorString) +{ + + IOnlineFriendsPtr Friends = Online::GetFriendsInterface(); + if (Friends.IsValid()) + Friends->ClearOnQueryRecentPlayersCompleteDelegate_Handle(DelegateHandle); + + + if (bWasSuccessful) + { + // WHOOPS + //IOnlineFriendsPtr Friends = Online::GetFriendsInterface(); + if (Friends.IsValid()) + { + TArray PlayersListOut; + TArray< TSharedRef > PlayerList; + + Friends->GetRecentPlayers(*(cUniqueNetId.GetUniqueNetId()), "", PlayerList); + + for (int32 i = 0; i < PlayerList.Num(); i++) + { + TSharedRef Player = PlayerList[i]; + FBPOnlineRecentPlayer BPF; + BPF.DisplayName = Player->GetDisplayName(); + BPF.RealName = Player->GetRealName(); + BPF.UniqueNetId.SetUniqueNetId(Player->GetUserId()); + PlayersListOut.Add(BPF); + } + + OnSuccess.Broadcast(PlayersListOut); + } + } + else + { + TArray EmptyArray; + OnFailure.Broadcast(EmptyArray); + } +} diff --git a/Source/AdvancedSessions/Private/OnlineSubSystemHeader.h b/Source/AdvancedSessions/Private/OnlineSubSystemHeader.h new file mode 100644 index 0000000..a0e48d1 --- /dev/null +++ b/Source/AdvancedSessions/Private/OnlineSubSystemHeader.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Engine.h" +#include "Core.h" +#include "OnlineSessionInterface.h" +#include "OnlineSessionSettings.h" +#include "OnlineDelegateMacros.h" +#include "OnlineSubsystem.h" +#include "OnlineSubsystemImpl.h" +#include "OnlineSubsystemUtils.h" +#include "OnlineSubsystemUtilsModule.h" +#include "ModuleManager.h" +#include "OnlineSubsystemUtilsClasses.h" +#include "BlueprintDataDefinitions.h" \ No newline at end of file diff --git a/Source/AdvancedSessions/Private/SendFriendInviteCallbackProxy.cpp b/Source/AdvancedSessions/Private/SendFriendInviteCallbackProxy.cpp new file mode 100644 index 0000000..0e25bd0 --- /dev/null +++ b/Source/AdvancedSessions/Private/SendFriendInviteCallbackProxy.cpp @@ -0,0 +1,73 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "OnlineSubSystemHeader.h" +#include "SendFriendInviteCallbackProxy.h" + +////////////////////////////////////////////////////////////////////////// +// UGetRecentPlayersCallbackProxy +DEFINE_LOG_CATEGORY(AdvancedSendFriendInviteLog); + +USendFriendInviteCallbackProxy::USendFriendInviteCallbackProxy(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , OnSendInviteCompleteDelegate(FOnSendInviteComplete::CreateUObject(this, &ThisClass::OnSendInviteComplete)) +{ +} + +USendFriendInviteCallbackProxy* USendFriendInviteCallbackProxy::SendFriendInvite(UObject* WorldContextObject, APlayerController *PlayerController, const FBPUniqueNetId &UniqueNetIDInvited) +{ + USendFriendInviteCallbackProxy* Proxy = NewObject(); + Proxy->PlayerControllerWeakPtr = PlayerController; + Proxy->cUniqueNetId = UniqueNetIDInvited; + Proxy->WorldContextObject = WorldContextObject; + return Proxy; +} + +void USendFriendInviteCallbackProxy::Activate() +{ + if (!cUniqueNetId.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedSendFriendInviteLog, Warning, TEXT("SendFriendInvite Failed received a bad UniqueNetId!")); + OnFailure.Broadcast(); + return; + } + + if (!PlayerControllerWeakPtr.IsValid()) + { + // Fail immediately + UE_LOG(AdvancedSendFriendInviteLog, Warning, TEXT("SendFriendInvite Failed received a bad playercontroller!")); + OnFailure.Broadcast(); + return; + } + + IOnlineFriendsPtr Friends = Online::GetFriendsInterface(); + if (Friends.IsValid()) + { + ULocalPlayer* Player = Cast(PlayerControllerWeakPtr->Player); + + if (!Player) + { + // Fail immediately + UE_LOG(AdvancedSendFriendInviteLog, Warning, TEXT("SendFriendInvite Failed couldn't cast to ULocalPlayer!")); + OnFailure.Broadcast(); + return; + } + + Friends->SendInvite(Player->GetControllerId(), *cUniqueNetId.GetUniqueNetId(), EFriendsLists::ToString((EFriendsLists::Type::Default)), OnSendInviteCompleteDelegate); + return; + } + // Fail immediately + OnFailure.Broadcast(); +} + +void USendFriendInviteCallbackProxy::OnSendInviteComplete(int32 LocalPlayerNum, bool bWasSuccessful, const FUniqueNetId &InvitedPlayer, const FString &ListName, const FString &ErrorString) +{ + if ( bWasSuccessful ) + { + OnSuccess.Broadcast(); + } + else + { + UE_LOG(AdvancedSendFriendInviteLog, Warning, TEXT("SendFriendInvite Failed with error: %s"), *ErrorString); + OnFailure.Broadcast(); + } +} diff --git a/Source/AdvancedSessions/Private/UpdateSessionCallbackProxyAdvanced.cpp b/Source/AdvancedSessions/Private/UpdateSessionCallbackProxyAdvanced.cpp new file mode 100644 index 0000000..0232158 --- /dev/null +++ b/Source/AdvancedSessions/Private/UpdateSessionCallbackProxyAdvanced.cpp @@ -0,0 +1,120 @@ +// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved. +#include "OnlineSubSystemHeader.h" +#include "UpdateSessionCallbackProxyAdvanced.h" + +////////////////////////////////////////////////////////////////////////// +// UUpdateSessionCallbackProxyAdvanced + +UUpdateSessionCallbackProxyAdvanced::UUpdateSessionCallbackProxyAdvanced(const FObjectInitializer& ObjectInitializer) + : Super(ObjectInitializer) + , OnUpdateSessionCompleteDelegate(FOnUpdateSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnUpdateCompleted)) + , NumPublicConnections(1) +{ +} + +UUpdateSessionCallbackProxyAdvanced* UUpdateSessionCallbackProxyAdvanced::UpdateSession(UObject* WorldContextObject, int32 PublicConnections, bool bUseLAN, bool bAllowInvites, bool bAllowJoinInProgress, const TArray &ExtraSettings, bool bRefreshOnlineData, bool bIsDedicatedServer) +{ + UUpdateSessionCallbackProxyAdvanced* Proxy = NewObject(); + Proxy->NumPublicConnections = PublicConnections; + Proxy->bUseLAN = bUseLAN; + Proxy->WorldContextObject = WorldContextObject; + Proxy->bAllowInvites = bAllowInvites; + Proxy->ExtraSettings = ExtraSettings; + Proxy->bRefreshOnlineData = bRefreshOnlineData; + Proxy->bAllowJoinInProgress = bAllowJoinInProgress; + Proxy->bDedicatedServer = bIsDedicatedServer; + return Proxy; +} + +void UUpdateSessionCallbackProxyAdvanced::Activate() +{ + + + IOnlineSessionPtr Sessions = Online::GetSessionInterface(); + + if (Sessions.IsValid()) + { + if (Sessions->GetNumSessions() < 1) + { + OnFailure.Broadcast(); + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("NO REGISTERED SESSIONS!")); + return; + } + + // This gets the actual session itself + //FNamedOnlineSession * curSession = Sessions->GetNamedSession(GameSessionName); + FOnlineSessionSettings* Settings = Sessions->GetSessionSettings(GameSessionName); + + if (!Settings) + { + // Fail immediately + OnFailure.Broadcast(); + return; + } + + OnUpdateSessionCompleteDelegateHandle = Sessions->AddOnUpdateSessionCompleteDelegate_Handle(OnUpdateSessionCompleteDelegate); + + // FOnlineSessionSettings Settings; + //Settings->BuildUniqueId = GetBuildUniqueId(); + Settings->NumPublicConnections = NumPublicConnections; + //Settings->bShouldAdvertise = true; + Settings->bAllowJoinInProgress = bAllowJoinInProgress; + Settings->bIsLANMatch = bUseLAN; + //Settings->bUsesPresence = true; + //Settings->bAllowJoinViaPresence = true; + Settings->bAllowInvites = bAllowInvites; + Settings->bAllowJoinInProgress = bAllowJoinInProgress; + Settings->bIsDedicated = bDedicatedServer; + + FOnlineSessionSetting * fSetting = NULL; + FOnlineSessionSetting ExtraSetting; + for (int i = 0; i < ExtraSettings.Num(); i++) + { + fSetting = Settings->Settings.Find(ExtraSettings[i].Key); + + if (fSetting) + { + fSetting->Data = ExtraSettings[i].Data; + } + else + { + ExtraSetting.Data = ExtraSettings[i].Data; + ExtraSetting.AdvertisementType = EOnlineDataAdvertisementType::ViaOnlineService; + Settings->Settings.Add(ExtraSettings[i].Key, ExtraSetting); + } + } + + Sessions->UpdateSession(GameSessionName, *Settings, bRefreshOnlineData); + + // OnUpdateCompleted will get called, nothing more to do now + return; + } + else + { + FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning); + } + // Fail immediately + OnFailure.Broadcast(); + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Sessions not supported")); +} + +void UUpdateSessionCallbackProxyAdvanced::OnUpdateCompleted(FName SessionName, bool bWasSuccessful) +{ + IOnlineSessionPtr Sessions = Online::GetSessionInterface(); + if (Sessions.IsValid()) + { + Sessions->ClearOnUpdateSessionCompleteDelegate_Handle(OnUpdateSessionCompleteDelegateHandle); + + if (bWasSuccessful) + { + OnSuccess.Broadcast(); + return; + } + } + + if (!bWasSuccessful) + { + OnFailure.Broadcast(); + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("WAS NOT SUCCESSFUL")); + } +} \ No newline at end of file