// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "OnlineDelegateMacros.h" #include "OnlineSubsystemImpl.h" #include "OnlineSubsystemSteamPackage.h" #define UE_API ONLINESUBSYSTEMSTEAM_API class FOnlineAchievementsSteam; class FOnlineExternalUISteam; class FOnlineFriendsSteam; class FOnlineIdentitySteam; class FOnlineLeaderboardsSteam; class FOnlineSessionSteam; class FOnlineSharedCloudSteam; class FOnlineUserCloudSteam; class FOnlineVoiceSteam; class FOnlinePresenceSteam; class FOnlineAuthSteam; class FOnlineAuthUtilsSteam; class FOnlinePingInterfaceSteam; class FOnlineEncryptedAppTicketSteam; class FOnlinePurchaseSteam; class FOnlineStoreSteam; /** Forward declarations of all interface classes */ typedef TSharedPtr FOnlineSessionSteamPtr; typedef TSharedPtr FOnlineIdentitySteamPtr; typedef TSharedPtr FOnlineFriendsSteamPtr; typedef TSharedPtr FOnlineSharedCloudSteamPtr; typedef TSharedPtr FOnlineUserCloudSteamPtr; typedef TSharedPtr FOnlineLeaderboardsSteamPtr; typedef TSharedPtr FOnlineVoiceSteamPtr; typedef TSharedPtr FOnlineExternalUISteamPtr; typedef TSharedPtr FOnlineAchievementsSteamPtr; typedef TSharedPtr FOnlinePresenceSteamPtr; typedef TSharedPtr FOnlineAuthSteamPtr; typedef TSharedPtr FOnlineAuthSteamUtilsPtr; typedef TSharedPtr FOnlinePingSteamPtr; typedef TSharedPtr FOnlineEncryptedAppTicketSteamPtr; typedef TSharedPtr FOnlinePurchaseSteamPtr; typedef TSharedPtr FOnlineStoreSteamPtr; /** * Delegate fired when a Steam Game Server has completed its login tasks with the Steam backend. * * @param bWasSuccessful if the login completed successfully */ DECLARE_MULTICAST_DELEGATE_OneParam(FOnSteamServerLoginCompleted, bool /* bWasSuccessful */); typedef FOnSteamServerLoginCompleted::FDelegate FOnSteamServerLoginCompletedDelegate; /** * OnlineSubsystemSteam - Implementation of the online subsystem for STEAM services */ class FOnlineSubsystemSteam : public FOnlineSubsystemImpl { protected: /** Has the STEAM client APIs been initialized */ bool bSteamworksClientInitialized; /** Whether or not the Steam game server API is initialized */ bool bSteamworksGameServerInitialized; /** If we are using the SteamNetworking protocol or not. */ bool bUsingSteamNetworking; /** Steam App ID for the running game */ uint32 SteamAppID; /** Game port - the port that clients will connect to for gameplay */ int32 GameServerGamePort; /** Query port - the port that will manage server browser related duties and info */ int32 GameServerQueryPort; /** Array of the files in the cloud for a given user */ TArray UserCloudData; /** Interface to the session services */ FOnlineSessionSteamPtr SessionInterface; /** Interface to the profile services */ FOnlineIdentitySteamPtr IdentityInterface; /** Interface to the friend services */ FOnlineFriendsSteamPtr FriendInterface; /** Interface to the shared cloud services */ FOnlineSharedCloudSteamPtr SharedCloudInterface; /** Interface to the user cloud services */ FOnlineUserCloudSteamPtr UserCloudInterface; /** Interface to the leaderboard services */ FOnlineLeaderboardsSteamPtr LeaderboardsInterface; /** Interface to the voice engine */ mutable IOnlineVoicePtr VoiceInterface; /** Interface for voice communication */ mutable bool bVoiceInterfaceInitialized; /** Interface to the external UI services */ FOnlineExternalUISteamPtr ExternalUIInterface; /** Interface for achievements */ FOnlineAchievementsSteamPtr AchievementsInterface; /** Interface for presence */ FOnlinePresenceSteamPtr PresenceInterface; /** Interface for Steam Session Auth */ FOnlineAuthSteamPtr AuthInterface; FOnlineAuthSteamUtilsPtr AuthInterfaceUtils; /** Interface for dynamically calculating SteamNetworking ping based off protocol */ FOnlinePingSteamPtr PingInterface; /** Interface for Steam encrypted application tickets. */ FOnlineEncryptedAppTicketSteamPtr EncryptedAppTicketInterface; /** Interface for the Purchase interface */ FOnlinePurchaseSteamPtr PurchaseInterface; /** Interface for the Store interface */ FOnlineStoreSteamPtr StoreInterface; /** Online async task runnable */ class FOnlineAsyncTaskManagerSteam* OnlineAsyncTaskThreadRunnable; /** Online async task thread */ class FRunnableThread* OnlineAsyncTaskThread; /** Steam Client API Handle */ TSharedPtr SteamAPIClientHandle; /** Steam Server API Handle */ TSharedPtr SteamAPIServerHandle; PACKAGE_SCOPE: /** Only the factory makes instances */ FOnlineSubsystemSteam() = delete; FOnlineSubsystemSteam(FName InInstanceName) : FOnlineSubsystemImpl(STEAM_SUBSYSTEM, InInstanceName), bSteamworksClientInitialized(false), bSteamworksGameServerInitialized(false), bUsingSteamNetworking(false), SteamAppID(0), GameServerGamePort(0), GameServerQueryPort(0), SessionInterface(nullptr), IdentityInterface(nullptr), FriendInterface(nullptr), SharedCloudInterface(nullptr), UserCloudInterface(nullptr), LeaderboardsInterface(nullptr), VoiceInterface(nullptr), bVoiceInterfaceInitialized(false), ExternalUIInterface(nullptr), PresenceInterface(nullptr), AuthInterface(nullptr), AuthInterfaceUtils(nullptr), PingInterface(nullptr), EncryptedAppTicketInterface(nullptr), PurchaseInterface(nullptr), StoreInterface(nullptr), OnlineAsyncTaskThreadRunnable(nullptr), OnlineAsyncTaskThread(nullptr), SteamAPIClientHandle(nullptr), SteamAPIServerHandle(nullptr) {} /** Critical sections for thread safe operation of the cloud files */ FCriticalSection UserCloudDataLock; /** * Initialize the client side APIs for Steam * @return true if the API was initialized successfully, false otherwise */ UE_API bool InitSteamworksClient(bool bRelaunchInSteam, int32 SteamAppId); /** * Initialize the server side APIs for Steam * @return true if the API was initialized successfully, false otherwise */ UE_API bool InitSteamworksServer(); /** * Shutdown the Steam APIs */ UE_API void ShutdownSteamworks(); /** * Add an async task onto the task queue for processing * @param AsyncTask - new heap allocated task to process on the async task thread */ UE_API void QueueAsyncTask(class FOnlineAsyncTask* AsyncTask); /** * Add an async task onto the outgoing task queue for processing * @param AsyncItem - new heap allocated task to process on the async task thread */ UE_API void QueueAsyncOutgoingItem(class FOnlineAsyncItem* AsyncItem); /** * **INTERNAL** * Get the metadata related to a given user * This information is only available after calling EnumerateUserFiles * * @param UserId the UserId to search for * @return the struct with the metadata about the requested user, will always return a valid struct, creating one if necessary * */ UE_API struct FSteamUserCloudData* GetUserCloudEntry(const FUniqueNetId& UserId); /** * **INTERNAL** * Clear the metadata related to a given user's file on Steam * This information is only available after calling EnumerateUserFiles * It doesn't actually delete any of the actual data on disk * * @param UserId the UserId for the file to search for * @param Filename the file to get metadata about * @return the true if the delete was successful, false otherwise * */ UE_API bool ClearUserCloudMetadata(const FUniqueNetId& UserId, const FString& Filename); /** * Clear out all the data related to user cloud storage */ UE_API void ClearUserCloudFiles(); /** * **INTERNAL** * Get the interface for accessing leaderboards/stats * * @return pointer for the appropriate class */ UE_API FOnlineLeaderboardsSteam * GetInternalLeaderboardsInterface(); public: virtual ~FOnlineSubsystemSteam() { } UE_API virtual FOnlineEncryptedAppTicketSteamPtr GetEncryptedAppTicketInterface() const; UE_API virtual FOnlineAuthSteamPtr GetAuthInterface() const; UE_API virtual FOnlineAuthSteamUtilsPtr GetAuthInterfaceUtils() const; UE_API virtual FOnlinePingSteamPtr GetPingInterface() const; UE_API virtual void SetPingInterface(FOnlinePingSteamPtr InPingInterface); // IOnlineSubsystem UE_API virtual IOnlineSessionPtr GetSessionInterface() const override; UE_API virtual IOnlineFriendsPtr GetFriendsInterface() const override; UE_API virtual IOnlinePartyPtr GetPartyInterface() const override; UE_API virtual IOnlineGroupsPtr GetGroupsInterface() const override; UE_API virtual IOnlineSharedCloudPtr GetSharedCloudInterface() const override; UE_API virtual IOnlineUserCloudPtr GetUserCloudInterface() const override; UE_API virtual IOnlineLeaderboardsPtr GetLeaderboardsInterface() const override; UE_API virtual IOnlineVoicePtr GetVoiceInterface() const override; UE_API virtual IOnlineExternalUIPtr GetExternalUIInterface() const override; UE_API virtual IOnlineTimePtr GetTimeInterface() const override; UE_API virtual IOnlineIdentityPtr GetIdentityInterface() const override; UE_API virtual IOnlineTitleFilePtr GetTitleFileInterface() const override; UE_API virtual IOnlineEntitlementsPtr GetEntitlementsInterface() const override; UE_API virtual IOnlineStoreV2Ptr GetStoreV2Interface() const override; UE_API virtual IOnlinePurchasePtr GetPurchaseInterface() const override; UE_API virtual IOnlineEventsPtr GetEventsInterface() const override; UE_API virtual IOnlineAchievementsPtr GetAchievementsInterface() const override; UE_API virtual IOnlineSharingPtr GetSharingInterface() const override; UE_API virtual IOnlineUserPtr GetUserInterface() const override; UE_API virtual IOnlineMessagePtr GetMessageInterface() const override; UE_API virtual IOnlinePresencePtr GetPresenceInterface() const override; UE_API virtual IOnlineChatPtr GetChatInterface() const override; UE_API virtual IOnlineStatsPtr GetStatsInterface() const override; UE_API virtual IOnlineTurnBasedPtr GetTurnBasedInterface() const override; UE_API virtual IOnlineTournamentPtr GetTournamentInterface() const override; UE_API virtual bool IsLocalPlayer(const FUniqueNetId& UniqueId) const override; UE_API virtual bool Init() override; UE_API virtual bool Shutdown() override; UE_API virtual bool Exec(class UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar) override; UE_API virtual bool IsEnabled() const override; UE_API virtual FString GetAppId() const override; UE_API virtual FText GetOnlineServiceName() const override; // FTSTickerObjectBase UE_API virtual bool Tick(float DeltaTime) override; // FOnlineSubsystemSteam /** * Whether or not the Steam Client interfaces are available; these interfaces are only available, if the Steam Client program is running * NOTE: These interfaces are made unavailable, when running a dedicated server * * @return Whether or not the Steam Client interfaces are available */ inline bool IsSteamClientAvailable() { return bSteamworksClientInitialized; } /** * Whether or not the Steam game server interfaces are available; these interfaces are always available, so long as they were initialized correctly * NOTE: The Steam Client does not need to be running for the game server interfaces to initialize * NOTE: These interfaces are made unavailable, when not running a server * * @return Whether or not the Steam game server interfaces are available */ inline bool IsSteamServerAvailable() { // @todo Steam - add some logic to detect somehow we intended to be a "Steam client" but failed that part // yet managed to still initialize the game server aspects of Steam return bSteamworksGameServerInitialized; } /** * @return the steam app id for this app */ inline uint32 GetSteamAppId() const { return SteamAppID; } /** * @return the port the game has registered for play */ inline int32 GetGameServerGamePort() const { return GameServerGamePort; } /** * @return the port the game has registered for incoming server queries */ inline int32 GetGameServerQueryPort() const { return GameServerQueryPort; } /** * @return if this subsystem is using SteamNetworking functionality * or another network layer like SteamSockets */ inline bool IsUsingSteamNetworking() const { return bUsingSteamNetworking; } /** * This delegate fires whenever a steam login has succeeded or failed its async task. * Useful for modules that need to check to see if a user is logged in before running other behavior */ DEFINE_ONLINE_DELEGATE_ONE_PARAM(OnSteamServerLoginCompleted, bool); }; namespace FNetworkProtocolTypes { ONLINESUBSYSTEMSTEAM_API extern const FLazyName Steam; } typedef TSharedPtr FOnlineSubsystemSteamPtr; #undef UE_API