From 98ced280e051d296fb76744e9e5640bd9e83bb63 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 12 Aug 2026 05:50:56 +0200 Subject: [PATCH] Add game overlay UI utilities to `IOnlinePlatform` --- Source/Engine/Online/IOnlinePlatform.h | 65 ++++++++++++++++++++++ Source/Engine/Platform/GDK/GDKPlatform.cpp | 6 +- Source/Engine/Platform/GDK/GDKPlatform.h | 2 +- 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/Source/Engine/Online/IOnlinePlatform.h b/Source/Engine/Online/IOnlinePlatform.h index 708bc9452..3dedafeda 100644 --- a/Source/Engine/Online/IOnlinePlatform.h +++ b/Source/Engine/Online/IOnlinePlatform.h @@ -204,6 +204,47 @@ API_STRUCT(Namespace="FlaxEngine.Online") struct FLAXENGINE_API OnlineLeaderboar API_FIELD() int32 Score; }; +/// +/// Online platform game overlay dialog types. +/// +API_ENUM(Namespace="FlaxEngine.Online") enum class OnlineOverlayDialog +{ + /// + /// Displays the user login page. + /// + Login = 0, + + /// + /// Displays the uweb browser. + /// + Website, + + /// + /// Displays the user profile page. + /// + Profile, + + /// + /// Displays the page with achievements list. + /// + Achievements, + + /// + /// Displays the page with stats list. + /// + Stats, + + /// + /// Displays the page with friends list. + /// + Friends, + + /// + /// Displays the page with text chat. + /// + Chat, +}; + /// /// Interface for online platform providers for communicating with various multiplayer services such as player info, achievements, game lobby or in-game store. /// @@ -416,4 +457,28 @@ public: /// The local user (null if use default one). /// True if failed, otherwise false. API_FUNCTION() virtual bool SetSaveGame(const StringView& name, const Span& data, User* localUser = nullptr) = 0; + +public: + /// + /// Opens the game store overlay to a specific place. Avaliability depends on the platform and store. + /// + /// The dialog to display. + /// True if failed, otherwise false. + API_FUNCTION() virtual bool OpenOverlay(OnlineOverlayDialog dialog) = 0; + + /// + /// Opens the game store overlay to a specific place for a given website URL. Avaliability depends on the platform and store. + /// + /// The URL of the website to open. Full address with protocol type is required, e.g. https://www.flaxengine.com/. + /// The dialog to display. + /// True if failed, otherwise false. + API_FUNCTION() virtual bool OpenOverlayUrl(const StringView& url, OnlineOverlayDialog dialog = OnlineOverlayDialog::Website) = 0; + + /// + /// Opens the game store overlay to a specific place for a given user. Avaliability depends on the platform and store. + /// + /// The user to show Profile/Achievements/Stats pages of. + /// The dialog to display. + /// True if failed, otherwise false. + API_FUNCTION() virtual bool OpenOverlayUser(const OnlineUser& user, OnlineOverlayDialog dialog = OnlineOverlayDialog::Profile) = 0; }; diff --git a/Source/Engine/Platform/GDK/GDKPlatform.cpp b/Source/Engine/Platform/GDK/GDKPlatform.cpp index 092c4037b..b5f0f6bd4 100644 --- a/Source/Engine/Platform/GDK/GDKPlatform.cpp +++ b/Source/Engine/Platform/GDK/GDKPlatform.cpp @@ -343,12 +343,12 @@ void GDKPlatform::SignInSilently() } } -void GDKPlatform::SignInWithUI() +void GDKPlatform::SignInWithUI(bool allowGuests) { auto ab = new XAsyncBlock(); ab->queue = TaskQueue; ab->callback = AddUserComplete; - HRESULT result = XUserAddAsync(XUserAddOptions::AllowGuests, ab); + HRESULT result = XUserAddAsync(allowGuests ? XUserAddOptions::AllowGuests : XUserAddOptions::None, ab); if (FAILED(result)) { GDK_LOG(result, "XUserAddAsync"); @@ -552,6 +552,8 @@ bool GDKPlatform::CanOpenUrl(const StringView& url) void GDKPlatform::OpenUrl(const StringView& url) { + if (Users.IsEmpty()) + return; const StringAsANSI<> urlANSI(url.Get(), url.Length()); XLaunchUri(Users[0]->UserHandle, urlANSI.Get()); } diff --git a/Source/Engine/Platform/GDK/GDKPlatform.h b/Source/Engine/Platform/GDK/GDKPlatform.h index 26dbd852b..7c6bb1e2a 100644 --- a/Source/Engine/Platform/GDK/GDKPlatform.h +++ b/Source/Engine/Platform/GDK/GDKPlatform.h @@ -43,7 +43,7 @@ public: // Signs in user without showing UI. If user is not signed in, it will fail and return false. Use SignInWithUI to show UI and let user sign in. API_FUNCTION() static void SignInSilently(); // Signs in user with showing UI. If user is already signed in, it will succeed and return true. If user is not signed in, it will show UI and let user sign in. - API_FUNCTION() static void SignInWithUI(); + API_FUNCTION() static void SignInWithUI(bool allowGuests = true); // Searches for a user with a specific local ID. static User* FindUser(const struct XUserLocalId& id);