generated from boo3/UnrealTemplate
Added plugin [AdvancedSessions] and changed Template LICENSE to reflect the project
This commit is contained in:
parent
c1614f8762
commit
5310aa7417
207
LICENSE
207
LICENSE
@ -1,158 +1,49 @@
|
|||||||
Creative Commons Attribution-NonCommercial 4.0 International
|
[MoneyMoneyMoneyGameUE5]
|
||||||
|
Copyright (C) 2025 boo3 (boo3@cozycorner.page). All Rights Reserved.
|
||||||
Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
|
|
||||||
|
1. License for Binaries
|
||||||
Using Creative Commons Public Licenses
|
You are granted permission to download, install, and execute the precompiled binary builds of "MoneyMoneyMoneyGameUE5" for personal, non-commercial use only.
|
||||||
|
|
||||||
Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
|
2. License for Source Code
|
||||||
|
The source code of "MoneyMoneyMoneyGameUE5" is publicly accessible under the following conditions:
|
||||||
Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors.
|
- Viewing, Copying, and Learning: You are permitted to view, copy, and study the source code for personal, non-commercial purposes.
|
||||||
|
- Modification and Contributions:
|
||||||
Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public.
|
- You may modify the source code for personal use or to propose contributions to the project.
|
||||||
|
- Contributions must be submitted to the repository and will be subject to review and acceptance by the copyright holder. By submitting contributions, you grant the copyright holder the rights to use, modify, and distribute your contributions as part of the project.
|
||||||
Creative Commons Attribution-NonCommercial 4.0 International Public License
|
- Prohibited Actions:
|
||||||
|
- You may not redistribute the source code or modified versions without explicit written permission from the copyright holder.
|
||||||
By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
|
- You may not use the source code or any derivative works for commercial purposes without explicit written permission.
|
||||||
|
|
||||||
Section 1 – Definitions.
|
3. Restrictions
|
||||||
|
- Redistribution of the binaries or source code is prohibited unless explicitly authorized by the copyright holder.
|
||||||
a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
|
- Decompiling, disassembling, or reverse engineering the binaries is prohibited.
|
||||||
|
|
||||||
b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
|
4. No Warranty
|
||||||
|
This software is provided "as is," without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement. In no event shall the copyright holder be liable for any claim, damages, or other liability arising from the use of this software.
|
||||||
c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
|
|
||||||
|
5. Ownership
|
||||||
d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
|
All intellectual property rights, including but not limited to the game assets, code, and binaries, remain the sole property of the copyright holder.
|
||||||
|
|
||||||
e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
|
6. Termination
|
||||||
|
Any violation of these terms will result in an immediate termination of this license.
|
||||||
f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
|
|
||||||
|
[AdvancedSessions] [AdvancedSteamSessions]
|
||||||
g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
|
Copyright Joshua Statzer
|
||||||
|
|
||||||
h. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
i. NonCommercial means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange.
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
j. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
k. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
l. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
Section 2 – Scope.
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
a. License grant.
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and
|
SOFTWARE.
|
||||||
|
|
||||||
B. produce, reproduce, and Share Adapted Material for NonCommercial purposes only.
|
|
||||||
|
|
||||||
2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
|
|
||||||
|
|
||||||
3. Term. The term of this Public License is specified in Section 6(a).
|
|
||||||
|
|
||||||
4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
|
|
||||||
|
|
||||||
5. Downstream recipients.
|
|
||||||
|
|
||||||
A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
|
|
||||||
|
|
||||||
B. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
|
|
||||||
|
|
||||||
6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
|
|
||||||
|
|
||||||
b. Other rights.
|
|
||||||
|
|
||||||
1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
|
|
||||||
|
|
||||||
2. Patent and trademark rights are not licensed under this Public License.
|
|
||||||
|
|
||||||
3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes.
|
|
||||||
|
|
||||||
Section 3 – License Conditions.
|
|
||||||
|
|
||||||
Your exercise of the Licensed Rights is expressly made subject to the following conditions.
|
|
||||||
|
|
||||||
a. Attribution.
|
|
||||||
|
|
||||||
1. If You Share the Licensed Material (including in modified form), You must:
|
|
||||||
|
|
||||||
A. retain the following if it is supplied by the Licensor with the Licensed Material:
|
|
||||||
|
|
||||||
i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
|
|
||||||
|
|
||||||
ii. a copyright notice;
|
|
||||||
|
|
||||||
iii. a notice that refers to this Public License;
|
|
||||||
|
|
||||||
iv. a notice that refers to the disclaimer of warranties;
|
|
||||||
|
|
||||||
v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
|
|
||||||
|
|
||||||
B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
|
|
||||||
|
|
||||||
C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
|
|
||||||
|
|
||||||
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
|
|
||||||
|
|
||||||
3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
|
|
||||||
|
|
||||||
4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
|
|
||||||
|
|
||||||
Section 4 – Sui Generis Database Rights.
|
|
||||||
|
|
||||||
Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
|
|
||||||
|
|
||||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only;
|
|
||||||
|
|
||||||
b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
|
|
||||||
|
|
||||||
c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
|
|
||||||
For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
|
|
||||||
|
|
||||||
Section 5 – Disclaimer of Warranties and Limitation of Liability.
|
|
||||||
|
|
||||||
a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
|
|
||||||
|
|
||||||
b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
|
|
||||||
|
|
||||||
c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
|
|
||||||
|
|
||||||
Section 6 – Term and Termination.
|
|
||||||
|
|
||||||
a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
|
|
||||||
|
|
||||||
b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
|
|
||||||
|
|
||||||
1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
|
|
||||||
|
|
||||||
2. upon express reinstatement by the Licensor.
|
|
||||||
|
|
||||||
For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
|
|
||||||
|
|
||||||
c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
|
|
||||||
|
|
||||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
|
|
||||||
|
|
||||||
Section 7 – Other Terms and Conditions.
|
|
||||||
|
|
||||||
a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
|
|
||||||
|
|
||||||
b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
|
|
||||||
|
|
||||||
Section 8 – Interpretation.
|
|
||||||
|
|
||||||
a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
|
|
||||||
|
|
||||||
b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
|
|
||||||
|
|
||||||
c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
|
|
||||||
|
|
||||||
d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
|
|
||||||
|
|
||||||
Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
|
|
||||||
|
|
||||||
Creative Commons may be contacted at creativecommons.org.
|
|
34
Plugins/AdvancedSessions/AdvancedSessions.uplugin
Normal file
34
Plugins/AdvancedSessions/AdvancedSessions.uplugin
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"FileVersion": 3,
|
||||||
|
"FriendlyName": "Advanced Sessions",
|
||||||
|
"Version": 5.5,
|
||||||
|
"VersionName": "5.5",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Plugins": [
|
||||||
|
{
|
||||||
|
"Name": "OnlineSubsystem",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "OnlineSubsystemUtils",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"DocsURL": "",
|
||||||
|
"MarketplaceURL": "",
|
||||||
|
"SupportURL": "",
|
||||||
|
"CanContainContent": false,
|
||||||
|
"IsBetaVersion": false,
|
||||||
|
"IsExperimentalVersion": false,
|
||||||
|
"Installed": false
|
||||||
|
}
|
8
Plugins/AdvancedSessions/Config/FilterPlugin.ini
Normal file
8
Plugins/AdvancedSessions/Config/FilterPlugin.ini
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[FilterPlugin]
|
||||||
|
; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and
|
||||||
|
; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively.
|
||||||
|
;
|
||||||
|
; Examples:
|
||||||
|
; /README.txt
|
||||||
|
; /Extras/...
|
||||||
|
; /Binaries/ThirdParty/*.dll
|
BIN
Plugins/AdvancedSessions/Resources/Icon128.png
(Stored with Git LFS)
Normal file
BIN
Plugins/AdvancedSessions/Resources/Icon128.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,17 @@
|
|||||||
|
using UnrealBuildTool;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
public class AdvancedSessions : ModuleRules
|
||||||
|
{
|
||||||
|
public AdvancedSessions(ReadOnlyTargetRules Target) : base(Target)
|
||||||
|
{
|
||||||
|
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
//bEnforceIWYU = true;
|
||||||
|
|
||||||
|
PublicDefinitions.Add("WITH_ADVANCED_SESSIONS=1");
|
||||||
|
|
||||||
|
// PrivateIncludePaths.AddRange(new string[] { "AdvancedSessions/Private"/*, "OnlineSubsystemSteam/Private"*/ });
|
||||||
|
// PublicIncludePaths.AddRange(new string[] { "AdvancedSessions/Public" });
|
||||||
|
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "OnlineSubsystem", "CoreUObject", "OnlineSubsystemUtils", "Networking", "Sockets"/*"Voice", "OnlineSubsystemSteam"*/ });
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "Online.h"
|
||||||
|
#include "Engine/LocalPlayer.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
//#include "OnlineFriendsInterface.h"
|
||||||
|
//#include "OnlineUserInterface.h"
|
||||||
|
//#include "OnlineMessageInterface.h"
|
||||||
|
//#include "OnlinePresenceInterface.h"
|
||||||
|
//#include "Engine/GameInstance.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
|
||||||
|
//#include "UObjectIterator.h"
|
||||||
|
|
||||||
|
#include "AdvancedExternalUILibrary.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
//General Advanced Sessions Log
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(AdvancedExternalUILog, Log, All);
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class UAdvancedExternalUILibrary : public UBlueprintFunctionLibrary
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
|
||||||
|
//********* External UI Functions *************//
|
||||||
|
|
||||||
|
// Show the UI that handles the Friends list
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject"))
|
||||||
|
static void ShowFriendsUI(UObject* WorldContextObject, APlayerController *PlayerController, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
// Show the UI that handles inviting people to your game
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject"))
|
||||||
|
static void ShowInviteUI(UObject* WorldContextObject, APlayerController *PlayerController, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
// Show the UI that shows the leaderboard (doesn't work with steam)
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject"))
|
||||||
|
static void ShowLeaderBoardUI(UObject* WorldContextObject, FString LeaderboardName, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
// Show the UI that shows a web URL
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", AutoCreateRefTerm = "AllowedDomains", WorldContext = "WorldContextObject"))
|
||||||
|
static void ShowWebURLUI(UObject* WorldContextObject, FString URLToShow, EBlueprintResultSwitch &Result, TArray<FString>& AllowedDomains, bool bEmbedded = false , bool bShowBackground = false, bool bShowCloseButton = false, int32 OffsetX = 0, int32 OffsetY = 0, int32 SizeX = 0, int32 SizeY = 0);
|
||||||
|
|
||||||
|
// Show the UI that shows a web URL
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void CloseWebURLUI(UObject* WorldContextObject);
|
||||||
|
|
||||||
|
|
||||||
|
// Show the UI that shows the profile of a uniquenetid
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject"))
|
||||||
|
static void ShowProfileUI(UObject* WorldContextObject, const FBPUniqueNetId PlayerViewingProfile, const FBPUniqueNetId PlayerToViewProfileOf, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
// Show the UI that shows the account upgrade UI (doesn't work with steam)
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedExternalUI", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject"))
|
||||||
|
static void ShowAccountUpgradeUI(UObject* WorldContextObject, const FBPUniqueNetId PlayerRequestingAccountUpgradeUI, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
};
|
@ -0,0 +1,152 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "Online.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#include "Interfaces/OnlineFriendsInterface.h"
|
||||||
|
#include "Interfaces/OnlineUserInterface.h"
|
||||||
|
#include "Interfaces/OnlineMessageInterface.h"
|
||||||
|
#include "Interfaces/OnlinePresenceInterface.h"
|
||||||
|
#include "Engine/GameInstance.h"
|
||||||
|
#include "Engine/LocalPlayer.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
#include "OnlineSessionSettings.h"
|
||||||
|
#include "UObject/UObjectIterator.h"
|
||||||
|
#include "AdvancedFriendsInterface.h"
|
||||||
|
|
||||||
|
#include "AdvancedFriendsGameInstance.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
//General Advanced Sessions Log
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(AdvancedFriendsInterfaceLog, Log, All);
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class ADVANCEDSESSIONS_API UAdvancedFriendsGameInstance : public UGameInstance
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
|
||||||
|
UAdvancedFriendsGameInstance(const FObjectInitializer& ObjectInitializer);
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedFriendsInterface)
|
||||||
|
bool bCallFriendInterfaceEventsOnPlayerControllers;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AdvancedFriendsInterface)
|
||||||
|
bool bCallIdentityInterfaceEventsOnPlayerControllers;
|
||||||
|
|
||||||
|
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 received by local ***//
|
||||||
|
FOnSessionInviteReceivedDelegate SessionInviteReceivedDelegate;
|
||||||
|
FDelegateHandle SessionInviteReceivedDelegateHandle;
|
||||||
|
|
||||||
|
// custom handle to join directly from steam ui "Join Game"
|
||||||
|
FDelegateHandle OnJoinSessionCompleteDelegateHandle;
|
||||||
|
// custom Steam UI Join User function #Self invite#
|
||||||
|
void OnSessionUserInviteAccepted(const bool bWasSuccessful, const int32 ControllerId, FUniqueNetIdPtr UserId, const FOnlineSessionSearchResult& InviteResult);
|
||||||
|
// custom Steam UI function to client travel #Self invite#
|
||||||
|
void OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result);
|
||||||
|
|
||||||
|
//const FUniqueNetId& /*UserId*/, const FUniqueNetId& /*FromId*/, const FString& /*AppId*/, const FOnlineSessionSearchResult& /*InviteResult*/
|
||||||
|
void OnSessionInviteReceivedMaster(const FUniqueNetId & PersonInvited, const FUniqueNetId & PersonInviting, const FString & AppId, 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 OnSessionInviteReceived(int32 LocalPlayerNum, FBPUniqueNetId PersonInviting, const FString& AppId, const FBlueprintSessionResult& SessionToJoin);
|
||||||
|
|
||||||
|
//*** Session invite accepted by local ***//
|
||||||
|
FOnSessionUserInviteAcceptedDelegate SessionInviteAcceptedDelegate;
|
||||||
|
FDelegateHandle SessionInviteAcceptedDelegateHandle;
|
||||||
|
|
||||||
|
void OnSessionInviteAcceptedMaster(const bool bWasSuccessful, int32 LocalPlayer, TSharedPtr<const FUniqueNetId> 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
|
||||||
|
// This function is currently not hooked up in any of Epics default subsystems, it is here for custom subsystems
|
||||||
|
UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedFriends")
|
||||||
|
void OnSessionInviteAccepted(int32 LocalPlayerNum, FBPUniqueNetId PersonInvited, 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<const FUniqueNetId> PlayerId, bool bIsTalking);
|
||||||
|
|
||||||
|
FOnPlayerTalkingStateChangedDelegate PlayerTalkingStateChangedDelegate;
|
||||||
|
FDelegateHandle PlayerTalkingStateChangedDelegateHandle;
|
||||||
|
|
||||||
|
|
||||||
|
// Called when the designated LocalUser has changed login state
|
||||||
|
UFUNCTION(BlueprintImplementableEvent , Category = "AdvancedIdentity", meta = (DisplayName = "OnPlayerLoginChanged"))
|
||||||
|
void OnPlayerLoginChanged(int32 PlayerNum);
|
||||||
|
|
||||||
|
void OnPlayerLoginChangedMaster(int32 PlayerNum);
|
||||||
|
FOnLoginChangedDelegate PlayerLoginChangedDelegate;
|
||||||
|
FDelegateHandle PlayerLoginChangedDelegateHandle;
|
||||||
|
|
||||||
|
// Called when the designated LocalUser has changed login status
|
||||||
|
UFUNCTION(BlueprintImplementableEvent, Category = "AdvancedIdentity", meta = (DisplayName = "OnPlayerLoginStatusChanged"))
|
||||||
|
void OnPlayerLoginStatusChanged(int32 PlayerNum, EBPLoginStatus PreviousStatus, EBPLoginStatus NewStatus, FBPUniqueNetId NewPlayerUniqueNetID);
|
||||||
|
|
||||||
|
void OnPlayerLoginStatusChangedMaster(int32 PlayerNum, ELoginStatus::Type PreviousStatus, ELoginStatus::Type NewStatus, const FUniqueNetId & NewPlayerUniqueNetID);
|
||||||
|
FOnLoginStatusChangedDelegate PlayerLoginStatusChangedDelegate;
|
||||||
|
FDelegateHandle PlayerLoginStatusChangedDelegateHandle;
|
||||||
|
|
||||||
|
|
||||||
|
//*** 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);*/
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,56 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "Online.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#include "Interfaces/OnlineFriendsInterface.h"
|
||||||
|
#include "Interfaces/OnlineUserInterface.h"
|
||||||
|
#include "Interfaces/OnlineMessageInterface.h"
|
||||||
|
#include "Interfaces/OnlinePresenceInterface.h"
|
||||||
|
#include "Engine/GameInstance.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
#include "OnlineSessionSettings.h"
|
||||||
|
#include "UObject/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 = "OnSessionInviteReceived"))
|
||||||
|
void OnSessionInviteReceived(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 = "OnSessionInviteAccepted"))
|
||||||
|
void OnSessionInviteAccepted(FBPUniqueNetId PersonInvited, 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);
|
||||||
|
|
||||||
|
// Called when the designated LocalUser has changed login state
|
||||||
|
UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "OnPlayerLoginChanged"))
|
||||||
|
void OnPlayerLoginChanged(int32 PlayerNum);
|
||||||
|
|
||||||
|
// Called when the designated LocalUser has changed login state
|
||||||
|
UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "OnPlayerLoginStatusChanged"))
|
||||||
|
void OnPlayerLoginStatusChanged(EBPLoginStatus PreviousStatus, EBPLoginStatus NewStatus, FBPUniqueNetId PlayerUniqueNetID);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
};
|
@ -0,0 +1,56 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "Online.h"
|
||||||
|
#include "Engine/LocalPlayer.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#include "Interfaces/OnlineFriendsInterface.h"
|
||||||
|
#include "Interfaces/OnlineUserInterface.h"
|
||||||
|
#include "Interfaces/OnlineMessageInterface.h"
|
||||||
|
#include "Interfaces/OnlinePresenceInterface.h"
|
||||||
|
#include "Engine/GameInstance.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
|
||||||
|
#include "UObject/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<FBPUniqueNetId> &Friends, EBlueprintResultSwitch &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, EBlueprintResultSwitch &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<FBPFriendInfo> &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<FBPOnlineRecentPlayer> &PlayersList);
|
||||||
|
|
||||||
|
// Check if a UniqueNetId is a friend
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|FriendsList")
|
||||||
|
static void IsAFriend(APlayerController *PlayerController, const FBPUniqueNetId UniqueNetId, bool &IsFriend);
|
||||||
|
};
|
@ -0,0 +1,71 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "Online.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#include "Engine/GameInstance.h"
|
||||||
|
#include "GameFramework/GameModeBase.h"
|
||||||
|
#include "GameFramework/GameSession.h"
|
||||||
|
#include "GameFramework/PlayerState.h"
|
||||||
|
|
||||||
|
//#include "UObjectIterator.h"
|
||||||
|
|
||||||
|
#include "AdvancedGameSession.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
A quick wrapper around the game session to add a partial ban implementation. Just bans for the duration of the current session
|
||||||
|
*/
|
||||||
|
UCLASS(config = Game, notplaceable)
|
||||||
|
class AAdvancedGameSession : public AGameSession
|
||||||
|
{
|
||||||
|
GENERATED_UCLASS_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UPROPERTY(Transient)
|
||||||
|
TMap<FUniqueNetIdRepl, FText> BanList;
|
||||||
|
|
||||||
|
virtual bool BanPlayer(class APlayerController* BannedPlayer, const FText& BanReason)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (APlayerState* PlayerState = (BannedPlayer != NULL) ? BannedPlayer->PlayerState : NULL)
|
||||||
|
{
|
||||||
|
FUniqueNetIdRepl UniqueNetID = PlayerState->GetUniqueId();
|
||||||
|
bool bWasKicked = KickPlayer(BannedPlayer, BanReason);
|
||||||
|
|
||||||
|
if (bWasKicked)
|
||||||
|
{
|
||||||
|
BanList.Add(UniqueNetID, BanReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bWasKicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should really be handled in the game mode asking game session, but I didn't want to force a custom game session AND game mode
|
||||||
|
// If done in the game mode, we could check prior to actually spooling up any player information in ApproveLogin
|
||||||
|
virtual void PostLogin(APlayerController* NewPlayer) override
|
||||||
|
{
|
||||||
|
if (APlayerState* PlayerState = (NewPlayer != NULL) ? NewPlayer->PlayerState : NULL)
|
||||||
|
{
|
||||||
|
FUniqueNetIdRepl UniqueNetID = PlayerState->GetUniqueId();
|
||||||
|
|
||||||
|
if (BanList.Contains(UniqueNetID))
|
||||||
|
{
|
||||||
|
KickPlayer(NewPlayer, BanList[UniqueNetID]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AAdvancedGameSession::AAdvancedGameSession(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "Online.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#include "Interfaces/OnlineIdentityInterface.h"
|
||||||
|
#include "Interfaces/OnlineUserInterface.h"
|
||||||
|
#include "Interfaces/OnlinePresenceInterface.h"
|
||||||
|
#include "Engine/GameInstance.h"
|
||||||
|
#include "Engine/LocalPlayer.h"
|
||||||
|
|
||||||
|
#include "UObject/UObjectIterator.h"
|
||||||
|
|
||||||
|
#include "AdvancedIdentityLibrary.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
//General Advanced Sessions Log
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(AdvancedIdentityLog, Log, All);
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class UAdvancedIdentityLibrary : public UBlueprintFunctionLibrary
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
//********* Identity Functions *************//
|
||||||
|
|
||||||
|
// Get the login status of a local player
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject"))
|
||||||
|
static void GetLoginStatus(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetID, EBPLoginStatus & LoginStatus, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
// Get the auth token for a local player
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject"))
|
||||||
|
static void GetPlayerAuthToken(UObject* WorldContextObject, APlayerController * PlayerController, FString & AuthToken, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
// Get a players nickname
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedIdentity", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void GetPlayerNickname(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetID, FString & PlayerNickname);
|
||||||
|
|
||||||
|
//********* User Account Functions *************//
|
||||||
|
|
||||||
|
// Get a users account
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity|UserAccount", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject"))
|
||||||
|
static void GetUserAccount(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetId, FBPUserOnlineAccount & AccountInfo, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
// Get all known users accounts
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity|UserAccount", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject"))
|
||||||
|
static void GetAllUserAccounts(UObject* WorldContextObject, TArray<FBPUserOnlineAccount> & AccountInfos, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
// Get a user account access token
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedIdentity|UserAccount")
|
||||||
|
static void GetUserAccountAccessToken(const FBPUserOnlineAccount & AccountInfo, FString & AccessToken);
|
||||||
|
|
||||||
|
// Get a user account Auth attribute (depends on subsystem)
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity|UserAccount", meta = (ExpandEnumAsExecs = "Result"))
|
||||||
|
static void GetUserAccountAuthAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, FString & AuthAttribute, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
// Set a user account attribute (depends on subsystem)
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity|UserAccount", meta = (ExpandEnumAsExecs = "Result"))
|
||||||
|
static void SetUserAccountAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, const FString & NewAttributeValue, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
// Get user ID
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedIdentity|UserAccount")
|
||||||
|
static void GetUserID(const FBPUserOnlineAccount & AccountInfo, FBPUniqueNetId & UniqueNetID);
|
||||||
|
|
||||||
|
// Get user accounts real name if possible
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedIdentity|UserAccount")
|
||||||
|
static void GetUserAccountRealName(const FBPUserOnlineAccount & AccountInfo, FString & UserName);
|
||||||
|
|
||||||
|
// Get user account display name if possible
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedIdentity|UserAccount")
|
||||||
|
static void GetUserAccountDisplayName(const FBPUserOnlineAccount & AccountInfo, FString & DisplayName);
|
||||||
|
|
||||||
|
// Get user account attribute (depends on subsystem)
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedIdentity|UserAccount", meta = (ExpandEnumAsExecs = "Result"))
|
||||||
|
static void GetUserAccountAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, FString & AttributeValue, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
|
||||||
|
};
|
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Modules/ModuleManager.h"
|
||||||
|
|
||||||
|
class AdvancedSessions : public IModuleInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** IModuleInterface implementation */
|
||||||
|
void StartupModule();
|
||||||
|
void ShutdownModule();
|
||||||
|
};
|
@ -0,0 +1,213 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "Online.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#include "Interfaces/OnlineFriendsInterface.h"
|
||||||
|
#include "Interfaces/OnlineUserInterface.h"
|
||||||
|
#include "Interfaces/OnlineMessageInterface.h"
|
||||||
|
#include "Interfaces/OnlinePresenceInterface.h"
|
||||||
|
#include "Engine/GameInstance.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
|
||||||
|
#include "GameFramework/GameModeBase.h"
|
||||||
|
#include "GameFramework/GameSession.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 Admin Functions *************//
|
||||||
|
|
||||||
|
// Kick a player from the currently active game session, only available on the server
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static bool KickPlayer(UObject* WorldContextObject, APlayerController* PlayerToKick, FText KickReason);
|
||||||
|
|
||||||
|
// Ban a player from the currently active game session, only available on the server
|
||||||
|
// Note that the default gamesession class does not implement an actual ban list and just kicks when this is called
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static bool BanPlayer(UObject* WorldContextObject, APlayerController* PlayerToBan, FText BanReason);
|
||||||
|
|
||||||
|
//********* Session Search Functions *************//
|
||||||
|
|
||||||
|
// Adds or modifies session settings in an existing array depending on if they exist already or not
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo")
|
||||||
|
static void AddOrModifyExtraSettings(UPARAM(ref) TArray<FSessionPropertyKeyPair> & SettingsArray, UPARAM(ref) TArray<FSessionPropertyKeyPair> & NewOrChangedSettings, TArray<FSessionPropertyKeyPair> & 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<FSessionPropertyKeyPair> & ExtraSettings);
|
||||||
|
|
||||||
|
// Get the current session state
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void GetSessionState(UObject* WorldContextObject, EBPOnlineSessionState &SessionState);
|
||||||
|
|
||||||
|
// Get the current session settings
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "Result", WorldContext = "WorldContextObject"))
|
||||||
|
static void GetSessionSettings(UObject* WorldContextObject, int32 &NumConnections, int32 &NumPrivateConnections, bool &bIsLAN, bool &bIsDedicated, bool &bAllowInvites, bool &bAllowJoinInProgress, bool &bIsAnticheatEnabled, int32 &BuildUniqueID, TArray<FSessionPropertyKeyPair> &ExtraSettings, EBlueprintResultSwitch &Result);
|
||||||
|
|
||||||
|
// Check if someone is in the current session
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void IsPlayerInSession(UObject* WorldContextObject, const FBPUniqueNetId &PlayerToCheck, bool &bIsInSession);
|
||||||
|
|
||||||
|
// Make a literal session search parameter
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo|Literals")
|
||||||
|
static FSessionsSearchSetting MakeLiteralSessionSearchProperty(FSessionPropertyKeyPair SessionSearchProperty, EOnlineComparisonOpRedux ComparisonOp);
|
||||||
|
|
||||||
|
|
||||||
|
//********* Session Information Functions ***********//
|
||||||
|
|
||||||
|
// Check if a session result is valid or not
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo")
|
||||||
|
static bool IsValidSession(const FBlueprintSessionResult & SessionResult);
|
||||||
|
|
||||||
|
// Get a string copy of a session ID
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo")
|
||||||
|
static void GetSessionID_AsString(const FBlueprintSessionResult & SessionResult, FString& SessionID);
|
||||||
|
|
||||||
|
// Get a string copy of the current session ID
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|SessionInfo", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void GetCurrentSessionID_AsString(UObject* WorldContextObject, FString& SessionID);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
|
||||||
|
// Thanks CriErr for submission
|
||||||
|
|
||||||
|
|
||||||
|
// Get session property Key Name value
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo")
|
||||||
|
static FName GetSessionPropertyKey(const FSessionPropertyKeyPair& SessionProperty);
|
||||||
|
|
||||||
|
// Find session property by Name
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "Result"))
|
||||||
|
static void FindSessionPropertyByName(const TArray<FSessionPropertyKeyPair>& ExtraSettings, FName SettingsName, EBlueprintResultSwitch &Result, FSessionPropertyKeyPair& OutProperty);
|
||||||
|
|
||||||
|
// Find session property index by Name
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "Result"))
|
||||||
|
static void FindSessionPropertyIndexByName(const TArray<FSessionPropertyKeyPair>& ExtraSettings, FName SettingName, EBlueprintResultSwitch &Result, int32& OutIndex);
|
||||||
|
|
||||||
|
/// Removed the Index_None part of the last function, that isn't accessible in blueprint, better to return success/failure
|
||||||
|
// End Thanks CriErr :p
|
||||||
|
|
||||||
|
// Get session custom information key/value as Byte (For Enums)
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult"))
|
||||||
|
static void GetSessionPropertyByte(const TArray<FSessionPropertyKeyPair> & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, uint8 &SettingValue);
|
||||||
|
|
||||||
|
// Get session custom information key/value as Bool
|
||||||
|
// Steam only currently supports Int,Float,String,BYTE values for search filtering!!!
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSessions|SessionInfo", meta = (ExpandEnumAsExecs = "SearchResult"))
|
||||||
|
static void GetSessionPropertyBool(const TArray<FSessionPropertyKeyPair> & ExtraSettings, FName SettingName, ESessionSettingSearchResult &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<FSessionPropertyKeyPair> & ExtraSettings, FName SettingName, ESessionSettingSearchResult &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<FSessionPropertyKeyPair> & ExtraSettings, FName SettingName, ESessionSettingSearchResult &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<FSessionPropertyKeyPair> & ExtraSettings, FName SettingName, ESessionSettingSearchResult &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
|
||||||
|
// Steam only currently supports Int,Float,String,BYTE values for search filtering!
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Get the unique net id of a network player who is assigned the the given player state
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerID")
|
||||||
|
static void GetUniqueNetIDFromPlayerState(APlayerState *PlayerState, FBPUniqueNetId &UniqueNetId);
|
||||||
|
|
||||||
|
// Return True if Unique Net ID is valid
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedSessions|PlayerInfo|PlayerID")
|
||||||
|
static bool IsValidUniqueNetID(const FBPUniqueNetId &UniqueNetId);
|
||||||
|
|
||||||
|
/* Returns true if the values are equal (A == B) */
|
||||||
|
UFUNCTION(BlueprintPure, meta = (DisplayName = "Equal Unique Net ID", CompactNodeTitle = "==", Keywords = "== equal"), Category = "Online|AdvancedSessions|PlayerInfo|PlayerID")
|
||||||
|
static bool EqualEqual_UNetIDUnetID(const FBPUniqueNetId &A, const FBPUniqueNetId &B);
|
||||||
|
|
||||||
|
/** Converts a FBPUniqueNetID into a FUniqueNetID_Repl */
|
||||||
|
UFUNCTION(BlueprintPure, meta = (DisplayName = "ToUniqueNetIDRepl (Unique Net ID)", CompactNodeTitle = "->", BlueprintAutocast), Category = "Online|AdvancedSessions|PlayerInfo|PlayerID")
|
||||||
|
static FUniqueNetIdRepl Conv_BPUniqueIDToUniqueNetIDRepl(const FBPUniqueNetId& InUniqueID);
|
||||||
|
|
||||||
|
// 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", meta = (bIgnoreSelf = "true", WorldContext = "WorldContextObject", DisplayName = "GetNumNetworkPlayers"))
|
||||||
|
static void GetNumberOfNetworkPlayers(UObject* WorldContextObject, 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);
|
||||||
|
|
||||||
|
//**** Seamless travel Functions ****//
|
||||||
|
|
||||||
|
//Exposes Server travel to blueprint
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Online|AdvancedSessions|Seamless", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
|
||||||
|
static bool ServerTravel(UObject* WorldContextObject, const FString& InURL, bool bAbsolute, bool bShouldSkipGameNotify);
|
||||||
|
|
||||||
|
};
|
@ -0,0 +1,99 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Online.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#include "Interfaces/VoiceInterface.h"
|
||||||
|
//#include "OnlineFriendsInterface.h"
|
||||||
|
//#include "OnlineUserInterface.h"
|
||||||
|
//#include "OnlineMessageInterface.h"
|
||||||
|
//#include "OnlinePresenceInterface.h"
|
||||||
|
#include "Engine/GameInstance.h"
|
||||||
|
//#include "OnlineSessionInterface.h"
|
||||||
|
|
||||||
|
#include "UObject/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", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void IsHeadsetPresent(UObject* WorldContextObject, bool & bHasHeadset, uint8 LocalPlayerNum = 0);
|
||||||
|
|
||||||
|
// Starts networked voice, allows push to talk in coordination with StopNetworkedVoice
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void StartNetworkedVoice(UObject* WorldContextObject, uint8 LocalPlayerNum = 0);
|
||||||
|
|
||||||
|
// Stops networked voice, allows push to talk in coordination with StartNetworkedVoice
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void StopNetworkedVoice(UObject* WorldContextObject, uint8 LocalPlayerNum = 0);
|
||||||
|
|
||||||
|
// Registers a local player as someone interested in voice data
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static bool RegisterLocalTalker(UObject* WorldContextObject, uint8 LocalPlayerNum = 0);
|
||||||
|
|
||||||
|
// Registers all signed in players as local talkers
|
||||||
|
// This is already done automatically, only do it manually if you unregistered someone
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void RegisterAllLocalTalkers(UObject* WorldContextObject);
|
||||||
|
|
||||||
|
// UnRegisters local player as a local talker
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void UnRegisterLocalTalker(UObject* WorldContextObject, uint8 LocalPlayerNum = 0);
|
||||||
|
|
||||||
|
// UnRegisters all signed in players as local talkers
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void UnRegisterAllLocalTalkers(UObject* WorldContextObject);
|
||||||
|
|
||||||
|
// Registers a remote player as a talker
|
||||||
|
// This is already done automatically, only do it manually if you unregistered someone
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static bool RegisterRemoteTalker(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId);
|
||||||
|
|
||||||
|
// UnRegisters a remote player as a talker
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static bool UnRegisterRemoteTalker(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId);
|
||||||
|
|
||||||
|
// UnRegisters all remote players as talkers
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedVoice", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void RemoveAllRemoteTalkers(UObject* WorldContextObject);
|
||||||
|
|
||||||
|
// Returns whether a local player is currently talking
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static bool IsLocalPlayerTalking(UObject* WorldContextObject, uint8 LocalPlayerNum);
|
||||||
|
|
||||||
|
// Returns whether a remote player is currently talking
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static bool IsRemotePlayerTalking(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId);
|
||||||
|
|
||||||
|
// Returns whether a player is muted for the specified local player
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static bool IsPlayerMuted(UObject* WorldContextObject, 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", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static bool MuteRemoteTalker(UObject* WorldContextObject, 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", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static bool UnMuteRemoteTalker(UObject* WorldContextObject, uint8 LocalUserNum, const FBPUniqueNetId& UniqueNetId, bool bIsSystemWide = false);
|
||||||
|
|
||||||
|
// Gets the number of local talkers for this system
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedVoice|VoiceInfo", meta = (WorldContext = "WorldContextObject"))
|
||||||
|
static void GetNumLocalTalkers(UObject* WorldContextObject, int32 & NumLocalTalkers);
|
||||||
|
};
|
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Interfaces/OnlineIdentityInterface.h"
|
||||||
|
#include "Engine/LocalPlayer.h"
|
||||||
|
#include "AutoLoginUserCallbackProxy.generated.h"
|
||||||
|
|
||||||
|
UCLASS(MinimalAPI)
|
||||||
|
class UAutoLoginUserCallbackProxy : 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the player into the online service using parameters passed on the
|
||||||
|
* command line. Expects -AUTH_LOGIN=<UserName> -AUTH_PASSWORD=<password>. If either
|
||||||
|
* are missing, the function returns false and doesn't start the login
|
||||||
|
* process
|
||||||
|
*
|
||||||
|
* @param LocalUserNum the controller number of the associated user
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedIdentity")
|
||||||
|
static UAutoLoginUserCallbackProxy* AutoLoginUser(UObject* WorldContextObject, int32 LocalUserNum);
|
||||||
|
|
||||||
|
// 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(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& ErrorVal);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The controller number of the associated user
|
||||||
|
int32 LocalUserNumber;
|
||||||
|
|
||||||
|
// The delegate executed by the online subsystem
|
||||||
|
FOnLoginCompleteDelegate Delegate;
|
||||||
|
|
||||||
|
// Handle to the registered OnDestroySessionComplete delegate
|
||||||
|
FDelegateHandle DelegateHandle;
|
||||||
|
|
||||||
|
// The world context object in which this call is taking place
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
@ -0,0 +1,435 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
//#include "EngineMinimal.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "GameFramework/PlayerState.h"
|
||||||
|
//#include "Core.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
#include "OnlineSessionSettings.h"
|
||||||
|
#include "OnlineDelegateMacros.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#include "OnlineSubsystemImpl.h"
|
||||||
|
#include "OnlineSubsystemUtils.h"
|
||||||
|
#include "OnlineSubsystemUtilsModule.h"
|
||||||
|
#include "GameFramework/PlayerController.h"
|
||||||
|
#include "Modules/ModuleManager.h"
|
||||||
|
#include "OnlineSubsystemUtilsClasses.h"
|
||||||
|
#include "BlueprintDataDefinitions.generated.h"
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EBPUserPrivileges : uint8
|
||||||
|
{
|
||||||
|
/** Whether the user can play at all, online or offline - may be age restricted */
|
||||||
|
CanPlay,
|
||||||
|
/** Whether the user can play in online modes */
|
||||||
|
CanPlayOnline,
|
||||||
|
/** Whether the user can use voice and text chat */
|
||||||
|
CanCommunicateOnline,
|
||||||
|
/** Whether the user can use content generated by other users */
|
||||||
|
CanUseUserGeneratedContent
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EBPLoginStatus : uint8
|
||||||
|
{
|
||||||
|
/** Player has not logged in or chosen a local profile */
|
||||||
|
NotLoggedIn,
|
||||||
|
/** Player is using a local profile but is not logged in */
|
||||||
|
UsingLocalProfile,
|
||||||
|
/** Player has been validated by the platform specific authentication service */
|
||||||
|
LoggedIn
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType)
|
||||||
|
struct FBPUserOnlineAccount
|
||||||
|
{
|
||||||
|
GENERATED_USTRUCT_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
TSharedPtr<FUserOnlineAccount> UserAccountInfo;
|
||||||
|
|
||||||
|
FBPUserOnlineAccount()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
FBPUserOnlineAccount(TSharedPtr<FUserOnlineAccount> UserAccount)
|
||||||
|
{
|
||||||
|
UserAccountInfo = UserAccount;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
UENUM()
|
||||||
|
enum class ESessionSettingSearchResult : uint8
|
||||||
|
{
|
||||||
|
// Found the setting
|
||||||
|
Found,
|
||||||
|
|
||||||
|
// Did not find the setting
|
||||||
|
NotFound,
|
||||||
|
|
||||||
|
// Was not the correct type
|
||||||
|
WrongType
|
||||||
|
};
|
||||||
|
|
||||||
|
// This makes a lot of the blueprint functions cleaner
|
||||||
|
UENUM()
|
||||||
|
enum class EBlueprintResultSwitch : uint8
|
||||||
|
{
|
||||||
|
// On Success
|
||||||
|
OnSuccess,
|
||||||
|
|
||||||
|
// On Failure
|
||||||
|
OnFailure
|
||||||
|
};
|
||||||
|
|
||||||
|
// This makes a lot of the blueprint functions cleaner
|
||||||
|
UENUM()
|
||||||
|
enum class EBlueprintAsyncResultSwitch : uint8
|
||||||
|
{
|
||||||
|
// On Success
|
||||||
|
OnSuccess,
|
||||||
|
|
||||||
|
// Still loading
|
||||||
|
AsyncLoading,
|
||||||
|
// On Failure
|
||||||
|
OnFailure
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is to define server type searches
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EBPServerPresenceSearchType : uint8
|
||||||
|
{
|
||||||
|
AllServers,
|
||||||
|
ClientServersOnly,
|
||||||
|
DedicatedServersOnly
|
||||||
|
};
|
||||||
|
|
||||||
|
// Wanted this to be switchable in the editor
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EBPOnlinePresenceState : uint8
|
||||||
|
{
|
||||||
|
Online,
|
||||||
|
Offline,
|
||||||
|
Away,
|
||||||
|
ExtendedAway,
|
||||||
|
DoNotDisturb,
|
||||||
|
Chat
|
||||||
|
};
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EBPOnlineSessionState : uint8
|
||||||
|
{
|
||||||
|
/** 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<const FUniqueNetId> UniqueNetId;
|
||||||
|
const FUniqueNetId * UniqueNetIdPtr;
|
||||||
|
|
||||||
|
void SetUniqueNetId(const TSharedPtr<const FUniqueNetId> &ID)
|
||||||
|
{
|
||||||
|
bUseDirectPointer = false;
|
||||||
|
UniqueNetIdPtr = nullptr;
|
||||||
|
UniqueNetId = ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetUniqueNetId(const FUniqueNetId *ID)
|
||||||
|
{
|
||||||
|
bUseDirectPointer = true;
|
||||||
|
UniqueNetIdPtr = ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValid() const
|
||||||
|
{
|
||||||
|
if (bUseDirectPointer && UniqueNetIdPtr != nullptr && UniqueNetIdPtr->IsValid())
|
||||||
|
{
|
||||||
|
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<FUniqueNetId*>*/(UniqueNetIdPtr);
|
||||||
|
}
|
||||||
|
else if (UniqueNetId.IsValid())
|
||||||
|
{
|
||||||
|
return UniqueNetId.Get();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding in a compare operator so that std functions will work with this struct
|
||||||
|
FORCEINLINE bool operator==(const FBPUniqueNetId& Other) const
|
||||||
|
{
|
||||||
|
return (IsValid() && Other.IsValid() && (*GetUniqueNetId() == *Other.GetUniqueNetId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE bool operator!=(const FBPUniqueNetId& Other) const
|
||||||
|
{
|
||||||
|
return !(IsValid() && Other.IsValid() && (*GetUniqueNetId() == *Other.GetUniqueNetId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
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 FBPFriendPresenceInfo
|
||||||
|
{
|
||||||
|
GENERATED_USTRUCT_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend")
|
||||||
|
bool bIsOnline = false;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend")
|
||||||
|
bool bIsPlaying = false;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend")
|
||||||
|
bool bIsPlayingThisGame = false;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend")
|
||||||
|
bool bIsJoinable = false;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend")
|
||||||
|
bool bHasVoiceSupport = false;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend")
|
||||||
|
EBPOnlinePresenceState PresenceState = EBPOnlinePresenceState::Offline;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend")
|
||||||
|
FString StatusString;
|
||||||
|
|
||||||
|
FBPFriendPresenceInfo()
|
||||||
|
{
|
||||||
|
bIsOnline = false;
|
||||||
|
bIsPlaying = false;
|
||||||
|
bIsPlayingThisGame = false;
|
||||||
|
bIsJoinable = false;
|
||||||
|
bHasVoiceSupport = false;
|
||||||
|
PresenceState = EBPOnlinePresenceState::Offline;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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")
|
||||||
|
EBPOnlinePresenceState OnlineState = EBPOnlinePresenceState::Offline;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend")
|
||||||
|
FBPUniqueNetId UniqueNetId;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend")
|
||||||
|
bool bIsPlayingSameGame = false;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Online|Friend")
|
||||||
|
FBPFriendPresenceInfo PresenceInfo;
|
||||||
|
|
||||||
|
FBPFriendInfo()
|
||||||
|
{
|
||||||
|
OnlineState = EBPOnlinePresenceState::Offline;
|
||||||
|
bIsPlayingSameGame = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** The types of comparison operations for a given search query */
|
||||||
|
// Used to compare session properties
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EOnlineComparisonOpRedux : uint8
|
||||||
|
{
|
||||||
|
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 */
|
||||||
|
EOnlineComparisonOpRedux 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<FUniqueNetId*>(UniqueNetIdPtr);
|
||||||
|
if (APlayerState* PlayerState = (PlayerController != NULL) ? PlayerController->PlayerState : NULL)
|
||||||
|
{
|
||||||
|
UserID = PlayerState->GetUniqueId().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<const FUniqueNetId>& GetUniqueNetId()
|
||||||
|
TSharedPtr</*class*/ const FUniqueNetId> 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 CompOp)
|
||||||
|
{
|
||||||
|
FOnlineSessionSearchParam* SearchParam = SearchParams.Find(Key);
|
||||||
|
|
||||||
|
TEnumAsByte<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
|
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
#include "BlueprintDataDefinitions.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<APlayerController> 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
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
@ -0,0 +1,107 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "BlueprintDataDefinitions.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, for dedicated servers leave UsePresence as false and set IsDedicatedServer to true. Dedicated servers don't use presence.
|
||||||
|
* @param PublicConnections When doing a 'listen' server, this must be >=2 (ListenServer itself counts as a connection)
|
||||||
|
* @param bUseLAN When you want to play LAN, the level to play on must be loaded with option 'bIsLanMatch'
|
||||||
|
* @param bUseLobbiesIfAvailable Used to flag the subsystem to use a lobby api instead of general hosting if the API supports it, generally true on steam for listen servers and false for dedicated
|
||||||
|
* Must be true for a 'listen' server (Map must be loaded with option 'listen'), false for a 'dedicated' server.
|
||||||
|
* @param bShouldAdvertise Set to true when the OnlineSubsystem should list your server when someone is searching for servers. Otherwise the server is hidden and only join via invite is possible.
|
||||||
|
* @param bUseLobbiesVoiceChatIfAvailable Set to true to setup voice chat lobbies if the API supports it
|
||||||
|
* @param bStartAfterCreate Set to true to start the session after it's created. If false you need to manually call StartSession when ready.
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject",AutoCreateRefTerm="ExtraSettings"), Category = "Online|AdvancedSessions")
|
||||||
|
static UCreateSessionCallbackProxyAdvanced* CreateAdvancedSession(UObject* WorldContextObject, const TArray<FSessionPropertyKeyPair>& ExtraSettings, class APlayerController* PlayerController = NULL, int32 PublicConnections = 100, int32 PrivateConnections = 0, bool bUseLAN = false, bool bAllowInvites = true, bool bIsDedicatedServer = false, /*bool bUsePresence = true,*/ bool bUseLobbiesIfAvailable = true, bool bAllowJoinViaPresence = true, bool bAllowJoinViaPresenceFriendsOnly = false, bool bAntiCheatProtected = false, bool bUsesStats = false, bool bShouldAdvertise = true, bool bUseLobbiesVoiceChatIfAvailable = false, bool bStartAfterCreate = true);
|
||||||
|
|
||||||
|
// UOnlineBlueprintCallProxyBase interface
|
||||||
|
virtual void Activate() override;
|
||||||
|
// End of UOnlineBlueprintCallProxyBase interface
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Internal callback when session creation completes, optionally calls StartSession
|
||||||
|
void OnCreateCompleted(FName SessionName, bool bWasSuccessful);
|
||||||
|
|
||||||
|
// Internal callback when session start completes
|
||||||
|
void OnStartCompleted(FName SessionName, bool bWasSuccessful);
|
||||||
|
|
||||||
|
// The player controller triggering things
|
||||||
|
TWeakObjectPtr<APlayerController> 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;
|
||||||
|
|
||||||
|
// Number of private connections
|
||||||
|
int NumPrivateConnections;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// Whether to use the presence option
|
||||||
|
bool bUsePresence;
|
||||||
|
|
||||||
|
// Whether to prefer the use of lobbies for hosting if the api supports them
|
||||||
|
bool bUseLobbiesIfAvailable;
|
||||||
|
|
||||||
|
// Whether to allow joining via presence
|
||||||
|
bool bAllowJoinViaPresence;
|
||||||
|
|
||||||
|
// Allow joining via presence for friends only
|
||||||
|
bool bAllowJoinViaPresenceFriendsOnly;
|
||||||
|
|
||||||
|
// Delcare the server to be anti cheat protected
|
||||||
|
bool bAntiCheatProtected;
|
||||||
|
|
||||||
|
// Record Stats
|
||||||
|
bool bUsesStats;
|
||||||
|
|
||||||
|
// Should advertise server?
|
||||||
|
bool bShouldAdvertise;
|
||||||
|
|
||||||
|
// Whether to prefer the use of voice chat lobbies if the api supports them
|
||||||
|
bool bUseLobbiesVoiceChatIfAvailable;
|
||||||
|
|
||||||
|
// Whether to start the session automatically after it is created
|
||||||
|
bool bStartAfterCreate;
|
||||||
|
|
||||||
|
// Store extra settings
|
||||||
|
TArray<FSessionPropertyKeyPair> ExtraSettings;
|
||||||
|
|
||||||
|
// The world context object in which this call is taking place
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
#include "BlueprintDataDefinitions.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 sessions, Generally for almost all uses you should be using the engines native Destroy Session node instead.
|
||||||
|
* This exists for people using StartSession and optionally hand managing the session state.
|
||||||
|
*/
|
||||||
|
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<APlayerController> 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
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Engine/LocalPlayer.h"
|
||||||
|
#include "FindFriendSessionCallbackProxy.generated.h"
|
||||||
|
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(AdvancedFindFriendSessionLog, Log, All);
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintFindFriendSessionDelegate, const TArray<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 TArray<FOnlineSessionSearchResult>& SessionInfo);
|
||||||
|
|
||||||
|
// The player controller triggering things
|
||||||
|
TWeakObjectPtr<APlayerController> 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
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,109 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
#include "FindSessionsCallbackProxy.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "FindSessionsCallbackProxyAdvanced.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
FORCEINLINE bool operator==(const FBlueprintSessionResult& A, const FBlueprintSessionResult& B)
|
||||||
|
{
|
||||||
|
return (A.OnlineResult.IsValid() == B.OnlineResult.IsValid() && (A.OnlineResult.GetSessionIdStr() == B.OnlineResult.GetSessionIdStr()));
|
||||||
|
}
|
||||||
|
|
||||||
|
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, EBPServerPresenceSearchType ServerTypeToSearch, const TArray<FSessionsSearchSetting> &Filters, bool bEmptyServersOnly = false, bool bNonEmptyServersOnly = false, bool bSecureServersOnly = false, /*bool bSearchLobbies = true,*/ int MinSlotsAvailable = 0);
|
||||||
|
|
||||||
|
static bool CompareVariants(const FVariantData &A, const FVariantData &B, EOnlineComparisonOpRedux 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<FBlueprintSessionResult> &SessionResults, const TArray<FSessionsSearchSetting> &Filters, TArray<FBlueprintSessionResult> &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);
|
||||||
|
|
||||||
|
bool bRunSecondSearch;
|
||||||
|
bool bIsOnSecondSearch;
|
||||||
|
|
||||||
|
TArray<FBlueprintSessionResult> SessionSearchResults;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The player controller triggering things
|
||||||
|
TWeakObjectPtr<APlayerController> PlayerControllerWeakPtr;
|
||||||
|
|
||||||
|
// The delegate executed by the online subsystem
|
||||||
|
FOnFindSessionsCompleteDelegate Delegate;
|
||||||
|
|
||||||
|
// Handle to the registered OnFindSessionsComplete delegate
|
||||||
|
FDelegateHandle DelegateHandle;
|
||||||
|
|
||||||
|
// Object to track search results
|
||||||
|
TSharedPtr<FOnlineSessionSearch> SearchObject;
|
||||||
|
TSharedPtr<FOnlineSessionSearch> SearchObjectDedicated;
|
||||||
|
|
||||||
|
// Whether or not to search LAN
|
||||||
|
bool bUseLAN;
|
||||||
|
|
||||||
|
// Whether or not to search for dedicated servers
|
||||||
|
EBPServerPresenceSearchType ServerSearchType;
|
||||||
|
|
||||||
|
// Maximum number of results to return
|
||||||
|
int MaxResults;
|
||||||
|
|
||||||
|
// Store extra settings
|
||||||
|
TArray<FSessionsSearchSetting> SearchSettings;
|
||||||
|
|
||||||
|
// Search for empty servers only
|
||||||
|
bool bEmptyServersOnly;
|
||||||
|
|
||||||
|
// Search for non empty servers only
|
||||||
|
bool bNonEmptyServersOnly;
|
||||||
|
|
||||||
|
// Search for secure servers only
|
||||||
|
bool bSecureServersOnly;
|
||||||
|
|
||||||
|
// Search through lobbies
|
||||||
|
//bool bSearchLobbies;
|
||||||
|
|
||||||
|
// Min slots requires to search
|
||||||
|
int MinSlotsAvailable;
|
||||||
|
|
||||||
|
// The world context object in which this call is taking place
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Engine/LocalPlayer.h"
|
||||||
|
#include "GetFriendsCallbackProxy.generated.h"
|
||||||
|
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(AdvancedGetFriendsLog, Log, All);
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintGetFriendsListDelegate, const TArray<FBPFriendInfo>&, 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<APlayerController> 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 FriendListToGet;
|
||||||
|
|
||||||
|
// The world context object in which this call is taking place
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "GetRecentPlayersCallbackProxy.generated.h"
|
||||||
|
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(AdvancedGetRecentPlayersLog, Log, All);
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintGetRecentPlayersDelegate, const TArray<FBPOnlineRecentPlayer>&, 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<APlayerController> 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
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Interfaces/OnlineIdentityInterface.h"
|
||||||
|
#include "GetUserPrivilegeCallbackProxy.generated.h"
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FBlueprintGetUserPrivilegeDelegate,/* const &FBPUniqueNetId, PlayerID,*/ EBPUserPrivileges, QueriedPrivilege, bool, HadPrivilege);
|
||||||
|
|
||||||
|
UCLASS(MinimalAPI)
|
||||||
|
class UGetUserPrivilegeCallbackProxy : public UOnlineBlueprintCallProxyBase
|
||||||
|
{
|
||||||
|
GENERATED_UCLASS_BODY()
|
||||||
|
|
||||||
|
// Called when there is a successful destroy
|
||||||
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FBlueprintGetUserPrivilegeDelegate OnSuccess;
|
||||||
|
|
||||||
|
// Called when there is an unsuccessful destroy
|
||||||
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FEmptyOnlineDelegate OnFailure;
|
||||||
|
|
||||||
|
// Gets the privilage of the user
|
||||||
|
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedIdentity")
|
||||||
|
static UGetUserPrivilegeCallbackProxy* GetUserPrivilege(UObject* WorldContextObject, const EBPUserPrivileges & PrivilegeToCheck, const FBPUniqueNetId & PlayerUniqueNetID);
|
||||||
|
|
||||||
|
// 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(const FUniqueNetId& PlayerID, EUserPrivileges::Type Privilege, uint32 Result);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The player controller triggering things
|
||||||
|
FBPUniqueNetId PlayerUniqueNetID;
|
||||||
|
|
||||||
|
// Privilege to check
|
||||||
|
EBPUserPrivileges UserPrivilege;
|
||||||
|
|
||||||
|
// The world context object in which this call is taking place
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Interfaces/OnlineIdentityInterface.h"
|
||||||
|
#include "Engine/LocalPlayer.h"
|
||||||
|
#include "LoginUserCallbackProxy.generated.h"
|
||||||
|
|
||||||
|
UCLASS(MinimalAPI)
|
||||||
|
class ULoginUserCallbackProxy : 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;
|
||||||
|
|
||||||
|
// Logs into the identity interface
|
||||||
|
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject", AdvancedDisplay = "AuthType"), Category = "Online|AdvancedIdentity")
|
||||||
|
static ULoginUserCallbackProxy* LoginUser(UObject* WorldContextObject, class APlayerController* PlayerController, FString UserID, FString UserToken, FString AuthType);
|
||||||
|
|
||||||
|
// 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(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& ErrorVal);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The player controller triggering things
|
||||||
|
TWeakObjectPtr<APlayerController> PlayerControllerWeakPtr;
|
||||||
|
|
||||||
|
// The user ID
|
||||||
|
FString UserID;
|
||||||
|
|
||||||
|
// The user pass / token
|
||||||
|
FString UserToken;
|
||||||
|
|
||||||
|
FString AuthType;
|
||||||
|
|
||||||
|
// The delegate executed by the online subsystem
|
||||||
|
FOnLoginCompleteDelegate Delegate;
|
||||||
|
|
||||||
|
// Handle to the registered OnDestroySessionComplete delegate
|
||||||
|
FDelegateHandle DelegateHandle;
|
||||||
|
|
||||||
|
// The world context object in which this call is taking place
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Interfaces/OnlineIdentityInterface.h"
|
||||||
|
#include "Engine/LocalPlayer.h"
|
||||||
|
#include "LogoutUserCallbackProxy.generated.h"
|
||||||
|
|
||||||
|
UCLASS(MinimalAPI)
|
||||||
|
class ULogoutUserCallbackProxy : 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;
|
||||||
|
|
||||||
|
// Logs out of the identity interface
|
||||||
|
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedIdentity")
|
||||||
|
static ULogoutUserCallbackProxy* LogoutUser(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(int LocalUserNum, bool bWasSuccessful);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The player controller triggering things
|
||||||
|
TWeakObjectPtr<APlayerController> PlayerControllerWeakPtr;
|
||||||
|
|
||||||
|
// The delegate executed by the online subsystem
|
||||||
|
FOnLogoutCompleteDelegate Delegate;
|
||||||
|
|
||||||
|
// Handle to the registered OnDestroySessionComplete delegate
|
||||||
|
FDelegateHandle DelegateHandle;
|
||||||
|
|
||||||
|
// The world context object in which this call is taking place
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#include "EngineMinimal.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"
|
||||||
|
|
||||||
|
|
||||||
|
/*#include "VoiceEngineImpl.h"
|
||||||
|
#include "VoiceInterfaceImpl.h"
|
||||||
|
#include "Voice.h""
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Found this in the steam controller, seems like a nice thought since steam is throwing errors
|
||||||
|
// Disable crazy warnings that claim that standard C library is "deprecated".
|
||||||
|
//#ifdef _MSC_VER
|
||||||
|
//#pragma warning(push)
|
||||||
|
//#pragma warning(disable:4996)
|
||||||
|
//#endif
|
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Engine/LocalPlayer.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<APlayerController> 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
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "StartSessionCallbackProxyAdvanced.generated.h"
|
||||||
|
|
||||||
|
UCLASS(MinimalAPI)
|
||||||
|
class UStartSessionCallbackProxyAdvanced : public UOnlineBlueprintCallProxyBase
|
||||||
|
{
|
||||||
|
GENERATED_UCLASS_BODY()
|
||||||
|
// Called when the session starts successfully
|
||||||
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FEmptyOnlineDelegate OnSuccess;
|
||||||
|
|
||||||
|
// Called when there is an error starting the session
|
||||||
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FEmptyOnlineDelegate OnFailure;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a session with the default online subsystem. The session needs to be previously created by calling the "CreateAdvancedSession" node.
|
||||||
|
* @param WorldContextObject
|
||||||
|
*/
|
||||||
|
UFUNCTION(
|
||||||
|
BlueprintCallable
|
||||||
|
, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject")
|
||||||
|
, Category = "Online|AdvancedSessions"
|
||||||
|
)
|
||||||
|
static UStartSessionCallbackProxyAdvanced* StartAdvancedSession(UObject* WorldContextObject);
|
||||||
|
|
||||||
|
// UOnlineBlueprintCallProxyBase interface
|
||||||
|
virtual void Activate() override;
|
||||||
|
// End of UOnlineBlueprintCallProxyBase interface
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Internal callback when session start completes
|
||||||
|
void OnStartCompleted(FName SessionName, bool bWasSuccessful);
|
||||||
|
|
||||||
|
// The delegate executed by the online subsystem
|
||||||
|
FOnStartSessionCompleteDelegate StartCompleteDelegate;
|
||||||
|
|
||||||
|
// Handles to the registered delegates above
|
||||||
|
FDelegateHandle StartCompleteDelegateHandle;
|
||||||
|
|
||||||
|
// The world context object in which this call is taking place
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
@ -0,0 +1,69 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/Engine.h"
|
||||||
|
#include "BlueprintDataDefinitions.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, you MUST fill in all categories or it will pass in values that you didn't want as default values
|
||||||
|
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject",AutoCreateRefTerm="ExtraSettings"), Category = "Online|AdvancedSessions")
|
||||||
|
static UUpdateSessionCallbackProxyAdvanced* UpdateSession(UObject* WorldContextObject, const TArray<FSessionPropertyKeyPair> &ExtraSettings, int32 PublicConnections = 100, int32 PrivateConnections = 0, bool bUseLAN = false, bool bAllowInvites = false, bool bAllowJoinInProgress = false, bool bRefreshOnlineData = true, bool bIsDedicatedServer = false, bool bShouldAdvertise = true);
|
||||||
|
|
||||||
|
// 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 = 100;
|
||||||
|
|
||||||
|
// Number of private connections
|
||||||
|
int NumPrivateConnections = 0;
|
||||||
|
|
||||||
|
// Whether or not to search LAN
|
||||||
|
bool bUseLAN = false;
|
||||||
|
|
||||||
|
// Whether or not to allow invites
|
||||||
|
bool bAllowInvites = true;
|
||||||
|
|
||||||
|
// Store extra settings
|
||||||
|
TArray<FSessionPropertyKeyPair> ExtraSettings;
|
||||||
|
|
||||||
|
// Whether to update the online data
|
||||||
|
bool bRefreshOnlineData = true;
|
||||||
|
|
||||||
|
// Allow joining in progress
|
||||||
|
bool bAllowJoinInProgress = true;
|
||||||
|
|
||||||
|
// Update whether this is a dedicated server or not
|
||||||
|
bool bDedicatedServer = false;
|
||||||
|
|
||||||
|
bool bShouldAdvertise = true;
|
||||||
|
|
||||||
|
// The world context object in which this call is taking place
|
||||||
|
TWeakObjectPtr<UObject> WorldContextObject;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,209 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
#include "AdvancedExternalUILibrary.h"
|
||||||
|
#include "Engine/LocalPlayer.h"
|
||||||
|
|
||||||
|
|
||||||
|
//General Log
|
||||||
|
DEFINE_LOG_CATEGORY(AdvancedExternalUILog);
|
||||||
|
|
||||||
|
void UAdvancedExternalUILibrary::ShowAccountUpgradeUI(UObject* WorldContextObject, const FBPUniqueNetId PlayerRequestingAccountUpgradeUI, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World);
|
||||||
|
|
||||||
|
if (!ExternalUIInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowAccountUpgradeUI Failed to get External UI interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalUIInterface->ShowAccountUpgradeUI(*PlayerRequestingAccountUpgradeUI.GetUniqueNetId());
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedExternalUILibrary::ShowProfileUI(UObject* WorldContextObject, const FBPUniqueNetId PlayerViewingProfile, const FBPUniqueNetId PlayerToViewProfileOf, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World);
|
||||||
|
|
||||||
|
if (!ExternalUIInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowProfileUI Failed to get External UI interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalUIInterface->ShowProfileUI(*PlayerViewingProfile.GetUniqueNetId(), *PlayerToViewProfileOf.GetUniqueNetId(), NULL);
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void UAdvancedExternalUILibrary::ShowWebURLUI(UObject* WorldContextObject, FString URLToShow, EBlueprintResultSwitch &Result, TArray<FString>& AllowedDomains, bool bEmbedded, bool bShowBackground, bool bShowCloseButton, int32 OffsetX, int32 OffsetY, int32 SizeX, int32 SizeY)
|
||||||
|
{
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World);
|
||||||
|
|
||||||
|
if (!ExternalUIInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowWebURLUI Failed to get External UI interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
URLToShow = URLToShow.Replace(TEXT("http://"), TEXT(""));
|
||||||
|
URLToShow = URLToShow.Replace(TEXT("https://"), TEXT(""));
|
||||||
|
|
||||||
|
FShowWebUrlParams Params;
|
||||||
|
Params.AllowedDomains = AllowedDomains;
|
||||||
|
Params.bEmbedded = bEmbedded;
|
||||||
|
Params.bShowBackground = bShowBackground;
|
||||||
|
Params.bShowCloseButton = bShowCloseButton;
|
||||||
|
Params.OffsetX = OffsetX;
|
||||||
|
Params.OffsetY = OffsetY;
|
||||||
|
Params.SizeX = SizeX;
|
||||||
|
Params.SizeY = SizeY;
|
||||||
|
|
||||||
|
ExternalUIInterface->ShowWebURL(URLToShow, Params);
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedExternalUILibrary::CloseWebURLUI(UObject* WorldContextObject)
|
||||||
|
{
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World);
|
||||||
|
|
||||||
|
if (!ExternalUIInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedExternalUILog, Warning, TEXT("CloseWebURLUI Failed to get External UI interface!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalUIInterface->CloseWebURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedExternalUILibrary::ShowLeaderBoardUI(UObject* WorldContextObject, FString LeaderboardName, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World);
|
||||||
|
|
||||||
|
if (!ExternalUIInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowLeaderboardsUI Failed to get External UI interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalUIInterface->ShowLeaderboardUI(LeaderboardName);
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UAdvancedExternalUILibrary::ShowInviteUI(UObject* WorldContextObject, APlayerController *PlayerController, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
if (!PlayerController)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowInviteUI Had a bad Player Controller!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World);
|
||||||
|
|
||||||
|
if (!ExternalUIInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowInviteUI Failed to get External UI interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerController->Player);
|
||||||
|
|
||||||
|
if (!Player)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowInviteUI Failed to get ULocalPlayer for the given PlayerController!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalUIInterface->ShowInviteUI(Player->GetControllerId(), NAME_GameSession);
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedExternalUILibrary::ShowFriendsUI(UObject* WorldContextObject, APlayerController *PlayerController, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
if (!PlayerController)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowFriendsUI Had a bad Player Controller!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineExternalUIPtr ExternalUIInterface = Online::GetExternalUIInterface(World);
|
||||||
|
|
||||||
|
if (!ExternalUIInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowFriendsUI Failed to get External UI interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerController->Player);
|
||||||
|
|
||||||
|
if (!Player)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedExternalUILog, Warning, TEXT("ShowFriendsUI Failed to get ULocalPlayer for the given PlayerController!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalUIInterface->ShowFriendsUI(Player->GetControllerId());
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
@ -0,0 +1,394 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
#include "AdvancedFriendsGameInstance.h"
|
||||||
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
#include "GameFramework/PlayerController.h"
|
||||||
|
|
||||||
|
//General Log
|
||||||
|
DEFINE_LOG_CATEGORY(AdvancedFriendsInterfaceLog);
|
||||||
|
|
||||||
|
UAdvancedFriendsGameInstance::UAdvancedFriendsGameInstance(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
, bCallFriendInterfaceEventsOnPlayerControllers(true)
|
||||||
|
, bCallIdentityInterfaceEventsOnPlayerControllers(true)
|
||||||
|
, bCallVoiceInterfaceEventsOnPlayerControllers(true)
|
||||||
|
, bEnableTalkingStatusDelegate(true)
|
||||||
|
, SessionInviteReceivedDelegate(FOnSessionInviteReceivedDelegate::CreateUObject(this, &ThisClass::OnSessionInviteReceivedMaster))
|
||||||
|
, SessionInviteAcceptedDelegate(FOnSessionUserInviteAcceptedDelegate::CreateUObject(this, &ThisClass::OnSessionInviteAcceptedMaster))
|
||||||
|
, PlayerTalkingStateChangedDelegate(FOnPlayerTalkingStateChangedDelegate::CreateUObject(this, &ThisClass::OnPlayerTalkingStateChangedMaster))
|
||||||
|
, PlayerLoginChangedDelegate(FOnLoginChangedDelegate::CreateUObject(this, &ThisClass::OnPlayerLoginChangedMaster))
|
||||||
|
, PlayerLoginStatusChangedDelegate(FOnLoginStatusChangedDelegate::CreateUObject(this, &ThisClass::OnPlayerLoginStatusChangedMaster))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedFriendsGameInstance::OnSessionUserInviteAccepted(const bool bWasSuccessful, const int32 ControllerId, FUniqueNetIdPtr UserId, const FOnlineSessionSearchResult& InviteResult)
|
||||||
|
{
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
||||||
|
if (SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegateHandle);
|
||||||
|
OnJoinSessionCompleteDelegateHandle = SessionInterface->AddOnJoinSessionCompleteDelegate_Handle(
|
||||||
|
FOnJoinSessionCompleteDelegate::CreateUObject(this, &UAdvancedFriendsGameInstance::OnJoinSessionComplete));
|
||||||
|
|
||||||
|
// Temp for 5.5, they aren't filling in the struct correctly
|
||||||
|
if (!InviteResult.Session.SessionSettings.bIsDedicated)
|
||||||
|
{
|
||||||
|
FOnlineSessionSearchResult ModResult = InviteResult;
|
||||||
|
ModResult.Session.SessionSettings.bUsesPresence = true;
|
||||||
|
ModResult.Session.SessionSettings.bUseLobbiesIfAvailable = true;
|
||||||
|
SessionInterface->JoinSession(0, NAME_GameSession, ModResult);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SessionInterface->JoinSession(0, NAME_GameSession, InviteResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UE_LOG(AdvancedFriendsInterfaceLog, Log, TEXT("Called Join Session for Steam Friends List UI InviteResults: %s, UserId: %s"), *InviteResult.GetSessionIdStr(), *UserId->ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedFriendsGameInstance::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
|
||||||
|
{
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
||||||
|
if (SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
FString ConnectInfo;
|
||||||
|
if (SessionInterface->GetResolvedConnectString(NAME_GameSession, ConnectInfo))
|
||||||
|
{
|
||||||
|
APlayerController* PlayerController = GetFirstLocalPlayerController();
|
||||||
|
if (PlayerController)
|
||||||
|
{
|
||||||
|
PlayerController->ClientTravel(ConnectInfo, ETravelType::TRAVEL_Absolute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedFriendsGameInstance::Shutdown()
|
||||||
|
{
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
||||||
|
|
||||||
|
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);
|
||||||
|
SessionInterface->ClearOnSessionInviteReceivedDelegate_Handle(SessionInviteReceivedDelegateHandle);
|
||||||
|
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (bEnableTalkingStatusDelegate)
|
||||||
|
{
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(GetWorld());
|
||||||
|
|
||||||
|
if (VoiceInterface.IsValid())
|
||||||
|
{
|
||||||
|
VoiceInterface->ClearOnPlayerTalkingStateChangedDelegate_Handle(PlayerTalkingStateChangedDelegateHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get voice interface!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(GetWorld());
|
||||||
|
|
||||||
|
if (IdentityInterface.IsValid())
|
||||||
|
{
|
||||||
|
IdentityInterface->ClearOnLoginChangedDelegate_Handle(PlayerLoginChangedDelegateHandle);
|
||||||
|
|
||||||
|
|
||||||
|
// I am just defaulting to player 1
|
||||||
|
IdentityInterface->ClearOnLoginStatusChangedDelegate_Handle(0, PlayerLoginStatusChangedDelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Super::Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedFriendsGameInstance::Init()
|
||||||
|
{
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());//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);
|
||||||
|
|
||||||
|
SessionInviteReceivedDelegateHandle = SessionInterface->AddOnSessionInviteReceivedDelegate_Handle(SessionInviteReceivedDelegate);
|
||||||
|
|
||||||
|
// Custom steam join game delegate
|
||||||
|
SessionInterface->OnSessionUserInviteAcceptedDelegates.AddUObject(this, &UAdvancedFriendsGameInstance::OnSessionUserInviteAccepted);
|
||||||
|
}
|
||||||
|
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(GetWorld());
|
||||||
|
|
||||||
|
if (VoiceInterface.IsValid())
|
||||||
|
{
|
||||||
|
PlayerTalkingStateChangedDelegateHandle = VoiceInterface->AddOnPlayerTalkingStateChangedDelegate_Handle(PlayerTalkingStateChangedDelegate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get voice interface!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(GetWorld());
|
||||||
|
|
||||||
|
if (IdentityInterface.IsValid())
|
||||||
|
{
|
||||||
|
PlayerLoginChangedDelegateHandle = IdentityInterface->AddOnLoginChangedDelegate_Handle(PlayerLoginChangedDelegate);
|
||||||
|
|
||||||
|
// Just defaulting to player 1
|
||||||
|
PlayerLoginStatusChangedDelegateHandle = IdentityInterface->AddOnLoginStatusChangedDelegate_Handle(0, PlayerLoginStatusChangedDelegate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get identity 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<class APlayerState*>& PlayerArray = GetWorld()->GetGameState()->PlayerArray;
|
||||||
|
const TArray<class ULocalPlayer*>&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::OnPlayerLoginStatusChangedMaster(int32 PlayerNum, ELoginStatus::Type PreviousStatus, ELoginStatus::Type NewStatus, const FUniqueNetId & NewPlayerUniqueNetID)
|
||||||
|
{
|
||||||
|
EBPLoginStatus OrigStatus = (EBPLoginStatus)PreviousStatus;
|
||||||
|
EBPLoginStatus CurrentStatus = (EBPLoginStatus)NewStatus;
|
||||||
|
FBPUniqueNetId PlayerID;
|
||||||
|
PlayerID.SetUniqueNetId(&NewPlayerUniqueNetID);
|
||||||
|
|
||||||
|
OnPlayerLoginStatusChanged(PlayerNum, OrigStatus,CurrentStatus,PlayerID);
|
||||||
|
|
||||||
|
|
||||||
|
if (bCallIdentityInterfaceEventsOnPlayerControllers)
|
||||||
|
{
|
||||||
|
APlayerController* Player = UGameplayStatics::GetPlayerController(GetWorld(), PlayerNum);
|
||||||
|
|
||||||
|
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_OnPlayerLoginStatusChanged(Player, OrigStatus, CurrentStatus, PlayerID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get a controller with the specified index in OnPlayerLoginStatusChangedMaster!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedFriendsGameInstance::OnPlayerLoginChangedMaster(int32 PlayerNum)
|
||||||
|
{
|
||||||
|
OnPlayerLoginChanged(PlayerNum);
|
||||||
|
|
||||||
|
if (bCallIdentityInterfaceEventsOnPlayerControllers)
|
||||||
|
{
|
||||||
|
APlayerController* Player = UGameplayStatics::GetPlayerController(GetWorld(), PlayerNum);
|
||||||
|
|
||||||
|
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_OnPlayerLoginChanged(Player, PlayerNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get a controller with the specified index in OnPlayerLoginChanged!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedFriendsGameInstance::OnPlayerTalkingStateChangedMaster(TSharedRef<const FUniqueNetId> 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::OnSessionInviteReceivedMaster(const FUniqueNetId & PersonInvited, const FUniqueNetId & PersonInviting, const FString& AppId, const FOnlineSessionSearchResult& SessionToJoin)
|
||||||
|
{
|
||||||
|
if (SessionToJoin.IsValid())
|
||||||
|
{
|
||||||
|
FBlueprintSessionResult BluePrintResult;
|
||||||
|
BluePrintResult.OnlineResult = SessionToJoin;
|
||||||
|
|
||||||
|
FBPUniqueNetId PInvited;
|
||||||
|
PInvited.SetUniqueNetId(&PersonInvited);
|
||||||
|
|
||||||
|
FBPUniqueNetId PInviting;
|
||||||
|
PInviting.SetUniqueNetId(&PersonInviting);
|
||||||
|
|
||||||
|
|
||||||
|
TArray<APlayerController*> PlayerList;
|
||||||
|
GEngine->GetAllLocalPlayerControllers(PlayerList);
|
||||||
|
|
||||||
|
APlayerController* Player = NULL;
|
||||||
|
|
||||||
|
int32 LocalPlayer = 0;
|
||||||
|
for (int i = 0; i < PlayerList.Num(); i++)
|
||||||
|
{
|
||||||
|
if (*PlayerList[i]->PlayerState->GetUniqueId().GetUniqueNetId() == PersonInvited)
|
||||||
|
{
|
||||||
|
LocalPlayer = i;
|
||||||
|
Player = PlayerList[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temp for 5.5, they aren't filling in the struct correctly
|
||||||
|
if (!BluePrintResult.OnlineResult.Session.SessionSettings.bIsDedicated)
|
||||||
|
{
|
||||||
|
BluePrintResult.OnlineResult.Session.SessionSettings.bUsesPresence = true;
|
||||||
|
BluePrintResult.OnlineResult.Session.SessionSettings.bUseLobbiesIfAvailable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnSessionInviteReceived(LocalPlayer, PInviting, AppId, BluePrintResult);
|
||||||
|
|
||||||
|
//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_OnSessionInviteReceived(Player, PInviting, BluePrintResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Failed to get a controller with the specified index in OnSessionInviteReceived!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsInterfaceLog, Warning, TEXT("UAdvancedFriendsInstance Return a bad search result in OnSessionInviteReceived!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedFriendsGameInstance::OnSessionInviteAcceptedMaster(const bool bWasSuccessful, int32 LocalPlayer, TSharedPtr<const FUniqueNetId> PersonInvited, const FOnlineSessionSearchResult& SessionToJoin)
|
||||||
|
{
|
||||||
|
if (bWasSuccessful)
|
||||||
|
{
|
||||||
|
if (SessionToJoin.IsValid())
|
||||||
|
{
|
||||||
|
|
||||||
|
FBlueprintSessionResult BluePrintResult;
|
||||||
|
BluePrintResult.OnlineResult = SessionToJoin;
|
||||||
|
|
||||||
|
FBPUniqueNetId PInvited;
|
||||||
|
PInvited.SetUniqueNetId(PersonInvited);
|
||||||
|
|
||||||
|
// Temp for 5.5, they aren't filling in the struct correctly
|
||||||
|
if (!BluePrintResult.OnlineResult.Session.SessionSettings.bIsDedicated)
|
||||||
|
{
|
||||||
|
BluePrintResult.OnlineResult.Session.SessionSettings.bUsesPresence = true;
|
||||||
|
BluePrintResult.OnlineResult.Session.SessionSettings.bUseLobbiesIfAvailable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnSessionInviteAccepted(LocalPlayer,PInvited, 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,PInvited, 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!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
#include "AdvancedFriendsInterface.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
UAdvancedFriendsInterface::UAdvancedFriendsInterface(const class FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,281 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
#include "AdvancedFriendsLibrary.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This is taken directly from UE4 - OnlineSubsystemSteamPrivatePCH.h as a fix for the array_count macro
|
||||||
|
|
||||||
|
//General Log
|
||||||
|
DEFINE_LOG_CATEGORY(AdvancedFriendsLog);
|
||||||
|
|
||||||
|
void UAdvancedFriendsLibrary::SendSessionInviteToFriends(APlayerController *PlayerController, const TArray<FBPUniqueNetId> &Friends, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
if (!PlayerController)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had a bad Player Controller!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Friends.Num() < 1)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had no friends in invitation array!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface();
|
||||||
|
|
||||||
|
if (!SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Failed to get session interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerController->Player);
|
||||||
|
|
||||||
|
if (!Player)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend failed to get LocalPlayer!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<TSharedRef<const FUniqueNetId>> List;
|
||||||
|
for (int i = 0; i < Friends.Num(); i++)
|
||||||
|
{
|
||||||
|
TSharedRef<const FUniqueNetId> val(Friends[i].UniqueNetId.ToSharedRef());
|
||||||
|
//TSharedRef<const FUniqueNetId> val(Friends[i].GetUniqueNetId());
|
||||||
|
List.Add(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SessionInterface->SendSessionInviteToFriends(Player->GetControllerId(), NAME_GameSession, List))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedFriendsLibrary::SendSessionInviteToFriend(APlayerController *PlayerController, const FBPUniqueNetId &FriendUniqueNetId, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
if (!PlayerController)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had a bad Player Controller!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FriendUniqueNetId.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Had a bad UniqueNetId!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface();
|
||||||
|
|
||||||
|
if (!SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend Failed to get session interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerController->Player);
|
||||||
|
|
||||||
|
if (!Player)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsLog, Warning, TEXT("SendSessionInviteToFriend failed to get LocalPlayer!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SessionInterface->SendSessionInviteToFriend(Player->GetControllerId(), NAME_GameSession, *FriendUniqueNetId.GetUniqueNetId()))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = EBlueprintResultSwitch::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<ULocalPlayer>(PlayerController->Player);
|
||||||
|
|
||||||
|
if (!Player)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriend failed to get LocalPlayer!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSharedPtr<FOnlineFriend> fr = FriendsInterface->GetFriend(Player->GetControllerId(), *FriendUniqueNetId.GetUniqueNetId(), EFriendsLists::ToString(EFriendsLists::Default));
|
||||||
|
if (fr.IsValid())
|
||||||
|
{
|
||||||
|
const FOnlineUserPresence& pres = fr->GetPresence();
|
||||||
|
Friend.DisplayName = fr->GetDisplayName();
|
||||||
|
Friend.OnlineState = ((EBPOnlinePresenceState)((int32)pres.Status.State));
|
||||||
|
Friend.RealName = fr->GetRealName();
|
||||||
|
Friend.UniqueNetId.SetUniqueNetId(fr->GetUserId());
|
||||||
|
Friend.bIsPlayingSameGame = pres.bIsPlayingThisGame;
|
||||||
|
|
||||||
|
Friend.PresenceInfo.bHasVoiceSupport = pres.bHasVoiceSupport;
|
||||||
|
Friend.PresenceInfo.bIsJoinable = pres.bIsJoinable;
|
||||||
|
Friend.PresenceInfo.bIsOnline = pres.bIsOnline;
|
||||||
|
Friend.PresenceInfo.bIsPlaying = pres.bIsPlaying;
|
||||||
|
Friend.PresenceInfo.bIsPlayingThisGame = pres.bIsPlayingThisGame;
|
||||||
|
Friend.PresenceInfo.PresenceState = ((EBPOnlinePresenceState)((int32)pres.Status.State));
|
||||||
|
// #TODO: Check back in on this in shipping, epic is missing the UTF8_TO_TCHAR call on converting this and its making an invalid string
|
||||||
|
//Friend.PresenceInfo.StatusString = pres.Status.StatusStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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<ULocalPlayer>(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::Default));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedFriendsLibrary::GetStoredRecentPlayersList(FBPUniqueNetId UniqueNetId, TArray<FBPOnlineRecentPlayer> &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<FOnlineRecentPlayer> > PlayerList;
|
||||||
|
|
||||||
|
// For now getting all namespaces
|
||||||
|
FriendsInterface->GetRecentPlayers(*(UniqueNetId.GetUniqueNetId()),"", PlayerList);
|
||||||
|
|
||||||
|
for (int32 i = 0; i < PlayerList.Num(); i++)
|
||||||
|
{
|
||||||
|
TSharedRef<FOnlineRecentPlayer> 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<FBPFriendInfo> &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<ULocalPlayer>(PlayerController->Player);
|
||||||
|
|
||||||
|
if (!Player)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriendsList Failed to get LocalPlayer!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TArray< TSharedRef<FOnlineFriend> > FriendList;
|
||||||
|
if (FriendsInterface->GetFriendsList(Player->GetControllerId(), EFriendsLists::ToString((EFriendsLists::Default)), FriendList))
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < FriendList.Num(); i++)
|
||||||
|
{
|
||||||
|
FBPFriendInfo BPF;
|
||||||
|
const FOnlineUserPresence& pres = FriendList[i]->GetPresence();
|
||||||
|
|
||||||
|
BPF.OnlineState = ((EBPOnlinePresenceState)((int32)pres.Status.State));
|
||||||
|
BPF.DisplayName = FriendList[i]->GetDisplayName();
|
||||||
|
BPF.RealName = FriendList[i]->GetRealName();
|
||||||
|
BPF.UniqueNetId.SetUniqueNetId(FriendList[i]->GetUserId());
|
||||||
|
BPF.bIsPlayingSameGame = pres.bIsPlayingThisGame;
|
||||||
|
|
||||||
|
BPF.PresenceInfo.bIsOnline = pres.bIsOnline;
|
||||||
|
BPF.PresenceInfo.bHasVoiceSupport = pres.bHasVoiceSupport;
|
||||||
|
BPF.PresenceInfo.bIsPlaying = pres.bIsPlaying;
|
||||||
|
BPF.PresenceInfo.PresenceState = ((EBPOnlinePresenceState)((int32)pres.Status.State));
|
||||||
|
// #TODO: Check back in on this in shipping, epic is missing the UTF8_TO_TCHAR call on converting this and its making an invalid string
|
||||||
|
//BPF.PresenceInfo.StatusString = pres.Status.StatusStr;
|
||||||
|
BPF.PresenceInfo.bIsJoinable = pres.bIsJoinable;
|
||||||
|
BPF.PresenceInfo.bIsPlayingThisGame = pres.bIsPlayingThisGame;
|
||||||
|
|
||||||
|
FriendsList.Add(BPF);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UE_LOG(AdvancedFriendsLog, Warning, TEXT("GetFriendsList Failed to get any friends!"));
|
||||||
|
return;
|
||||||
|
}
|
@ -0,0 +1,271 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
#include "AdvancedIdentityLibrary.h"
|
||||||
|
|
||||||
|
//General Log
|
||||||
|
DEFINE_LOG_CATEGORY(AdvancedIdentityLog);
|
||||||
|
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::GetPlayerAuthToken(UObject* WorldContextObject, APlayerController * PlayerController, FString & AuthToken, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
if (!PlayerController)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetPlayerAuthToken was passed a bad player controller!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerController->Player);
|
||||||
|
|
||||||
|
if (!Player)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetPlayerAuthToken failed to get LocalPlayer!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(World);
|
||||||
|
|
||||||
|
if (!IdentityInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetPlayerAuthToken Failed to get identity interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthToken = IdentityInterface->GetAuthToken(Player->GetControllerId());
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::GetPlayerNickname(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetID, FString & PlayerNickname)
|
||||||
|
{
|
||||||
|
if (!UniqueNetID.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetPlayerNickname was passed a bad player uniquenetid!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(World);
|
||||||
|
|
||||||
|
if (!IdentityInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetPlayerNickname Failed to get identity interface!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PlayerNickname = IdentityInterface->GetPlayerNickname(*UniqueNetID.GetUniqueNetId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::GetLoginStatus(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetID, EBPLoginStatus & LoginStatus, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
if (!UniqueNetID.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetLoginStatus was passed a bad player uniquenetid!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(World);
|
||||||
|
|
||||||
|
if (!IdentityInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetLoginStatus Failed to get identity interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginStatus = (EBPLoginStatus)IdentityInterface->GetLoginStatus(*UniqueNetID.GetUniqueNetId());
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::GetAllUserAccounts(UObject* WorldContextObject, TArray<FBPUserOnlineAccount> & AccountInfos, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(World);
|
||||||
|
|
||||||
|
if (!IdentityInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetAllUserAccounts Failed to get identity interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<TSharedPtr<FUserOnlineAccount>> accountInfos = IdentityInterface->GetAllUserAccounts();
|
||||||
|
|
||||||
|
for (int i = 0; i < accountInfos.Num(); ++i)
|
||||||
|
{
|
||||||
|
AccountInfos.Add(FBPUserOnlineAccount(accountInfos[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::GetUserAccount(UObject* WorldContextObject, const FBPUniqueNetId & UniqueNetId, FBPUserOnlineAccount & AccountInfo, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineIdentityPtr IdentityInterface = Online::GetIdentityInterface(World);
|
||||||
|
|
||||||
|
if(!UniqueNetId.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccount was passed a bad unique net id!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IdentityInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccount Failed to get identity interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSharedPtr<FUserOnlineAccount> accountInfo = IdentityInterface->GetUserAccount(*UniqueNetId.GetUniqueNetId());
|
||||||
|
|
||||||
|
if (!accountInfo.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccount Failed to get the account!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountInfo.UserAccountInfo = accountInfo;
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::GetUserAccountAccessToken(const FBPUserOnlineAccount & AccountInfo, FString & AccessToken)
|
||||||
|
{
|
||||||
|
if (!AccountInfo.UserAccountInfo.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountAccessToken was passed an invalid account!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessToken = AccountInfo.UserAccountInfo->GetAccessToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::GetUserAccountAuthAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, FString & AuthAttribute, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
if (!AccountInfo.UserAccountInfo.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountAuthAttribute was passed an invalid account!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AccountInfo.UserAccountInfo->GetAuthAttribute(AttributeName, AuthAttribute))
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountAuthAttribute couldn't find the attribute!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::SetUserAccountAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, const FString & NewAttributeValue, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
if (!AccountInfo.UserAccountInfo.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("SetUserAccountAuthAttribute was passed an invalid account!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AccountInfo.UserAccountInfo->SetUserAttribute(AttributeName, NewAttributeValue))
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("SetUserAccountAuthAttribute was unable to set the attribute!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::GetUserID(const FBPUserOnlineAccount & AccountInfo, FBPUniqueNetId & UniqueNetID)
|
||||||
|
{
|
||||||
|
if (!AccountInfo.UserAccountInfo.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserID was passed an invalid account!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UniqueNetID.SetUniqueNetId(AccountInfo.UserAccountInfo->GetUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::GetUserAccountRealName(const FBPUserOnlineAccount & AccountInfo, FString & UserName)
|
||||||
|
{
|
||||||
|
if (!AccountInfo.UserAccountInfo.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountRealName was passed an invalid account!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UserName = AccountInfo.UserAccountInfo->GetRealName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::GetUserAccountDisplayName(const FBPUserOnlineAccount & AccountInfo, FString & DisplayName)
|
||||||
|
{
|
||||||
|
if (!AccountInfo.UserAccountInfo.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountDisplayName was passed an invalid account!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DisplayName = AccountInfo.UserAccountInfo->GetDisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedIdentityLibrary::GetUserAccountAttribute(const FBPUserOnlineAccount & AccountInfo, const FString & AttributeName, FString & AttributeValue, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
if (!AccountInfo.UserAccountInfo.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountAttribute was passed an invalid account!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AccountInfo.UserAccountInfo->GetUserAttribute(AttributeName, AttributeValue))
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedIdentityLog, Warning, TEXT("GetUserAccountAttribute failed to get user attribute!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
//#include "StandAlonePrivatePCH.h"
|
||||||
|
#include "AdvancedSessions.h"
|
||||||
|
|
||||||
|
void AdvancedSessions::StartupModule()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvancedSessions::ShutdownModule()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_MODULE(AdvancedSessions, AdvancedSessions)
|
@ -0,0 +1,552 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
#include "AdvancedSessionsLibrary.h"
|
||||||
|
#include "GameFramework/PlayerState.h"
|
||||||
|
#include "GameFramework/GameStateBase.h"
|
||||||
|
|
||||||
|
//General Log
|
||||||
|
DEFINE_LOG_CATEGORY(AdvancedSessionsLog);
|
||||||
|
|
||||||
|
|
||||||
|
bool UAdvancedSessionsLibrary::KickPlayer(UObject* WorldContextObject, APlayerController* PlayerToKick, FText KickReason)
|
||||||
|
{
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
|
||||||
|
if (World)
|
||||||
|
{
|
||||||
|
if (AGameModeBase* GameMode = World->GetAuthGameMode())
|
||||||
|
{
|
||||||
|
if (GameMode->GameSession)
|
||||||
|
{
|
||||||
|
return GameMode->GameSession->KickPlayer(PlayerToKick, KickReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedSessionsLibrary::BanPlayer(UObject* WorldContextObject, APlayerController* PlayerToBan, FText BanReason)
|
||||||
|
{
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
|
||||||
|
if (World)
|
||||||
|
{
|
||||||
|
if (AGameModeBase* GameMode = World->GetAuthGameMode())
|
||||||
|
{
|
||||||
|
if (GameMode->GameSession)
|
||||||
|
{
|
||||||
|
return GameMode->GameSession->BanPlayer(PlayerToBan, BanReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedSessionsLibrary::IsValidSession(const FBlueprintSessionResult & SessionResult)
|
||||||
|
{
|
||||||
|
return SessionResult.OnlineResult.IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetSessionID_AsString(const FBlueprintSessionResult & SessionResult, FString& SessionID)
|
||||||
|
{
|
||||||
|
const TSharedPtr<class FOnlineSessionInfo> SessionInfo = SessionResult.OnlineResult.Session.SessionInfo;
|
||||||
|
if (SessionInfo.IsValid() && SessionInfo->IsValid() && SessionInfo->GetSessionId().IsValid())
|
||||||
|
{
|
||||||
|
SessionID = SessionInfo->GetSessionId().ToString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zero the string out if we didn't have a valid one, in case this is called in c++
|
||||||
|
SessionID.Empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetCurrentSessionID_AsString(UObject* WorldContextObject, FString& SessionID)
|
||||||
|
{
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(World);
|
||||||
|
|
||||||
|
if (!SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetCurrentSessionID_AsString couldn't get the session interface!"));
|
||||||
|
SessionID.Empty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FNamedOnlineSession* Session = SessionInterface->GetNamedSession(NAME_GameSession);
|
||||||
|
if (Session != nullptr)
|
||||||
|
{
|
||||||
|
const TSharedPtr<class FOnlineSessionInfo> SessionInfo = Session->SessionInfo;
|
||||||
|
if (SessionInfo.IsValid() && SessionInfo->IsValid() && SessionInfo->GetSessionId().IsValid())
|
||||||
|
{
|
||||||
|
SessionID = SessionInfo->GetSessionId().ToString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zero the string out if we didn't have a valid one, in case this is called in c++
|
||||||
|
SessionID.Empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetCurrentUniqueBuildID(int32 &UniqueBuildId)
|
||||||
|
{
|
||||||
|
UniqueBuildId = GetBuildUniqueId();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetUniqueBuildID(FBlueprintSessionResult SessionResult, int32 &UniqueBuildId)
|
||||||
|
{
|
||||||
|
UniqueBuildId = SessionResult.OnlineResult.Session.SessionSettings.BuildUniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
FName UAdvancedSessionsLibrary::GetSessionPropertyKey(const FSessionPropertyKeyPair& SessionProperty)
|
||||||
|
{
|
||||||
|
return SessionProperty.Key;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::FindSessionPropertyByName(const TArray<FSessionPropertyKeyPair>& ExtraSettings, FName SettingName, EBlueprintResultSwitch &Result, FSessionPropertyKeyPair& OutProperty)
|
||||||
|
{
|
||||||
|
const FSessionPropertyKeyPair* prop = ExtraSettings.FindByPredicate([&](const FSessionPropertyKeyPair& it) {return it.Key == SettingName; });
|
||||||
|
if (prop)
|
||||||
|
{
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
OutProperty = *prop;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::FindSessionPropertyIndexByName(const TArray<FSessionPropertyKeyPair>& ExtraSettings, FName SettingName, EBlueprintResultSwitch &Result, int32& OutIndex)
|
||||||
|
{
|
||||||
|
OutIndex = ExtraSettings.IndexOfByPredicate([&](const FSessionPropertyKeyPair& it) {return it.Key == SettingName; });
|
||||||
|
|
||||||
|
Result = OutIndex != INDEX_NONE ? EBlueprintResultSwitch::OnSuccess : EBlueprintResultSwitch::OnFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::AddOrModifyExtraSettings(UPARAM(ref) TArray<FSessionPropertyKeyPair> & SettingsArray, UPARAM(ref) TArray<FSessionPropertyKeyPair> & NewOrChangedSettings, TArray<FSessionPropertyKeyPair> & 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<FSessionPropertyKeyPair> & 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(UObject* WorldContextObject, EBPOnlineSessionState &SessionState)
|
||||||
|
{
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(World);
|
||||||
|
|
||||||
|
if (!SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetSessionState couldn't get the session interface!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionState = ((EBPOnlineSessionState)SessionInterface->GetSessionState(NAME_GameSession));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetSessionSettings(UObject* WorldContextObject, int32 &NumConnections, int32 &NumPrivateConnections, bool &bIsLAN, bool &bIsDedicated, bool &bAllowInvites, bool &bAllowJoinInProgress, bool &bIsAnticheatEnabled, int32 &BuildUniqueID, TArray<FSessionPropertyKeyPair> &ExtraSettings, EBlueprintResultSwitch &Result)
|
||||||
|
{
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(World);
|
||||||
|
|
||||||
|
if (!SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetSessionSettings couldn't get the session interface!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FOnlineSessionSettings* settings = SessionInterface->GetSessionSettings(NAME_GameSession);
|
||||||
|
if (!settings)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetSessionSettings couldn't get the session settings!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildUniqueID = settings->BuildUniqueId;
|
||||||
|
NumConnections = settings->NumPublicConnections;
|
||||||
|
NumPrivateConnections = settings->NumPrivateConnections;
|
||||||
|
bIsLAN = settings->bIsLANMatch;
|
||||||
|
bIsDedicated = settings->bIsDedicated;
|
||||||
|
bIsAnticheatEnabled = settings->bAntiCheatProtected;
|
||||||
|
bAllowInvites = settings->bAllowInvites;
|
||||||
|
bAllowJoinInProgress = settings->bAllowJoinInProgress;
|
||||||
|
|
||||||
|
FSessionPropertyKeyPair NewSetting;
|
||||||
|
|
||||||
|
for (auto& Elem : settings->Settings)
|
||||||
|
{
|
||||||
|
NewSetting.Key = Elem.Key;
|
||||||
|
NewSetting.Data = Elem.Value.Data;
|
||||||
|
ExtraSettings.Add(NewSetting);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::IsPlayerInSession(UObject* WorldContextObject, const FBPUniqueNetId &PlayerToCheck, bool &bIsInSession)
|
||||||
|
{
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(World);
|
||||||
|
|
||||||
|
if (!SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSessionsLog, Warning, TEXT("IsPlayerInSession couldn't get the session interface!"));
|
||||||
|
bIsInSession = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bIsInSession = SessionInterface->IsPlayerInSession(NAME_GameSession, *PlayerToCheck.GetUniqueNetId());
|
||||||
|
}
|
||||||
|
|
||||||
|
FSessionsSearchSetting UAdvancedSessionsLibrary::MakeLiteralSessionSearchProperty(FSessionPropertyKeyPair SessionSearchProperty, EOnlineComparisonOpRedux 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<FSessionPropertyKeyPair> & ExtraSettings, FName SettingName, ESessionSettingSearchResult &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::Found;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SearchResult = ESessionSettingSearchResult::WrongType;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchResult = ESessionSettingSearchResult::NotFound;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetSessionPropertyBool(const TArray<FSessionPropertyKeyPair> & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, bool &SettingValue)
|
||||||
|
{
|
||||||
|
for (FSessionPropertyKeyPair itr : ExtraSettings)
|
||||||
|
{
|
||||||
|
if (itr.Key == SettingName)
|
||||||
|
{
|
||||||
|
if (itr.Data.GetType() == EOnlineKeyValuePairDataType::Bool)
|
||||||
|
{
|
||||||
|
itr.Data.GetValue(SettingValue);
|
||||||
|
SearchResult = ESessionSettingSearchResult::Found;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SearchResult = ESessionSettingSearchResult::WrongType;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchResult = ESessionSettingSearchResult::NotFound;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetSessionPropertyString(const TArray<FSessionPropertyKeyPair> & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, FString &SettingValue)
|
||||||
|
{
|
||||||
|
for (FSessionPropertyKeyPair itr : ExtraSettings)
|
||||||
|
{
|
||||||
|
if (itr.Key == SettingName)
|
||||||
|
{
|
||||||
|
if (itr.Data.GetType() == EOnlineKeyValuePairDataType::String)
|
||||||
|
{
|
||||||
|
itr.Data.GetValue(SettingValue);
|
||||||
|
SearchResult = ESessionSettingSearchResult::Found;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SearchResult = ESessionSettingSearchResult::WrongType;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchResult = ESessionSettingSearchResult::NotFound;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetSessionPropertyInt(const TArray<FSessionPropertyKeyPair> & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, int32 &SettingValue)
|
||||||
|
{
|
||||||
|
for (FSessionPropertyKeyPair itr : ExtraSettings)
|
||||||
|
{
|
||||||
|
if (itr.Key == SettingName)
|
||||||
|
{
|
||||||
|
if (itr.Data.GetType() == EOnlineKeyValuePairDataType::Int32)
|
||||||
|
{
|
||||||
|
itr.Data.GetValue(SettingValue);
|
||||||
|
SearchResult = ESessionSettingSearchResult::Found;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SearchResult = ESessionSettingSearchResult::WrongType;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchResult = ESessionSettingSearchResult::NotFound;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetSessionPropertyFloat(const TArray<FSessionPropertyKeyPair> & ExtraSettings, FName SettingName, ESessionSettingSearchResult &SearchResult, float &SettingValue)
|
||||||
|
{
|
||||||
|
for (FSessionPropertyKeyPair itr : ExtraSettings)
|
||||||
|
{
|
||||||
|
if (itr.Key == SettingName)
|
||||||
|
{
|
||||||
|
if (itr.Data.GetType() == EOnlineKeyValuePairDataType::Float)
|
||||||
|
{
|
||||||
|
itr.Data.GetValue(SettingValue);
|
||||||
|
SearchResult = ESessionSettingSearchResult::Found;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SearchResult = ESessionSettingSearchResult::WrongType;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchResult = ESessionSettingSearchResult::NotFound;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UAdvancedSessionsLibrary::HasOnlineSubsystem(FName SubSystemName)
|
||||||
|
{
|
||||||
|
return IOnlineSubsystem::DoesInstanceExist(SubSystemName);
|
||||||
|
}
|
||||||
|
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
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->GetUniqueId().GetUniqueNetId());
|
||||||
|
if (!UniqueNetId.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetUniqueNetIdFromController couldn't get the player uniquenetid!"));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetUniqueNetIDFromPlayerState(APlayerState *PlayerState, FBPUniqueNetId &UniqueNetId)
|
||||||
|
{
|
||||||
|
if (!PlayerState)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetUniqueNetIdFromPlayerState received a bad PlayerState!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UniqueNetId.SetUniqueNetId(PlayerState->GetUniqueId().GetUniqueNetId());
|
||||||
|
if (!UniqueNetId.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetUniqueNetIdFromPlayerState couldn't get the player uniquenetid!"));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedSessionsLibrary::IsValidUniqueNetID(const FBPUniqueNetId &UniqueNetId)
|
||||||
|
{
|
||||||
|
return UniqueNetId.IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedSessionsLibrary::EqualEqual_UNetIDUnetID(const FBPUniqueNetId &A, const FBPUniqueNetId &B)
|
||||||
|
{
|
||||||
|
return ((A.IsValid() && B.IsValid()) && (*A.GetUniqueNetId() == *B.GetUniqueNetId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
FUniqueNetIdRepl UAdvancedSessionsLibrary::Conv_BPUniqueIDToUniqueNetIDRepl(const FBPUniqueNetId& InUniqueID)
|
||||||
|
{
|
||||||
|
return FUniqueNetIdRepl(InUniqueID.GetUniqueNetId()->AsShared());
|
||||||
|
}
|
||||||
|
|
||||||
|
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->GetPlayerName();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetLocalPlayerNameFromController had a bad player state!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSessionsLibrary::GetNumberOfNetworkPlayers(UObject* WorldContextObject, int32 &NumNetPlayers)
|
||||||
|
{
|
||||||
|
//Get World
|
||||||
|
UWorld* TheWorld = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
|
||||||
|
if (!TheWorld)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSessionsLog, Warning, TEXT("GetNumberOfNetworkPlayers Failed to get World()!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NumNetPlayers = TheWorld->GetGameState()->PlayerArray.Num();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedSessionsLibrary::ServerTravel(UObject* WorldContextObject, const FString& FURL, bool bAbsolute, bool bShouldSkipGameNotify)
|
||||||
|
{
|
||||||
|
if (!WorldContextObject)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//using a context object to get the world
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull);
|
||||||
|
if (World)
|
||||||
|
{
|
||||||
|
return World->ServerTravel(FURL, bAbsolute, bShouldSkipGameNotify);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
@ -0,0 +1,359 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
#include "AdvancedVoiceLibrary.h"
|
||||||
|
|
||||||
|
|
||||||
|
//General Log
|
||||||
|
DEFINE_LOG_CATEGORY(AdvancedVoiceLog);
|
||||||
|
|
||||||
|
void UAdvancedVoiceLibrary::IsHeadsetPresent(UObject* WorldContextObject, bool & bHasHeadset, uint8 LocalPlayerNum)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
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(UObject* WorldContextObject, uint8 LocalPlayerNum)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
if (!VoiceInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("Start Networked Voice couldn't get the voice interface!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VoiceInterface->StartNetworkedVoice(LocalPlayerNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedVoiceLibrary::StopNetworkedVoice(UObject* WorldContextObject, uint8 LocalPlayerNum)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
if (!VoiceInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("Start Networked Voice couldn't get the voice interface!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VoiceInterface->StopNetworkedVoice(LocalPlayerNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedVoiceLibrary::RegisterLocalTalker(UObject* WorldContextObject, uint8 LocalPlayerNum)
|
||||||
|
{
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
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(UObject* WorldContextObject)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
if (!VoiceInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("Register Local Talkers couldn't get the voice interface!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VoiceInterface->RegisterLocalTalkers();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UAdvancedVoiceLibrary::UnRegisterLocalTalker(UObject* WorldContextObject, uint8 LocalPlayerNum)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
if (!VoiceInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("Unregister Local Talker couldn't get the voice interface!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VoiceInterface->UnregisterLocalTalker(LocalPlayerNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedVoiceLibrary::UnRegisterAllLocalTalkers(UObject* WorldContextObject)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
if (!VoiceInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("UnRegister All Local Talkers couldn't get the voice interface!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VoiceInterface->UnregisterLocalTalkers();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedVoiceLibrary::RegisterRemoteTalker(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId)
|
||||||
|
{
|
||||||
|
if (!UniqueNetId.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("Register Remote Talker was passed an invalid unique net id!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
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(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId)
|
||||||
|
{
|
||||||
|
if (!UniqueNetId.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("UnRegister Remote Talker was passed an invalid unique net id!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
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(UObject* WorldContextObject)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
if (!VoiceInterface.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("Remove All Remote Talkers couldn't get the voice interface!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VoiceInterface->RemoveAllRemoteTalkers();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedVoiceLibrary::IsLocalPlayerTalking(UObject* WorldContextObject, uint8 LocalPlayerNum)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
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(UObject* WorldContextObject, const FBPUniqueNetId& UniqueNetId)
|
||||||
|
{
|
||||||
|
if (!UniqueNetId.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("Is Remote Player Talking was passed an invalid unique net id!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
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(UObject* WorldContextObject, uint8 LocalUserNumChecking, const FBPUniqueNetId& UniqueNetId)
|
||||||
|
{
|
||||||
|
if (!UniqueNetId.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("Is Player Muted was passed an invalid unique net id!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
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(UObject* WorldContextObject, uint8 LocalUserNum, const FBPUniqueNetId& UniqueNetId, bool bIsSystemWide)
|
||||||
|
{
|
||||||
|
if (!UniqueNetId.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("Mute Remote Talker was passed an invalid unique net id!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
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(UObject* WorldContextObject, uint8 LocalUserNum, const FBPUniqueNetId& UniqueNetId, bool bIsSystemWide)
|
||||||
|
{
|
||||||
|
if (!UniqueNetId.IsValid())
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("Unmute Remote Talker was passed an invalid unique net id!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
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(UObject* WorldContextObject, int32 & NumLocalTalkers)
|
||||||
|
{
|
||||||
|
|
||||||
|
UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||||
|
if (!IsValid(World))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineVoicePtr VoiceInterface = Online::GetVoiceInterface(World);
|
||||||
|
|
||||||
|
if (!VoiceInterface.IsValid())
|
||||||
|
{
|
||||||
|
NumLocalTalkers = 0;
|
||||||
|
UE_LOG(AdvancedVoiceLog, Warning, TEXT("Unmute Remote Talker couldn't get the voice interface!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NumLocalTalkers = VoiceInterface->GetNumLocalTalkers();
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "AutoLoginUserCallbackProxy.h"
|
||||||
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
|
||||||
|
#include "Online.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// ULoginUserCallbackProxy
|
||||||
|
|
||||||
|
UAutoLoginUserCallbackProxy::UAutoLoginUserCallbackProxy(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
, Delegate(FOnLoginCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UAutoLoginUserCallbackProxy* UAutoLoginUserCallbackProxy::AutoLoginUser(UObject* WorldContextObject, int32 LocalUserNum)
|
||||||
|
{
|
||||||
|
UAutoLoginUserCallbackProxy* Proxy = NewObject<UAutoLoginUserCallbackProxy>();
|
||||||
|
Proxy->LocalUserNumber = LocalUserNum;
|
||||||
|
Proxy->WorldContextObject = WorldContextObject;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAutoLoginUserCallbackProxy::Activate()
|
||||||
|
{
|
||||||
|
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("AutoLoginUser"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (Helper.OnlineSub != nullptr)
|
||||||
|
{
|
||||||
|
auto Identity = Helper.OnlineSub->GetIdentityInterface();
|
||||||
|
|
||||||
|
if (Identity.IsValid())
|
||||||
|
{
|
||||||
|
DelegateHandle = Identity->AddOnLoginCompleteDelegate_Handle(LocalUserNumber, Delegate);
|
||||||
|
Identity->AutoLogin(LocalUserNumber);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail immediately
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAutoLoginUserCallbackProxy::OnCompleted(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& ErrorVal)
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("AutoLoginUser"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (Helper.OnlineSub != nullptr)
|
||||||
|
{
|
||||||
|
auto Identity = Helper.OnlineSub->GetIdentityInterface();
|
||||||
|
|
||||||
|
if (Identity.IsValid())
|
||||||
|
{
|
||||||
|
Identity->ClearOnLoginCompleteDelegate_Handle(LocalUserNum, DelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (APlayerController* PController = UGameplayStatics::GetPlayerController(WorldContextObject->GetWorld(), LocalUserNum))
|
||||||
|
{
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PController->Player);
|
||||||
|
|
||||||
|
FUniqueNetIdRepl uniqueId(UserId.AsShared());
|
||||||
|
|
||||||
|
if (Player)
|
||||||
|
{
|
||||||
|
Player->SetCachedUniqueNetId(uniqueId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (APlayerState* State = PController->PlayerState)
|
||||||
|
{
|
||||||
|
// Update UniqueId. See also ShowLoginUICallbackProxy.cpp
|
||||||
|
State->SetUniqueId(uniqueId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (bWasSuccessful)
|
||||||
|
{
|
||||||
|
OnSuccess.Broadcast();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#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<UCancelFindSessionsCallbackProxy>();
|
||||||
|
Proxy->PlayerControllerWeakPtr = PlayerController;
|
||||||
|
Proxy->WorldContextObject = WorldContextObject;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCancelFindSessionsCallbackProxy::Activate()
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("CancelFindSessions"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
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.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,182 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#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<FSessionPropertyKeyPair>& ExtraSettings, class APlayerController* PlayerController, int32 PublicConnections, int32 PrivateConnections, bool bUseLAN, bool bAllowInvites, bool bIsDedicatedServer, /*bool bUsePresence,*/ bool bUseLobbiesIfAvailable, bool bAllowJoinViaPresence, bool bAllowJoinViaPresenceFriendsOnly, bool bAntiCheatProtected, bool bUsesStats, bool bShouldAdvertise, bool bUseLobbiesVoiceChatIfAvailable, bool bStartAfterCreate)
|
||||||
|
{
|
||||||
|
UCreateSessionCallbackProxyAdvanced* Proxy = NewObject<UCreateSessionCallbackProxyAdvanced>();
|
||||||
|
Proxy->PlayerControllerWeakPtr = PlayerController;
|
||||||
|
Proxy->NumPublicConnections = PublicConnections;
|
||||||
|
Proxy->NumPrivateConnections = PrivateConnections;
|
||||||
|
Proxy->bUseLAN = bUseLAN;
|
||||||
|
Proxy->WorldContextObject = WorldContextObject;
|
||||||
|
Proxy->bAllowInvites = bAllowInvites;
|
||||||
|
Proxy->ExtraSettings = ExtraSettings;
|
||||||
|
Proxy->bDedicatedServer = bIsDedicatedServer;
|
||||||
|
/*Proxy->bUsePresence = bUsePresence;*/
|
||||||
|
Proxy->bUseLobbiesIfAvailable = bUseLobbiesIfAvailable;
|
||||||
|
Proxy->bAllowJoinViaPresence = bAllowJoinViaPresence;
|
||||||
|
Proxy->bAllowJoinViaPresenceFriendsOnly = bAllowJoinViaPresenceFriendsOnly;
|
||||||
|
Proxy->bAntiCheatProtected = bAntiCheatProtected;
|
||||||
|
Proxy->bUsesStats = bUsesStats;
|
||||||
|
Proxy->bShouldAdvertise = bShouldAdvertise;
|
||||||
|
Proxy->bUseLobbiesVoiceChatIfAvailable = bUseLobbiesVoiceChatIfAvailable;
|
||||||
|
Proxy->bStartAfterCreate = bStartAfterCreate;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UCreateSessionCallbackProxyAdvanced::Activate()
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("CreateSession"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
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.NumPrivateConnections = NumPrivateConnections;
|
||||||
|
Settings.bShouldAdvertise = bShouldAdvertise;
|
||||||
|
Settings.bAllowJoinInProgress = true;
|
||||||
|
Settings.bIsLANMatch = bUseLAN;
|
||||||
|
Settings.bAllowJoinViaPresence = bAllowJoinViaPresence;
|
||||||
|
Settings.bIsDedicated = bDedicatedServer;
|
||||||
|
|
||||||
|
if (bDedicatedServer)
|
||||||
|
{
|
||||||
|
Settings.bUseLobbiesIfAvailable = false;
|
||||||
|
Settings.bUsesPresence = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Settings.bUseLobbiesIfAvailable = bUseLobbiesIfAvailable;
|
||||||
|
Settings.bUsesPresence = bUseLobbiesIfAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings.bUseLobbiesVoiceChatIfAvailable = bUseLobbiesIfAvailable ? bUseLobbiesVoiceChatIfAvailable : false;
|
||||||
|
Settings.bAllowJoinViaPresenceFriendsOnly = bAllowJoinViaPresenceFriendsOnly;
|
||||||
|
Settings.bAntiCheatProtected = bAntiCheatProtected;
|
||||||
|
Settings.bUsesStats = bUsesStats;
|
||||||
|
|
||||||
|
// 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 (!bDedicatedServer )
|
||||||
|
{
|
||||||
|
if (PlayerControllerWeakPtr.IsValid() && Helper.UserID.IsValid())
|
||||||
|
{
|
||||||
|
Sessions->CreateSession(*Helper.UserID, NAME_GameSession, Settings);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FFrame::KismetExecutionMessage(TEXT("Invalid Player controller when attempting to start a session"), ELogVerbosity::Warning);
|
||||||
|
Sessions->ClearOnCreateSessionCompleteDelegate_Handle(CreateCompleteDelegateHandle);
|
||||||
|
|
||||||
|
// Fail immediately
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Sessions->CreateSession(0, NAME_GameSession, 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.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
//Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get());
|
||||||
|
|
||||||
|
if (Helper.OnlineSub != nullptr)
|
||||||
|
{
|
||||||
|
auto Sessions = Helper.OnlineSub->GetSessionInterface();
|
||||||
|
if (Sessions.IsValid())
|
||||||
|
{
|
||||||
|
Sessions->ClearOnCreateSessionCompleteDelegate_Handle(CreateCompleteDelegateHandle);
|
||||||
|
|
||||||
|
if (bWasSuccessful)
|
||||||
|
{
|
||||||
|
if (this->bStartAfterCreate)
|
||||||
|
{
|
||||||
|
UE_LOG_ONLINE_SESSION(Display, TEXT("Session creation completed. Automatic start is turned on, starting session now."));
|
||||||
|
StartCompleteDelegateHandle = Sessions->AddOnStartSessionCompleteDelegate_Handle(StartCompleteDelegate);
|
||||||
|
Sessions->StartSession(NAME_GameSession); // We'll call `OnSuccess.Broadcast()` when start succeeds.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG_ONLINE_SESSION(Display, TEXT("Session creation completed. Automatic start is turned off, to start the session call 'StartSession'."));
|
||||||
|
OnSuccess.Broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
//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();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#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<UEndSessionCallbackProxy>();
|
||||||
|
Proxy->PlayerControllerWeakPtr = PlayerController;
|
||||||
|
Proxy->WorldContextObject = WorldContextObject;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UEndSessionCallbackProxy::Activate()
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("EndSession"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get());
|
||||||
|
|
||||||
|
if (Helper.IsValid())
|
||||||
|
{
|
||||||
|
auto Sessions = Helper.OnlineSub->GetSessionInterface();
|
||||||
|
if (Sessions.IsValid())
|
||||||
|
{
|
||||||
|
FNamedOnlineSession* Session = Sessions->GetNamedSession(NAME_GameSession);
|
||||||
|
if (Session &&
|
||||||
|
Session->SessionState == EOnlineSessionState::InProgress)
|
||||||
|
{
|
||||||
|
DelegateHandle = Sessions->AddOnEndSessionCompleteDelegate_Handle(Delegate);
|
||||||
|
Sessions->EndSession(NAME_GameSession);
|
||||||
|
}
|
||||||
|
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.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#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<UFindFriendSessionCallbackProxy>();
|
||||||
|
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!"));
|
||||||
|
TArray<FBlueprintSessionResult> EmptyResult;
|
||||||
|
OnFailure.Broadcast(EmptyResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PlayerControllerWeakPtr.IsValid())
|
||||||
|
{
|
||||||
|
// Fail immediately
|
||||||
|
UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed received a bad playercontroller!"));
|
||||||
|
TArray<FBlueprintSessionResult> EmptyResult;
|
||||||
|
OnFailure.Broadcast(EmptyResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("EndSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get());
|
||||||
|
|
||||||
|
if (!Helper.IsValid())
|
||||||
|
{
|
||||||
|
// Fail immediately
|
||||||
|
TArray<FBlueprintSessionResult> EmptyResult;
|
||||||
|
OnFailure.Broadcast(EmptyResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineSessionPtr Sessions = Helper.OnlineSub->GetSessionInterface();
|
||||||
|
|
||||||
|
if (Sessions.IsValid())
|
||||||
|
{
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerControllerWeakPtr->Player);
|
||||||
|
|
||||||
|
if (!Player)
|
||||||
|
{
|
||||||
|
// Fail immediately
|
||||||
|
UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed couldn't cast to ULocalPlayer!"));
|
||||||
|
TArray<FBlueprintSessionResult> EmptyResult;
|
||||||
|
OnFailure.Broadcast(EmptyResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindFriendSessionCompleteDelegateHandle = Sessions->AddOnFindFriendSessionCompleteDelegate_Handle(Player->GetControllerId(), OnFindFriendSessionCompleteDelegate);
|
||||||
|
|
||||||
|
Sessions->FindFriendSession(Player->GetControllerId(), *cUniqueNetId.GetUniqueNetId());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail immediately
|
||||||
|
TArray<FBlueprintSessionResult> EmptyResult;
|
||||||
|
OnFailure.Broadcast(EmptyResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UFindFriendSessionCallbackProxy::OnFindFriendSessionCompleted(int32 LocalPlayer, bool bWasSuccessful, const TArray<FOnlineSessionSearchResult>& SessionInfo)
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("EndSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get());
|
||||||
|
|
||||||
|
if (Helper.IsValid())
|
||||||
|
{
|
||||||
|
IOnlineSessionPtr Sessions = Helper.OnlineSub->GetSessionInterface();
|
||||||
|
|
||||||
|
if (Sessions.IsValid())
|
||||||
|
Sessions->ClearOnFindFriendSessionCompleteDelegate_Handle(LocalPlayer, FindFriendSessionCompleteDelegateHandle);
|
||||||
|
|
||||||
|
if (bWasSuccessful)
|
||||||
|
{
|
||||||
|
TArray<FBlueprintSessionResult> Result;
|
||||||
|
|
||||||
|
for (auto& Sesh : SessionInfo)
|
||||||
|
{
|
||||||
|
if (Sesh.IsValid())
|
||||||
|
{
|
||||||
|
FBlueprintSessionResult BSesh;
|
||||||
|
BSesh.OnlineResult = Sesh;
|
||||||
|
Result.Add(BSesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Result.Num() > 0)
|
||||||
|
OnSuccess.Broadcast(Result);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed, returned an invalid session."));
|
||||||
|
OnFailure.Broadcast(Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed"));
|
||||||
|
TArray<FBlueprintSessionResult> EmptyResult;
|
||||||
|
OnFailure.Broadcast(EmptyResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedFindFriendSessionLog, Warning, TEXT("FindFriendSession Failed"));
|
||||||
|
TArray<FBlueprintSessionResult> EmptyResult;
|
||||||
|
OnFailure.Broadcast(EmptyResult);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,451 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#include "FindSessionsCallbackProxyAdvanced.h"
|
||||||
|
|
||||||
|
#include "Online/OnlineSessionNames.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// UFindSessionsCallbackProxyAdvanced
|
||||||
|
|
||||||
|
|
||||||
|
UFindSessionsCallbackProxyAdvanced::UFindSessionsCallbackProxyAdvanced(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
, Delegate(FOnFindSessionsCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted))
|
||||||
|
, bUseLAN(false)
|
||||||
|
{
|
||||||
|
bRunSecondSearch = false;
|
||||||
|
bIsOnSecondSearch = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UFindSessionsCallbackProxyAdvanced* UFindSessionsCallbackProxyAdvanced::FindSessionsAdvanced(UObject* WorldContextObject, class APlayerController* PlayerController, int MaxResults, bool bUseLAN, EBPServerPresenceSearchType ServerTypeToSearch, const TArray<FSessionsSearchSetting> &Filters, bool bEmptyServersOnly, bool bNonEmptyServersOnly, bool bSecureServersOnly, /*bool bSearchLobbies,*/ int MinSlotsAvailable)
|
||||||
|
{
|
||||||
|
UFindSessionsCallbackProxyAdvanced* Proxy = NewObject<UFindSessionsCallbackProxyAdvanced>();
|
||||||
|
Proxy->PlayerControllerWeakPtr = PlayerController;
|
||||||
|
Proxy->bUseLAN = bUseLAN;
|
||||||
|
Proxy->MaxResults = MaxResults;
|
||||||
|
Proxy->WorldContextObject = WorldContextObject;
|
||||||
|
Proxy->SearchSettings = Filters;
|
||||||
|
Proxy->ServerSearchType = ServerTypeToSearch;
|
||||||
|
Proxy->bEmptyServersOnly = bEmptyServersOnly,
|
||||||
|
Proxy->bNonEmptyServersOnly = bNonEmptyServersOnly;
|
||||||
|
Proxy->bSecureServersOnly = bSecureServersOnly;
|
||||||
|
//Proxy->bSearchLobbies = bSearchLobbies;
|
||||||
|
Proxy->MinSlotsAvailable = MinSlotsAvailable;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UFindSessionsCallbackProxyAdvanced::Activate()
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("FindSessions"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get());
|
||||||
|
|
||||||
|
if (Helper.IsValid())
|
||||||
|
{
|
||||||
|
auto Sessions = Helper.OnlineSub->GetSessionInterface();
|
||||||
|
if (Sessions.IsValid())
|
||||||
|
{
|
||||||
|
// Re-initialize here, otherwise I think there might be issues with people re-calling search for some reason before it is destroyed
|
||||||
|
bRunSecondSearch = false;
|
||||||
|
bIsOnSecondSearch = false;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* // Search only for dedicated servers (value is true/false)
|
||||||
|
#define SEARCH_DEDICATED_ONLY FName(TEXT("DEDICATEDONLY"))
|
||||||
|
// Search for empty servers only (value is true/false)
|
||||||
|
#define SEARCH_EMPTY_SERVERS_ONLY FName(TEXT("EMPTYONLY"))
|
||||||
|
// Search for non empty servers only (value is true/false)
|
||||||
|
#define SEARCH_NONEMPTY_SERVERS_ONLY FName(TEXT("NONEMPTYONLY"))
|
||||||
|
// Search for secure servers only (value is true/false)
|
||||||
|
#define SEARCH_SECURE_SERVERS_ONLY FName(TEXT("SECUREONLY"))
|
||||||
|
// Search for presence sessions only (value is true/false)
|
||||||
|
#define SEARCH_PRESENCE FName(TEXT("PRESENCESEARCH"))
|
||||||
|
// Search for a match with min player availability (value is int)
|
||||||
|
#define SEARCH_MINSLOTSAVAILABLE FName(TEXT("MINSLOTSAVAILABLE"))
|
||||||
|
// Exclude all matches where any unique ids in a given array are present (value is string of the form "uniqueid1;uniqueid2;uniqueid3")
|
||||||
|
#define SEARCH_EXCLUDE_UNIQUEIDS FName(TEXT("EXCLUDEUNIQUEIDS"))
|
||||||
|
// User ID to search for session of
|
||||||
|
#define SEARCH_USER FName(TEXT("SEARCHUSER"))
|
||||||
|
// Keywords to match in session search
|
||||||
|
#define SEARCH_KEYWORDS FName(TEXT("SEARCHKEYWORDS"))*/
|
||||||
|
/** Keywords to match in session search */
|
||||||
|
/** The matchmaking queue name to matchmake in, e.g. "TeamDeathmatch" (value is string) */
|
||||||
|
/** #define SEARCH_MATCHMAKING_QUEUE FName(TEXT("MATCHMAKINGQUEUE"))*/
|
||||||
|
/** If set, use the named Xbox Live hopper to find a session via matchmaking (value is a string) */
|
||||||
|
/** #define SEARCH_XBOX_LIVE_HOPPER_NAME FName(TEXT("LIVEHOPPERNAME"))*/
|
||||||
|
/** Which session template from the service configuration to use */
|
||||||
|
/** #define SEARCH_XBOX_LIVE_SESSION_TEMPLATE_NAME FName(TEXT("LIVESESSIONTEMPLATE"))*/
|
||||||
|
/** Selection method used to determine which match to join when multiple are returned (valid only on Switch) */
|
||||||
|
/** #define SEARCH_SWITCH_SELECTION_METHOD FName(TEXT("SWITCHSELECTIONMETHOD"))*/
|
||||||
|
/** Whether to use lobbies vs sessions */
|
||||||
|
/** #define SEARCH_LOBBIES FName(TEXT("LOBBYSEARCH"))*/
|
||||||
|
if (bEmptyServersOnly)
|
||||||
|
tem.Set(SEARCH_EMPTY_SERVERS_ONLY, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
|
if (bNonEmptyServersOnly)
|
||||||
|
tem.Set(SEARCH_NONEMPTY_SERVERS_ONLY, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
|
if (bSecureServersOnly)
|
||||||
|
tem.Set(SEARCH_SECURE_SERVERS_ONLY, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
|
if (MinSlotsAvailable != 0)
|
||||||
|
tem.Set(SEARCH_MINSLOTSAVAILABLE, MinSlotsAvailable, EOnlineComparisonOp::GreaterThanEquals);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ServerSearchType)
|
||||||
|
{
|
||||||
|
|
||||||
|
case EBPServerPresenceSearchType::ClientServersOnly:
|
||||||
|
{
|
||||||
|
//tem.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
|
//if (bSearchLobbies)// && !IOnlineSubsystem::DoesInstanceExist("STEAM"))
|
||||||
|
tem.Set(SEARCH_LOBBIES, true, EOnlineComparisonOp::Equals);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EBPServerPresenceSearchType::DedicatedServersOnly:
|
||||||
|
{
|
||||||
|
//tem.Set(SEARCH_DEDICATED_ONLY, true, EOnlineComparisonOp::Equals);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EBPServerPresenceSearchType::AllServers:
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
//if (IOnlineSubsystem::DoesInstanceExist("STEAM"))
|
||||||
|
//{
|
||||||
|
bRunSecondSearch = true;
|
||||||
|
|
||||||
|
SearchObjectDedicated = MakeShareable(new FOnlineSessionSearch);
|
||||||
|
SearchObjectDedicated->MaxSearchResults = MaxResults;
|
||||||
|
SearchObjectDedicated->bIsLanQuery = bUseLAN;
|
||||||
|
|
||||||
|
FOnlineSearchSettingsEx DedicatedOnly = tem;
|
||||||
|
|
||||||
|
//tem.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
|
//if (bSearchLobbies)// && !IOnlineSubsystem::DoesInstanceExist("STEAM"))
|
||||||
|
tem.Set(SEARCH_LOBBIES, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
|
//DedicatedOnly.Set(SEARCH_DEDICATED_ONLY, true, EOnlineComparisonOp::Equals);
|
||||||
|
SearchObjectDedicated->QuerySettings = DedicatedOnly;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
OnFailure.Broadcast(SessionSearchResults);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UFindSessionsCallbackProxyAdvanced::OnCompleted(bool bSuccess)
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("FindSessionsCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get());
|
||||||
|
|
||||||
|
if (!Helper.IsValid())
|
||||||
|
{
|
||||||
|
// Fail immediately
|
||||||
|
OnFailure.Broadcast(SessionSearchResults);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bRunSecondSearch && Helper.IsValid())
|
||||||
|
{
|
||||||
|
auto Sessions = Helper.OnlineSub->GetSessionInterface();
|
||||||
|
if (Sessions.IsValid())
|
||||||
|
{
|
||||||
|
Sessions->ClearOnFindSessionsCompleteDelegate_Handle(DelegateHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bSuccess)
|
||||||
|
{
|
||||||
|
if (bIsOnSecondSearch)
|
||||||
|
{
|
||||||
|
if (SearchObjectDedicated.IsValid())
|
||||||
|
{
|
||||||
|
// Just log the results for now, will need to add a blueprint-compatible search result struct
|
||||||
|
for (auto& Result : SearchObjectDedicated->SearchResults)
|
||||||
|
{
|
||||||
|
FString ResultText = FString::Printf(TEXT("Found a session. Ping is %d"), Result.PingInMs);
|
||||||
|
|
||||||
|
FFrame::KismetExecutionMessage(*ResultText, ELogVerbosity::Log);
|
||||||
|
|
||||||
|
FBlueprintSessionResult BPResult;
|
||||||
|
BPResult.OnlineResult = Result;
|
||||||
|
SessionSearchResults.AddUnique(BPResult);
|
||||||
|
}
|
||||||
|
OnSuccess.Broadcast(SessionSearchResults);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SearchObject.IsValid())
|
||||||
|
{
|
||||||
|
// Just log the results for now, will need to add a blueprint-compatible search result struct
|
||||||
|
for (auto& Result : SearchObject->SearchResults)
|
||||||
|
{
|
||||||
|
FString ResultText = FString::Printf(TEXT("Found a session. Ping is %d"), Result.PingInMs);
|
||||||
|
|
||||||
|
FFrame::KismetExecutionMessage(*ResultText, ELogVerbosity::Log);
|
||||||
|
|
||||||
|
FBlueprintSessionResult BPResult;
|
||||||
|
BPResult.OnlineResult = Result;
|
||||||
|
|
||||||
|
// Temp for 5.5, force the values if epic isn't setting them, lobbies should always have these true
|
||||||
|
if (ServerSearchType != EBPServerPresenceSearchType::DedicatedServersOnly )
|
||||||
|
{
|
||||||
|
BPResult.OnlineResult.Session.SessionSettings.bUseLobbiesIfAvailable = true;
|
||||||
|
BPResult.OnlineResult.Session.SessionSettings.bUsesPresence = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SessionSearchResults.AddUnique(BPResult);
|
||||||
|
}
|
||||||
|
if (!bRunSecondSearch)
|
||||||
|
{
|
||||||
|
OnSuccess.Broadcast(SessionSearchResults);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!bRunSecondSearch)
|
||||||
|
{
|
||||||
|
// Need to account for only one of the searches failing
|
||||||
|
if (SessionSearchResults.Num() > 0)
|
||||||
|
OnSuccess.Broadcast(SessionSearchResults);
|
||||||
|
else
|
||||||
|
OnFailure.Broadcast(SessionSearchResults);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Helper.IsValid() && bRunSecondSearch && ServerSearchType == EBPServerPresenceSearchType::AllServers)
|
||||||
|
{
|
||||||
|
bRunSecondSearch = false;
|
||||||
|
bIsOnSecondSearch = true;
|
||||||
|
auto Sessions = Helper.OnlineSub->GetSessionInterface();
|
||||||
|
Sessions->FindSessions(*Helper.UserID, SearchObjectDedicated.ToSharedRef());
|
||||||
|
}
|
||||||
|
else // We lost our player controller
|
||||||
|
{
|
||||||
|
if (bSuccess && SessionSearchResults.Num() > 0)
|
||||||
|
OnSuccess.Broadcast(SessionSearchResults);
|
||||||
|
else
|
||||||
|
OnFailure.Broadcast(SessionSearchResults);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UFindSessionsCallbackProxyAdvanced::FilterSessionResults(const TArray<FBlueprintSessionResult> &SessionResults, const TArray<FSessionsSearchSetting> &Filters, TArray<FBlueprintSessionResult> &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 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,114 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#include "GetFriendsCallbackProxy.h"
|
||||||
|
|
||||||
|
#include "Online.h"
|
||||||
|
#include "Interfaces/OnlineFriendsInterface.h"
|
||||||
|
#include "Interfaces/OnlinePresenceInterface.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<UGetFriendsCallbackProxy>();
|
||||||
|
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<FBPFriendInfo> EmptyArray;
|
||||||
|
OnFailure.Broadcast(EmptyArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetFriends"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get());
|
||||||
|
|
||||||
|
if (Helper.IsValid())
|
||||||
|
{
|
||||||
|
IOnlineFriendsPtr Friends = Helper.OnlineSub->GetFriendsInterface();
|
||||||
|
if (Friends.IsValid())
|
||||||
|
{
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerControllerWeakPtr->Player);
|
||||||
|
|
||||||
|
Friends->ReadFriendsList(Player->GetControllerId(), EFriendsLists::ToString((EFriendsLists::Default)), FriendListReadCompleteDelegate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail immediately
|
||||||
|
TArray<FBPFriendInfo> EmptyArray;
|
||||||
|
OnFailure.Broadcast(EmptyArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGetFriendsCallbackProxy::OnReadFriendsListCompleted(int32 LocalUserNum, bool bWasSuccessful, const FString& ListName, const FString& ErrorString)
|
||||||
|
{
|
||||||
|
if (bWasSuccessful)
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetFriends"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
Helper.QueryIDFromPlayerController(PlayerControllerWeakPtr.Get());
|
||||||
|
|
||||||
|
if (!Helper.IsValid())
|
||||||
|
{
|
||||||
|
TArray<FBPFriendInfo> EmptyArray;
|
||||||
|
OnFailure.Broadcast(EmptyArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Friends = Helper.OnlineSub->GetFriendsInterface();
|
||||||
|
if (Friends.IsValid())
|
||||||
|
{
|
||||||
|
// Not actually needed anymore, plus was not being validated and causing a crash
|
||||||
|
//ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerControllerWeakPtr->Player);
|
||||||
|
|
||||||
|
TArray<FBPFriendInfo> FriendsListOut;
|
||||||
|
TArray< TSharedRef<FOnlineFriend> > FriendList;
|
||||||
|
if (Friends->GetFriendsList(LocalUserNum, ListName, FriendList))
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < FriendList.Num(); i++)
|
||||||
|
{
|
||||||
|
FBPFriendInfo BPF;
|
||||||
|
const FOnlineUserPresence& pres = FriendList[i]->GetPresence();
|
||||||
|
BPF.OnlineState = ((EBPOnlinePresenceState)((int32)pres.Status.State));
|
||||||
|
BPF.DisplayName = FriendList[i]->GetDisplayName();
|
||||||
|
BPF.RealName = FriendList[i]->GetRealName();
|
||||||
|
BPF.UniqueNetId.SetUniqueNetId(FriendList[i]->GetUserId());
|
||||||
|
BPF.bIsPlayingSameGame = pres.bIsPlayingThisGame;
|
||||||
|
|
||||||
|
BPF.PresenceInfo.bIsOnline = pres.bIsOnline;
|
||||||
|
BPF.PresenceInfo.bHasVoiceSupport = pres.bHasVoiceSupport;
|
||||||
|
BPF.PresenceInfo.bIsPlaying = pres.bIsPlaying;
|
||||||
|
BPF.PresenceInfo.PresenceState = ((EBPOnlinePresenceState)((int32)pres.Status.State));
|
||||||
|
|
||||||
|
// #TODO: Check back in on this in shipping, epic is missing the UTF8_TO_TCHAR call on converting this and its making an invalid string
|
||||||
|
//BPF.PresenceInfo.StatusString = pres.Status.StatusStr;
|
||||||
|
BPF.PresenceInfo.bIsJoinable = pres.bIsJoinable;
|
||||||
|
BPF.PresenceInfo.bIsPlayingThisGame = pres.bIsPlayingThisGame;
|
||||||
|
|
||||||
|
|
||||||
|
FriendsListOut.Add(BPF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OnSuccess.Broadcast(FriendsListOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TArray<FBPFriendInfo> EmptyArray;
|
||||||
|
OnFailure.Broadcast(EmptyArray);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#include "GetRecentPlayersCallbackProxy.h"
|
||||||
|
|
||||||
|
#include "Online.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<UGetRecentPlayersCallbackProxy>();
|
||||||
|
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<FBPOnlineRecentPlayer> EmptyArray;
|
||||||
|
OnFailure.Broadcast(EmptyArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetRecentPlayers"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (!Helper.OnlineSub)
|
||||||
|
{
|
||||||
|
TArray<FBPOnlineRecentPlayer> EmptyArray;
|
||||||
|
OnFailure.Broadcast(EmptyArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineFriendsPtr Friends = Helper.OnlineSub->GetFriendsInterface();
|
||||||
|
if (Friends.IsValid())
|
||||||
|
{
|
||||||
|
DelegateHandle = Friends->AddOnQueryRecentPlayersCompleteDelegate_Handle(QueryRecentPlayersCompleteDelegate);
|
||||||
|
|
||||||
|
// Testing with null namespace
|
||||||
|
Friends->QueryRecentPlayers(*(cUniqueNetId.GetUniqueNetId()), "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Fail immediately
|
||||||
|
TArray<FBPOnlineRecentPlayer> EmptyArray;
|
||||||
|
OnFailure.Broadcast(EmptyArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGetRecentPlayersCallbackProxy::OnQueryRecentPlayersCompleted(const FUniqueNetId &UserID, const FString &Namespace, bool bWasSuccessful, const FString& ErrorString)
|
||||||
|
{
|
||||||
|
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetRecentPlayers"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (!Helper.OnlineSub)
|
||||||
|
{
|
||||||
|
TArray<FBPOnlineRecentPlayer> EmptyArray;
|
||||||
|
OnFailure.Broadcast(EmptyArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOnlineFriendsPtr Friends = Helper.OnlineSub->GetFriendsInterface();
|
||||||
|
if (Friends.IsValid())
|
||||||
|
Friends->ClearOnQueryRecentPlayersCompleteDelegate_Handle(DelegateHandle);
|
||||||
|
|
||||||
|
|
||||||
|
if (bWasSuccessful)
|
||||||
|
{
|
||||||
|
// WHOOPS
|
||||||
|
//IOnlineFriendsPtr Friends = Online::GetFriendsInterface();
|
||||||
|
if (Friends.IsValid())
|
||||||
|
{
|
||||||
|
TArray<FBPOnlineRecentPlayer> PlayersListOut;
|
||||||
|
TArray< TSharedRef<FOnlineRecentPlayer> > PlayerList;
|
||||||
|
|
||||||
|
Friends->GetRecentPlayers(*(cUniqueNetId.GetUniqueNetId()), "", PlayerList);
|
||||||
|
|
||||||
|
for (int32 i = 0; i < PlayerList.Num(); i++)
|
||||||
|
{
|
||||||
|
TSharedRef<FOnlineRecentPlayer> 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<FBPOnlineRecentPlayer> EmptyArray;
|
||||||
|
OnFailure.Broadcast(EmptyArray);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "GetUserPrivilegeCallbackProxy.h"
|
||||||
|
|
||||||
|
#include "Online.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// UGetUserPrivilegeCallbackProxy
|
||||||
|
|
||||||
|
UGetUserPrivilegeCallbackProxy::UGetUserPrivilegeCallbackProxy(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UGetUserPrivilegeCallbackProxy* UGetUserPrivilegeCallbackProxy::GetUserPrivilege(UObject* WorldContextObject, const EBPUserPrivileges & PrivilegeToCheck, const FBPUniqueNetId & PlayerUniqueNetID)
|
||||||
|
{
|
||||||
|
UGetUserPrivilegeCallbackProxy* Proxy = NewObject<UGetUserPrivilegeCallbackProxy>();
|
||||||
|
Proxy->PlayerUniqueNetID.SetUniqueNetId(PlayerUniqueNetID.GetUniqueNetId());
|
||||||
|
Proxy->UserPrivilege = PrivilegeToCheck;
|
||||||
|
Proxy->WorldContextObject = WorldContextObject;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGetUserPrivilegeCallbackProxy::Activate()
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetUserPrivilege"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (!Helper.OnlineSub)
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto Identity = Helper.OnlineSub->GetIdentityInterface();
|
||||||
|
|
||||||
|
if (Identity.IsValid())
|
||||||
|
{
|
||||||
|
Identity->GetUserPrivilege(*PlayerUniqueNetID.GetUniqueNetId(), (EUserPrivileges::Type)UserPrivilege, IOnlineIdentity::FOnGetUserPrivilegeCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail immediately
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGetUserPrivilegeCallbackProxy::OnCompleted(const FUniqueNetId& PlayerID, EUserPrivileges::Type Privilege, uint32 PrivilegeResult)
|
||||||
|
{
|
||||||
|
OnSuccess.Broadcast(/*PlayerID,*/ (EBPUserPrivileges)Privilege, PrivilegeResult == 0);
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "LoginUserCallbackProxy.h"
|
||||||
|
|
||||||
|
#include "Online.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// ULoginUserCallbackProxy
|
||||||
|
|
||||||
|
ULoginUserCallbackProxy::ULoginUserCallbackProxy(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
, Delegate(FOnLoginCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ULoginUserCallbackProxy* ULoginUserCallbackProxy::LoginUser(UObject* WorldContextObject, class APlayerController* PlayerController, FString UserID, FString UserToken, FString AuthType)
|
||||||
|
{
|
||||||
|
ULoginUserCallbackProxy* Proxy = NewObject<ULoginUserCallbackProxy>();
|
||||||
|
Proxy->PlayerControllerWeakPtr = PlayerController;
|
||||||
|
Proxy->UserID = UserID;
|
||||||
|
Proxy->UserToken = UserToken;
|
||||||
|
Proxy->AuthType = AuthType;
|
||||||
|
Proxy->WorldContextObject = WorldContextObject;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ULoginUserCallbackProxy::Activate()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!PlayerControllerWeakPtr.IsValid())
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerControllerWeakPtr->Player);
|
||||||
|
|
||||||
|
if (!Player)
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("LoginUser"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (!Helper.OnlineSub)
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Identity = Helper.OnlineSub->GetIdentityInterface();
|
||||||
|
if (Identity.IsValid())
|
||||||
|
{
|
||||||
|
// Fallback to default AuthType if nothing is specified
|
||||||
|
if (AuthType.IsEmpty())
|
||||||
|
{
|
||||||
|
AuthType = Identity->GetAuthType();
|
||||||
|
}
|
||||||
|
DelegateHandle = Identity->AddOnLoginCompleteDelegate_Handle(Player->GetControllerId(), Delegate);
|
||||||
|
FOnlineAccountCredentials AccountCreds(AuthType, UserID, UserToken);
|
||||||
|
Identity->Login(Player->GetControllerId(), AccountCreds);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail immediately
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ULoginUserCallbackProxy::OnCompleted(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& ErrorVal)
|
||||||
|
{
|
||||||
|
if (PlayerControllerWeakPtr.IsValid())
|
||||||
|
{
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerControllerWeakPtr->Player);
|
||||||
|
|
||||||
|
FUniqueNetIdRepl UniqueID(UserId.AsShared());
|
||||||
|
|
||||||
|
if (Player)
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("GetUserPrivilege"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (!Helper.OnlineSub)
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Identity = Helper.OnlineSub->GetIdentityInterface();
|
||||||
|
if (Identity.IsValid())
|
||||||
|
{
|
||||||
|
Identity->ClearOnLoginCompleteDelegate_Handle(Player->GetControllerId(), DelegateHandle);
|
||||||
|
}
|
||||||
|
Player->SetCachedUniqueNetId(UniqueID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (APlayerState* State = PlayerControllerWeakPtr->PlayerState)
|
||||||
|
{
|
||||||
|
// Update UniqueId. See also ShowLoginUICallbackProxy.cpp
|
||||||
|
State->SetUniqueId(UniqueID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bWasSuccessful)
|
||||||
|
{
|
||||||
|
OnSuccess.Broadcast();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "LogoutUserCallbackProxy.h"
|
||||||
|
|
||||||
|
#include "Online.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// ULogoutUserCallbackProxy
|
||||||
|
|
||||||
|
ULogoutUserCallbackProxy::ULogoutUserCallbackProxy(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
, Delegate(FOnLogoutCompleteDelegate::CreateUObject(this, &ThisClass::OnCompleted))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ULogoutUserCallbackProxy* ULogoutUserCallbackProxy::LogoutUser(UObject* WorldContextObject, class APlayerController* PlayerController)
|
||||||
|
{
|
||||||
|
ULogoutUserCallbackProxy* Proxy = NewObject<ULogoutUserCallbackProxy>();
|
||||||
|
Proxy->PlayerControllerWeakPtr = PlayerController;
|
||||||
|
Proxy->WorldContextObject = WorldContextObject;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ULogoutUserCallbackProxy::Activate()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!PlayerControllerWeakPtr.IsValid())
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerControllerWeakPtr->Player);
|
||||||
|
|
||||||
|
if (!Player)
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("LogoutUser"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (!Helper.OnlineSub)
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto Identity = Helper.OnlineSub->GetIdentityInterface();
|
||||||
|
|
||||||
|
if (Identity.IsValid())
|
||||||
|
{
|
||||||
|
DelegateHandle = Identity->AddOnLogoutCompleteDelegate_Handle(Player->GetControllerId(), Delegate);
|
||||||
|
Identity->Logout(Player->GetControllerId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail immediately
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ULogoutUserCallbackProxy::OnCompleted(int LocalUserNum, bool bWasSuccessful)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (PlayerControllerWeakPtr.IsValid())
|
||||||
|
{
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(PlayerControllerWeakPtr->Player);
|
||||||
|
|
||||||
|
if (Player)
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("LogoutUser"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (!Helper.OnlineSub)
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto Identity = Helper.OnlineSub->GetIdentityInterface();
|
||||||
|
|
||||||
|
if (Identity.IsValid())
|
||||||
|
{
|
||||||
|
Identity->ClearOnLogoutCompleteDelegate_Handle(Player->GetControllerId(), DelegateHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bWasSuccessful)
|
||||||
|
{
|
||||||
|
OnSuccess.Broadcast();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#include "SendFriendInviteCallbackProxy.h"
|
||||||
|
|
||||||
|
#include "Online.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<USendFriendInviteCallbackProxy>();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("SendFriendInvite"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (!Helper.OnlineSub)
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Friends = Helper.OnlineSub->GetFriendsInterface();
|
||||||
|
if (Friends.IsValid())
|
||||||
|
{
|
||||||
|
ULocalPlayer* Player = Cast<ULocalPlayer>(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::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();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
#include "StartSessionCallbackProxyAdvanced.h"
|
||||||
|
|
||||||
|
UStartSessionCallbackProxyAdvanced::UStartSessionCallbackProxyAdvanced(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
, StartCompleteDelegate(FOnStartSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnStartCompleted))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UStartSessionCallbackProxyAdvanced* UStartSessionCallbackProxyAdvanced::StartAdvancedSession(
|
||||||
|
UObject* WorldContextObject)
|
||||||
|
{
|
||||||
|
UStartSessionCallbackProxyAdvanced* Proxy = NewObject<UStartSessionCallbackProxyAdvanced>();
|
||||||
|
Proxy->WorldContextObject = WorldContextObject;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UStartSessionCallbackProxyAdvanced::Activate()
|
||||||
|
{
|
||||||
|
const FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("StartSession"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (Helper.OnlineSub != nullptr)
|
||||||
|
{
|
||||||
|
const auto Sessions = Helper.OnlineSub->GetSessionInterface();
|
||||||
|
if (Sessions.IsValid())
|
||||||
|
{
|
||||||
|
StartCompleteDelegateHandle = Sessions->AddOnStartSessionCompleteDelegate_Handle(StartCompleteDelegate);
|
||||||
|
Sessions->StartSession(NAME_GameSession);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FFrame::KismetExecutionMessage(TEXT("Sessions not supported by Online Subsystem"), ELogVerbosity::Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail immediately
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UStartSessionCallbackProxyAdvanced::OnStartCompleted(FName SessionName, bool bWasSuccessful)
|
||||||
|
{
|
||||||
|
FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("StartSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (Helper.OnlineSub != nullptr)
|
||||||
|
{
|
||||||
|
auto Sessions = Helper.OnlineSub->GetSessionInterface();
|
||||||
|
if (Sessions.IsValid())
|
||||||
|
{
|
||||||
|
Sessions->ClearOnStartSessionCompleteDelegate_Handle(StartCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bWasSuccessful)
|
||||||
|
{
|
||||||
|
OnSuccess.Broadcast();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#include "UpdateSessionCallbackProxyAdvanced.h"
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// UUpdateSessionCallbackProxyAdvanced
|
||||||
|
|
||||||
|
UUpdateSessionCallbackProxyAdvanced::UUpdateSessionCallbackProxyAdvanced(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
, OnUpdateSessionCompleteDelegate(FOnUpdateSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnUpdateCompleted))
|
||||||
|
, NumPublicConnections(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UUpdateSessionCallbackProxyAdvanced* UUpdateSessionCallbackProxyAdvanced::UpdateSession(UObject* WorldContextObject, const TArray<FSessionPropertyKeyPair> &ExtraSettings, int32 PublicConnections, int32 PrivateConnections, bool bUseLAN, bool bAllowInvites, bool bAllowJoinInProgress, bool bRefreshOnlineData, bool bIsDedicatedServer, bool bShouldAdvertise)
|
||||||
|
{
|
||||||
|
UUpdateSessionCallbackProxyAdvanced* Proxy = NewObject<UUpdateSessionCallbackProxyAdvanced>();
|
||||||
|
Proxy->NumPublicConnections = PublicConnections;
|
||||||
|
Proxy->NumPrivateConnections = PrivateConnections;
|
||||||
|
Proxy->bUseLAN = bUseLAN;
|
||||||
|
Proxy->WorldContextObject = WorldContextObject;
|
||||||
|
Proxy->bAllowInvites = bAllowInvites;
|
||||||
|
Proxy->ExtraSettings = ExtraSettings;
|
||||||
|
Proxy->bRefreshOnlineData = bRefreshOnlineData;
|
||||||
|
Proxy->bAllowJoinInProgress = bAllowJoinInProgress;
|
||||||
|
Proxy->bDedicatedServer = bIsDedicatedServer;
|
||||||
|
Proxy->bShouldAdvertise = bShouldAdvertise;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UUpdateSessionCallbackProxyAdvanced::Activate()
|
||||||
|
{
|
||||||
|
const FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("UpdateSession"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (Helper.OnlineSub != nullptr)
|
||||||
|
{
|
||||||
|
const auto Sessions = Helper.OnlineSub->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(NAME_GameSession);
|
||||||
|
FOnlineSessionSettings* Settings = Sessions->GetSessionSettings(NAME_GameSession);
|
||||||
|
|
||||||
|
if (!Settings)
|
||||||
|
{
|
||||||
|
// Fail immediately
|
||||||
|
OnFailure.Broadcast();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnUpdateSessionCompleteDelegateHandle = Sessions->AddOnUpdateSessionCompleteDelegate_Handle(OnUpdateSessionCompleteDelegate);
|
||||||
|
|
||||||
|
// FOnlineSessionSettings Settings;
|
||||||
|
//Settings->BuildUniqueId = GetBuildUniqueId();
|
||||||
|
Settings->NumPublicConnections = NumPublicConnections;
|
||||||
|
Settings->NumPrivateConnections = NumPrivateConnections;
|
||||||
|
Settings->bShouldAdvertise = bShouldAdvertise;
|
||||||
|
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(NAME_GameSession, *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)
|
||||||
|
{
|
||||||
|
const FOnlineSubsystemBPCallHelperAdvanced Helper(TEXT("UpdateSessionCallback"), GEngine->GetWorldFromContextObject(WorldContextObject.Get(), EGetWorldErrorMode::LogAndReturnNull));
|
||||||
|
|
||||||
|
if (Helper.OnlineSub != nullptr)
|
||||||
|
{
|
||||||
|
const auto Sessions = Helper.OnlineSub->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"));
|
||||||
|
}
|
||||||
|
}
|
42
Plugins/AdvancedSteamSessions/AdvancedSteamSessions.uplugin
Normal file
42
Plugins/AdvancedSteamSessions/AdvancedSteamSessions.uplugin
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"FileVersion" : 3,
|
||||||
|
|
||||||
|
"FriendlyName" : "Advanced Steam Sessions",
|
||||||
|
"Version" : 5.4,
|
||||||
|
"VersionName": "5.4",
|
||||||
|
"Description" : "Adds new blueprint functions to handle more advanced session operations in Steam. REQUIRES ADVANCED SESSIONS",
|
||||||
|
"Category" : "Advanced Sessions Plugin",
|
||||||
|
"CreatedBy" : "Joshua Statzer",
|
||||||
|
"CreatedByURL" : "N/A",
|
||||||
|
|
||||||
|
"Modules" :
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"Name": "AdvancedSteamSessions",
|
||||||
|
"Type": "RunTime",
|
||||||
|
"LoadingPhase": "PostDefault"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Plugins": [
|
||||||
|
{
|
||||||
|
"Name": "AdvancedSessions",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "OnlineSubsystem",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "OnlineSubsystemSteam",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "OnlineSubsystemUtils",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "SteamShared",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
8
Plugins/AdvancedSteamSessions/Config/FilterPlugin.ini
Normal file
8
Plugins/AdvancedSteamSessions/Config/FilterPlugin.ini
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[FilterPlugin]
|
||||||
|
; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and
|
||||||
|
; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively.
|
||||||
|
;
|
||||||
|
; Examples:
|
||||||
|
; /README.txt
|
||||||
|
; /Extras/...
|
||||||
|
; /Binaries/ThirdParty/*.dll
|
BIN
Plugins/AdvancedSteamSessions/Resources/Icon128.png
(Stored with Git LFS)
Normal file
BIN
Plugins/AdvancedSteamSessions/Resources/Icon128.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,23 @@
|
|||||||
|
using UnrealBuildTool;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
public class AdvancedSteamSessions : ModuleRules
|
||||||
|
{
|
||||||
|
public AdvancedSteamSessions(ReadOnlyTargetRules Target) : base(Target)
|
||||||
|
{
|
||||||
|
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
//bEnforceIWYU = true;
|
||||||
|
|
||||||
|
PublicDefinitions.Add("WITH_ADVANCED_STEAM_SESSIONS=1");
|
||||||
|
|
||||||
|
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "OnlineSubsystem", "CoreUObject", "OnlineSubsystemUtils", "Networking", "Sockets", "AdvancedSessions"/*"Voice", "OnlineSubsystemSteam"*/ });
|
||||||
|
PrivateDependencyModuleNames.AddRange(new string[] { "OnlineSubsystem", "Sockets", "Networking", "OnlineSubsystemUtils" /*"Voice", "Steamworks","OnlineSubsystemSteam"*/});
|
||||||
|
|
||||||
|
if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Linux) || (Target.Platform == UnrealTargetPlatform.Mac))
|
||||||
|
{
|
||||||
|
PublicDependencyModuleNames.AddRange(new string[] { "SteamShared", "Steamworks", "OnlineSubsystemSteam" });
|
||||||
|
AddEngineThirdPartyPrivateStaticDependencies(Target, "Steamworks");
|
||||||
|
//PublicIncludePaths.AddRange(new string[] { "../Plugins/Online/OnlineSubsystemSteam/Source/Private" });// This is dumb but it isn't very open
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,389 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "Online.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#include "Interfaces/OnlineFriendsInterface.h"
|
||||||
|
#include "Interfaces/OnlineUserInterface.h"
|
||||||
|
#include "Interfaces/OnlineMessageInterface.h"
|
||||||
|
#include "Interfaces/OnlinePresenceInterface.h"
|
||||||
|
#include "Engine/GameInstance.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "UObject/UObjectIterator.h"
|
||||||
|
|
||||||
|
// This is taken directly from UE4 - OnlineSubsystemSteamPrivatePCH.h as a fix for the array_count macro
|
||||||
|
// @todo Steam: Steam headers trigger secure-C-runtime warnings in Visual C++. Rather than mess with _CRT_SECURE_NO_WARNINGS, we'll just
|
||||||
|
// disable the warnings locally. Remove when this is fixed in the SDK
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
// #TODO check back on this at some point
|
||||||
|
#pragma warning(disable:4265) // SteamAPI CCallback< specifically, this warning is off by default but 4.17 turned it on....
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
|
||||||
|
#pragma push_macro("ARRAY_COUNT")
|
||||||
|
#undef ARRAY_COUNT
|
||||||
|
|
||||||
|
#if USING_CODE_ANALYSIS
|
||||||
|
MSVC_PRAGMA(warning(push))
|
||||||
|
MSVC_PRAGMA(warning(disable : ALL_CODE_ANALYSIS_WARNINGS))
|
||||||
|
#endif // USING_CODE_ANALYSIS
|
||||||
|
|
||||||
|
#include <steam/steam_api.h>
|
||||||
|
|
||||||
|
#if USING_CODE_ANALYSIS
|
||||||
|
MSVC_PRAGMA(warning(pop))
|
||||||
|
#endif // USING_CODE_ANALYSIS
|
||||||
|
|
||||||
|
#include <steam/isteamapps.h>
|
||||||
|
#include <steam/isteamapplist.h>
|
||||||
|
//#include <OnlineSubsystemSteamTypes.h>
|
||||||
|
#pragma pop_macro("ARRAY_COUNT")
|
||||||
|
|
||||||
|
// @todo Steam: See above
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Making a copy of this here since the original is still in a private folder and is screwing with things
|
||||||
|
/**
|
||||||
|
* Steam specific implementation of the unique net id
|
||||||
|
*/
|
||||||
|
class FUniqueNetIdSteam2 :
|
||||||
|
public FUniqueNetId
|
||||||
|
{
|
||||||
|
PACKAGE_SCOPE:
|
||||||
|
/** Holds the net id for a player */
|
||||||
|
uint64 UniqueNetId;
|
||||||
|
|
||||||
|
/** Hidden on purpose */
|
||||||
|
FUniqueNetIdSteam2() :
|
||||||
|
UniqueNetId(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy Constructor
|
||||||
|
*
|
||||||
|
* @param Src the id to copy
|
||||||
|
*/
|
||||||
|
explicit FUniqueNetIdSteam2(const FUniqueNetIdSteam2& Src) :
|
||||||
|
UniqueNetId(Src.UniqueNetId)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructs this object with the specified net id
|
||||||
|
*
|
||||||
|
* @param InUniqueNetId the id to set ours to
|
||||||
|
*/
|
||||||
|
explicit FUniqueNetIdSteam2(uint64 InUniqueNetId) :
|
||||||
|
UniqueNetId(InUniqueNetId)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs this object with the steam id
|
||||||
|
*
|
||||||
|
* @param InUniqueNetId the id to set ours to
|
||||||
|
*/
|
||||||
|
explicit FUniqueNetIdSteam2(CSteamID InSteamId) :
|
||||||
|
UniqueNetId(InSteamId.ConvertToUint64())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs this object with the specified net id
|
||||||
|
*
|
||||||
|
* @param String textual representation of an id
|
||||||
|
*/
|
||||||
|
explicit FUniqueNetIdSteam2(const FString& Str) :
|
||||||
|
UniqueNetId(FCString::Atoi64(*Str))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs this object with the specified net id
|
||||||
|
*
|
||||||
|
* @param InUniqueNetId the id to set ours to (assumed to be FUniqueNetIdSteam in fact)
|
||||||
|
*/
|
||||||
|
explicit FUniqueNetIdSteam2(const FUniqueNetId& InUniqueNetId) :
|
||||||
|
UniqueNetId(*(uint64*)InUniqueNetId.GetBytes())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual FName GetType() const override
|
||||||
|
{
|
||||||
|
return STEAM_SUBSYSTEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the raw byte representation of this net id
|
||||||
|
* This data is platform dependent and shouldn't be manipulated directly
|
||||||
|
*
|
||||||
|
* @return byte array of size GetSize()
|
||||||
|
*/
|
||||||
|
virtual const uint8* GetBytes() const override
|
||||||
|
{
|
||||||
|
return (uint8*)&UniqueNetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the size of the id
|
||||||
|
*
|
||||||
|
* @return size in bytes of the id representation
|
||||||
|
*/
|
||||||
|
virtual int32 GetSize() const override
|
||||||
|
{
|
||||||
|
return sizeof(uint64);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the validity of the id
|
||||||
|
*
|
||||||
|
* @return true if this is a well formed ID, false otherwise
|
||||||
|
*/
|
||||||
|
virtual bool IsValid() const override
|
||||||
|
{
|
||||||
|
return UniqueNetId != 0 && CSteamID(UniqueNetId).IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Platform specific conversion to string representation of data
|
||||||
|
*
|
||||||
|
* @return data in string form
|
||||||
|
*/
|
||||||
|
virtual FString ToString() const override
|
||||||
|
{
|
||||||
|
return FString::Printf(TEXT("%llu"), UniqueNetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a human readable representation of the net id
|
||||||
|
* Shouldn't be used for anything other than logging/debugging
|
||||||
|
*
|
||||||
|
* @return id in string form
|
||||||
|
*/
|
||||||
|
virtual FString ToDebugString() const override
|
||||||
|
{
|
||||||
|
CSteamID SteamID(UniqueNetId);
|
||||||
|
if (SteamID.IsLobby())
|
||||||
|
{
|
||||||
|
return FString::Printf(TEXT("Lobby [0x%llX]"), UniqueNetId);
|
||||||
|
}
|
||||||
|
else if (SteamID.BAnonGameServerAccount())
|
||||||
|
{
|
||||||
|
return FString::Printf(TEXT("Server [0x%llX]"), UniqueNetId);
|
||||||
|
}
|
||||||
|
else if (SteamID.IsValid())
|
||||||
|
{
|
||||||
|
const FString NickName(SteamFriends() ? UTF8_TO_TCHAR(SteamFriends()->GetFriendPersonaName(UniqueNetId)) : TEXT("UNKNOWN"));
|
||||||
|
return FString::Printf(TEXT("%s [0x%llX]"), *NickName, UniqueNetId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FString::Printf(TEXT("INVALID [0x%llX]"), UniqueNetId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual uint32 GetTypeHash() const override
|
||||||
|
{
|
||||||
|
return ::GetTypeHash(UniqueNetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convenience cast to CSteamID */
|
||||||
|
operator CSteamID()
|
||||||
|
{
|
||||||
|
return UniqueNetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convenience cast to CSteamID */
|
||||||
|
operator const CSteamID() const
|
||||||
|
{
|
||||||
|
return UniqueNetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convenience cast to CSteamID pointer */
|
||||||
|
operator CSteamID*()
|
||||||
|
{
|
||||||
|
return (CSteamID*)&UniqueNetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convenience cast to CSteamID pointer */
|
||||||
|
operator const CSteamID*() const
|
||||||
|
{
|
||||||
|
return (const CSteamID*)&UniqueNetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend FArchive& operator<<(FArchive& Ar, FUniqueNetIdSteam2& UserId)
|
||||||
|
{
|
||||||
|
return Ar << UserId.UniqueNetId;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "AdvancedSteamFriendsLibrary.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
//General Advanced Sessions Log
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(AdvancedSteamFriendsLog, Log, All);
|
||||||
|
|
||||||
|
UENUM(Blueprintable)
|
||||||
|
enum class SteamAvatarSize : uint8
|
||||||
|
{
|
||||||
|
SteamAvatar_INVALID = 0,
|
||||||
|
SteamAvatar_Small = 1,
|
||||||
|
SteamAvatar_Medium = 2,
|
||||||
|
SteamAvatar_Large = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
UENUM(Blueprintable)
|
||||||
|
enum class ESteamUserOverlayType : uint8
|
||||||
|
{
|
||||||
|
/*Opens the overlay web browser to the specified user or groups profile.*/
|
||||||
|
steamid,
|
||||||
|
/*Opens a chat window to the specified user, or joins the group chat.*/
|
||||||
|
chat,
|
||||||
|
/*Opens a window to a Steam Trading session that was started with the ISteamEconomy / StartTrade Web API.*/
|
||||||
|
jointrade,
|
||||||
|
/*Opens the overlay web browser to the specified user's stats.*/
|
||||||
|
stats,
|
||||||
|
/*Opens the overlay web browser to the specified user's achievements.*/
|
||||||
|
achievements,
|
||||||
|
/*Opens the overlay in minimal mode prompting the user to add the target user as a friend.*/
|
||||||
|
friendadd,
|
||||||
|
/*Opens the overlay in minimal mode prompting the user to remove the target friend.*/
|
||||||
|
friendremove,
|
||||||
|
/*Opens the overlay in minimal mode prompting the user to accept an incoming friend invite.*/
|
||||||
|
friendrequestaccept,
|
||||||
|
/*Opens the overlay in minimal mode prompting the user to ignore an incoming friend invite.*/
|
||||||
|
friendrequestignore,
|
||||||
|
/*Opens the invite overlay, invitations sent from this dialog will be for the provided lobby*/
|
||||||
|
invitetolobby
|
||||||
|
};
|
||||||
|
|
||||||
|
static FString EnumToString(const FString& enumName, uint8 value)
|
||||||
|
{
|
||||||
|
|
||||||
|
const UEnum* EnumPtr = FindFirstObject<UEnum>(*enumName, EFindFirstObjectOptions::None, ELogVerbosity::Warning, TEXT("EumtoString"));
|
||||||
|
|
||||||
|
if (!EnumPtr)
|
||||||
|
return FString();
|
||||||
|
|
||||||
|
FString EnumName = EnumPtr->GetNameStringByIndex(value);
|
||||||
|
return EnumName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
struct FBPSteamGroupInfo
|
||||||
|
{
|
||||||
|
GENERATED_USTRUCT_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
FBPUniqueNetId GroupID; // Uint64 representation
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
FString GroupName;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
FString GroupTag;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
int32 numOnline = 0;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
int32 numInGame = 0;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
int32 numChatting = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
UENUM(Blueprintable)
|
||||||
|
enum class EBPTextFilteringContext : uint8
|
||||||
|
{
|
||||||
|
/*Unknown context.*/
|
||||||
|
FContext_Unknown = 0,
|
||||||
|
/*Game content, only legally required filtering is performed.*/
|
||||||
|
FContext_GameContent = 1,
|
||||||
|
/*Char from another player.*/
|
||||||
|
FContext_Chat = 2,
|
||||||
|
/*Character or item name.*/
|
||||||
|
FContext_Name = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class UAdvancedSteamFriendsLibrary : public UBlueprintFunctionLibrary
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
|
||||||
|
//********* Friend List Functions *************//
|
||||||
|
|
||||||
|
// Get a texture of a valid friends avatar, STEAM ONLY, Returns invalid texture if the subsystem hasn't loaded that size of avatar yet
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI", meta = (ExpandEnumAsExecs = "Result"))
|
||||||
|
static UTexture2D * GetSteamFriendAvatar(const FBPUniqueNetId UniqueNetId, EBlueprintAsyncResultSwitch &Result, SteamAvatarSize AvatarSize = SteamAvatarSize::SteamAvatar_Medium);
|
||||||
|
|
||||||
|
// Preloads the avatar and name of a steam friend, return whether it is already available or not, STEAM ONLY, Takes time to actually load everything after this is called.
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI")
|
||||||
|
static bool RequestSteamFriendInfo(const FBPUniqueNetId UniqueNetId, bool bRequireNameOnly = false);
|
||||||
|
|
||||||
|
// Opens the steam overlay to go to the specified user dialog
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI")
|
||||||
|
static bool OpenSteamUserOverlay(const FBPUniqueNetId UniqueNetId, ESteamUserOverlayType DialogType);
|
||||||
|
|
||||||
|
// Returns if the steam overlay is currently active (this can return false during initial overlay hooking)
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|SteamAPI")
|
||||||
|
static bool IsOverlayEnabled();
|
||||||
|
|
||||||
|
// Gets the level of a friends steam account, STEAM ONLY, Returns -1 if the steam level is not known, might need RequestSteamFriendInfo called first.
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI")
|
||||||
|
static int32 GetFriendSteamLevel(const FBPUniqueNetId UniqueNetId);
|
||||||
|
|
||||||
|
// Gets the persona name of a steam ID, STEAM ONLY, Returns empty if no result, might need RequestSteamFriendInfo called first.
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI")
|
||||||
|
static FString GetSteamPersonaName(const FBPUniqueNetId UniqueNetId);
|
||||||
|
|
||||||
|
// Creates a unique steam id directly from a string holding a uint64 value, useful for testing
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|SteamAPI")
|
||||||
|
static FBPUniqueNetId CreateSteamIDFromString(const FString SteamID64);
|
||||||
|
|
||||||
|
// Retreives the local steam ID from steam
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|AdvancedFriends|SteamAPI")
|
||||||
|
static FBPUniqueNetId GetLocalSteamIDFromSteam();
|
||||||
|
|
||||||
|
/* Gets the current game played by a friend - AppID is int32 even though steam ids are uint32, can't be helped in blueprint currently
|
||||||
|
* can use the AppID with the WebAPI GetAppList request.
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedFriends|SteamAPI", meta = (ExpandEnumAsExecs = "Result"))
|
||||||
|
static void GetSteamFriendGamePlayed(const FBPUniqueNetId UniqueNetId, EBlueprintResultSwitch &Result/*, FString & GameName*/, int32 & AppID);
|
||||||
|
|
||||||
|
// Get a full list of steam groups
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
static void GetSteamGroups(TArray<FBPSteamGroupInfo> & SteamGroups);
|
||||||
|
|
||||||
|
// Initializes text filtering (pre-loading dictonaries)
|
||||||
|
// Returns if it succeeded, false if filtering is unavailable for the games language
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|SteamAPI|TextFiltering")
|
||||||
|
static bool InitTextFiltering();
|
||||||
|
|
||||||
|
// Attempts to filter a string with the given filtering context
|
||||||
|
// Returns true if the text has been filtered, false if it hasn't (no filtering required or operation failed)
|
||||||
|
// If false it will still output the original text
|
||||||
|
// Textsource is the steam id that is the source of the text (player name / chat)
|
||||||
|
// Requires that InitTextFiltering be called first!!
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|SteamAPI|TextFiltering")
|
||||||
|
static bool FilterText(FString TextToFilter, EBPTextFilteringContext Context, const FBPUniqueNetId TextSourceID, FString& FilteredText);
|
||||||
|
|
||||||
|
// Returns if steam is running in big picture mode
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Online|SteamAPI")
|
||||||
|
static bool IsSteamInBigPictureMode();
|
||||||
|
};
|
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Modules/ModuleManager.h"
|
||||||
|
|
||||||
|
class AdvancedSteamSessions : public IModuleInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** IModuleInterface implementation */
|
||||||
|
void StartupModule();
|
||||||
|
void ShutdownModule();
|
||||||
|
};
|
@ -0,0 +1,351 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "Online.h"
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
#include "steam/isteamugc.h"
|
||||||
|
#include "steam/isteamremotestorage.h"
|
||||||
|
#endif
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
|
||||||
|
// @todo Steam: Steam headers trigger secure-C-runtime warnings in Visual C++. Rather than mess with _CRT_SECURE_NO_WARNINGS, we'll just
|
||||||
|
// disable the warnings locally. Remove when this is fixed in the SDK
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
// #TODO check back on this at some point
|
||||||
|
#pragma warning(disable:4265) // SteamAPI CCallback< specifically, this warning is off by default but 4.17 turned it on....
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
|
||||||
|
#pragma push_macro("ARRAY_COUNT")
|
||||||
|
#undef ARRAY_COUNT
|
||||||
|
|
||||||
|
#if USING_CODE_ANALYSIS
|
||||||
|
MSVC_PRAGMA(warning(push))
|
||||||
|
MSVC_PRAGMA(warning(disable : ALL_CODE_ANALYSIS_WARNINGS))
|
||||||
|
#endif // USING_CODE_ANALYSIS
|
||||||
|
|
||||||
|
#include <steam/steam_api.h>
|
||||||
|
|
||||||
|
#if USING_CODE_ANALYSIS
|
||||||
|
MSVC_PRAGMA(warning(pop))
|
||||||
|
#endif // USING_CODE_ANALYSIS
|
||||||
|
|
||||||
|
|
||||||
|
#pragma pop_macro("ARRAY_COUNT")
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// @todo Steam: See above
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "AdvancedSteamWorkshopLibrary.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
//General Advanced Sessions Log
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(AdvancedSteamWorkshopLog, Log, All);
|
||||||
|
|
||||||
|
|
||||||
|
// Using a custom struct because uint32 isn't blueprint supported and I don't want to cast to int32
|
||||||
|
// due to the size of the workshop it could end up overflowing?
|
||||||
|
USTRUCT(BlueprintType)
|
||||||
|
struct FBPSteamWorkshopID
|
||||||
|
{
|
||||||
|
GENERATED_USTRUCT_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
uint64 SteamWorkshopID;
|
||||||
|
|
||||||
|
FBPSteamWorkshopID()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
FBPSteamWorkshopID(uint64 ID)
|
||||||
|
{
|
||||||
|
SteamWorkshopID = ID;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// General result codes - Copying steams version over
|
||||||
|
// Check these to future proof
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class FBPSteamResult : uint8
|
||||||
|
{
|
||||||
|
K_EResultInvalid = 0,
|
||||||
|
k_EResultOK = 1, // success
|
||||||
|
k_EResultFail = 2, // generic failure
|
||||||
|
k_EResultNoConnection = 3, // no/failed network connection
|
||||||
|
// k_EResultNoConnectionRetry = 4, // OBSOLETE - removed
|
||||||
|
k_EResultInvalidPassword = 5, // password/ticket is invalid
|
||||||
|
k_EResultLoggedInElsewhere = 6, // same user logged in elsewhere
|
||||||
|
k_EResultInvalidProtocolVer = 7, // protocol version is incorrect
|
||||||
|
k_EResultInvalidParam = 8, // a parameter is incorrect
|
||||||
|
k_EResultFileNotFound = 9, // file was not found
|
||||||
|
k_EResultBusy = 10, // called method busy - action not taken
|
||||||
|
k_EResultInvalidState = 11, // called object was in an invalid state
|
||||||
|
k_EResultInvalidName = 12, // name is invalid
|
||||||
|
k_EResultInvalidEmail = 13, // email is invalid
|
||||||
|
k_EResultDuplicateName = 14, // name is not unique
|
||||||
|
k_EResultAccessDenied = 15, // access is denied
|
||||||
|
k_EResultTimeout = 16, // operation timed out
|
||||||
|
k_EResultBanned = 17, // VAC2 banned
|
||||||
|
k_EResultAccountNotFound = 18, // account not found
|
||||||
|
k_EResultInvalidSteamID = 19, // steamID is invalid
|
||||||
|
k_EResultServiceUnavailable = 20, // The requested service is currently unavailable
|
||||||
|
k_EResultNotLoggedOn = 21, // The user is not logged on
|
||||||
|
k_EResultPending = 22, // Request is pending (may be in process, or waiting on third party)
|
||||||
|
k_EResultEncryptionFailure = 23, // Encryption or Decryption failed
|
||||||
|
k_EResultInsufficientPrivilege = 24, // Insufficient privilege
|
||||||
|
k_EResultLimitExceeded = 25, // Too much of a good thing
|
||||||
|
k_EResultRevoked = 26, // Access has been revoked (used for revoked guest passes)
|
||||||
|
k_EResultExpired = 27, // License/Guest pass the user is trying to access is expired
|
||||||
|
k_EResultAlreadyRedeemed = 28, // Guest pass has already been redeemed by account, cannot be acked again
|
||||||
|
k_EResultDuplicateRequest = 29, // The request is a duplicate and the action has already occurred in the past, ignored this time
|
||||||
|
k_EResultAlreadyOwned = 30, // All the games in this guest pass redemption request are already owned by the user
|
||||||
|
k_EResultIPNotFound = 31, // IP address not found
|
||||||
|
k_EResultPersistFailed = 32, // failed to write change to the data store
|
||||||
|
k_EResultLockingFailed = 33, // failed to acquire access lock for this operation
|
||||||
|
k_EResultLogonSessionReplaced = 34,
|
||||||
|
k_EResultConnectFailed = 35,
|
||||||
|
k_EResultHandshakeFailed = 36,
|
||||||
|
k_EResultIOFailure = 37,
|
||||||
|
k_EResultRemoteDisconnect = 38,
|
||||||
|
k_EResultShoppingCartNotFound = 39, // failed to find the shopping cart requested
|
||||||
|
k_EResultBlocked = 40, // a user didn't allow it
|
||||||
|
k_EResultIgnored = 41, // target is ignoring sender
|
||||||
|
k_EResultNoMatch = 42, // nothing matching the request found
|
||||||
|
k_EResultAccountDisabled = 43,
|
||||||
|
k_EResultServiceReadOnly = 44, // this service is not accepting content changes right now
|
||||||
|
k_EResultAccountNotFeatured = 45, // account doesn't have value, so this feature isn't available
|
||||||
|
k_EResultAdministratorOK = 46, // allowed to take this action, but only because requester is admin
|
||||||
|
k_EResultContentVersion = 47, // A Version mismatch in content transmitted within the Steam protocol.
|
||||||
|
k_EResultTryAnotherCM = 48, // The current CM can't service the user making a request, user should try another.
|
||||||
|
k_EResultPasswordRequiredToKickSession = 49,// You are already logged in elsewhere, this cached credential login has failed.
|
||||||
|
k_EResultAlreadyLoggedInElsewhere = 50, // You are already logged in elsewhere, you must wait
|
||||||
|
k_EResultSuspended = 51, // Long running operation (content download) suspended/paused
|
||||||
|
k_EResultCancelled = 52, // Operation canceled (typically by user: content download)
|
||||||
|
k_EResultDataCorruption = 53, // Operation canceled because data is ill formed or unrecoverable
|
||||||
|
k_EResultDiskFull = 54, // Operation canceled - not enough disk space.
|
||||||
|
k_EResultRemoteCallFailed = 55, // an remote call or IPC call failed
|
||||||
|
k_EResultPasswordUnset = 56, // Password could not be verified as it's unset server side
|
||||||
|
k_EResultExternalAccountUnlinked = 57, // External account (PSN, Facebook...) is not linked to a Steam account
|
||||||
|
k_EResultPSNTicketInvalid = 58, // PSN ticket was invalid
|
||||||
|
k_EResultExternalAccountAlreadyLinked = 59, // External account (PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first
|
||||||
|
k_EResultRemoteFileConflict = 60, // The sync cannot resume due to a conflict between the local and remote files
|
||||||
|
k_EResultIllegalPassword = 61, // The requested new password is not legal
|
||||||
|
k_EResultSameAsPreviousValue = 62, // new value is the same as the old one ( secret question and answer )
|
||||||
|
k_EResultAccountLogonDenied = 63, // account login denied due to 2nd factor authentication failure
|
||||||
|
k_EResultCannotUseOldPassword = 64, // The requested new password is not legal
|
||||||
|
k_EResultInvalidLoginAuthCode = 65, // account login denied due to auth code invalid
|
||||||
|
k_EResultAccountLogonDeniedNoMail = 66, // account login denied due to 2nd factor auth failure - and no mail has been sent
|
||||||
|
k_EResultHardwareNotCapableOfIPT = 67, //
|
||||||
|
k_EResultIPTInitError = 68, //
|
||||||
|
k_EResultParentalControlRestricted = 69, // operation failed due to parental control restrictions for current user
|
||||||
|
k_EResultFacebookQueryError = 70, // Facebook query returned an error
|
||||||
|
k_EResultExpiredLoginAuthCode = 71, // account login denied due to auth code expired
|
||||||
|
k_EResultIPLoginRestrictionFailed = 72,
|
||||||
|
k_EResultAccountLockedDown = 73,
|
||||||
|
k_EResultAccountLogonDeniedVerifiedEmailRequired = 74,
|
||||||
|
k_EResultNoMatchingURL = 75,
|
||||||
|
k_EResultBadResponse = 76, // parse failure, missing field, etc.
|
||||||
|
k_EResultRequirePasswordReEntry = 77, // The user cannot complete the action until they re-enter their password
|
||||||
|
k_EResultValueOutOfRange = 78, // the value entered is outside the acceptable range
|
||||||
|
k_EResultUnexpectedError = 79, // something happened that we didn't expect to ever happen
|
||||||
|
k_EResultDisabled = 80, // The requested service has been configured to be unavailable
|
||||||
|
k_EResultInvalidCEGSubmission = 81, // The set of files submitted to the CEG server are not valid !
|
||||||
|
k_EResultRestrictedDevice = 82, // The device being used is not allowed to perform this action
|
||||||
|
k_EResultRegionLocked = 83, // The action could not be complete because it is region restricted
|
||||||
|
k_EResultRateLimitExceeded = 84, // Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent
|
||||||
|
k_EResultAccountLoginDeniedNeedTwoFactor = 85, // Need two-factor code to login
|
||||||
|
k_EResultItemDeleted = 86, // The thing we're trying to access has been deleted
|
||||||
|
k_EResultAccountLoginDeniedThrottle = 87, // login attempt failed, try to throttle response to possible attacker
|
||||||
|
k_EResultTwoFactorCodeMismatch = 88, // two factor code mismatch
|
||||||
|
k_EResultTwoFactorActivationCodeMismatch = 89, // activation code for two-factor didn't match
|
||||||
|
k_EResultAccountAssociatedToMultiplePartners = 90, // account has been associated with multiple partners
|
||||||
|
k_EResultNotModified = 91, // data not modified
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check these to future proof
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class FBPWorkshopFileType : uint8
|
||||||
|
{
|
||||||
|
k_EWorkshopFileTypeCommunity = 0,
|
||||||
|
k_EWorkshopFileTypeMicrotransaction = 1,
|
||||||
|
k_EWorkshopFileTypeCollection = 2,
|
||||||
|
k_EWorkshopFileTypeArt = 3,
|
||||||
|
k_EWorkshopFileTypeVideo = 4,
|
||||||
|
k_EWorkshopFileTypeScreenshot = 5,
|
||||||
|
k_EWorkshopFileTypeGame = 6,
|
||||||
|
k_EWorkshopFileTypeSoftware = 7,
|
||||||
|
k_EWorkshopFileTypeConcept = 8,
|
||||||
|
k_EWorkshopFileTypeWebGuide = 9,
|
||||||
|
k_EWorkshopFileTypeIntegratedGuide = 10,
|
||||||
|
k_EWorkshopFileTypeMerch = 11,
|
||||||
|
k_EWorkshopFileTypeControllerBinding = 12,
|
||||||
|
k_EWorkshopFileTypeSteamworksAccessInvite = 13,
|
||||||
|
k_EWorkshopFileTypeSteamVideo = 14,
|
||||||
|
|
||||||
|
// Update k_EWorkshopFileTypeMax if you add values.
|
||||||
|
k_EWorkshopFileTypeMax = 15
|
||||||
|
};
|
||||||
|
|
||||||
|
// WorkshopItemDetails Struct
|
||||||
|
USTRUCT(BlueprintType)
|
||||||
|
struct FBPSteamWorkshopItemDetails
|
||||||
|
{
|
||||||
|
GENERATED_USTRUCT_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FBPSteamWorkshopItemDetails()
|
||||||
|
{
|
||||||
|
ResultOfRequest = FBPSteamResult::k_EResultOK;
|
||||||
|
FileType = FBPWorkshopFileType::k_EWorkshopFileTypeMax;
|
||||||
|
CreatorAppID = 0;
|
||||||
|
ConsumerAppID = 0;
|
||||||
|
VotesUp = 0;
|
||||||
|
VotesDown = 0;
|
||||||
|
CalculatedScore = 0.f;
|
||||||
|
bBanned = false;
|
||||||
|
bAcceptedForUse = false;
|
||||||
|
bTagsTruncated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
FBPSteamWorkshopItemDetails(SteamUGCDetails_t &hUGCDetails)
|
||||||
|
{
|
||||||
|
ResultOfRequest = (FBPSteamResult)hUGCDetails.m_eResult;
|
||||||
|
FileType = (FBPWorkshopFileType)hUGCDetails.m_eFileType;
|
||||||
|
CreatorAppID = (int32)hUGCDetails.m_nCreatorAppID;
|
||||||
|
ConsumerAppID = (int32)hUGCDetails.m_nConsumerAppID;
|
||||||
|
Title = FString(hUGCDetails.m_rgchTitle, k_cchPublishedDocumentTitleMax);
|
||||||
|
Description = FString(hUGCDetails.m_rgchDescription, k_cchPublishedDocumentDescriptionMax);
|
||||||
|
ItemUrl = FString(hUGCDetails.m_rgchURL, k_cchPublishedFileURLMax);
|
||||||
|
VotesUp = (int32)hUGCDetails.m_unVotesUp;
|
||||||
|
VotesDown = (int32)hUGCDetails.m_unVotesDown;
|
||||||
|
CalculatedScore = hUGCDetails.m_flScore;
|
||||||
|
bBanned = hUGCDetails.m_bBanned;
|
||||||
|
bAcceptedForUse = hUGCDetails.m_bAcceptedForUse;
|
||||||
|
bTagsTruncated = hUGCDetails.m_bTagsTruncated;
|
||||||
|
|
||||||
|
CreatorSteamID = FString::Printf(TEXT("%llu"), hUGCDetails.m_ulSteamIDOwner);
|
||||||
|
}
|
||||||
|
|
||||||
|
FBPSteamWorkshopItemDetails(const SteamUGCDetails_t &hUGCDetails)
|
||||||
|
{
|
||||||
|
ResultOfRequest = (FBPSteamResult)hUGCDetails.m_eResult;
|
||||||
|
FileType = (FBPWorkshopFileType)hUGCDetails.m_eFileType;
|
||||||
|
CreatorAppID = (int32)hUGCDetails.m_nCreatorAppID;
|
||||||
|
ConsumerAppID = (int32)hUGCDetails.m_nConsumerAppID;
|
||||||
|
Title = FString(hUGCDetails.m_rgchTitle, k_cchPublishedDocumentTitleMax);
|
||||||
|
Description = FString(hUGCDetails.m_rgchDescription, k_cchPublishedDocumentDescriptionMax);
|
||||||
|
ItemUrl = FString(hUGCDetails.m_rgchURL, k_cchPublishedFileURLMax);
|
||||||
|
VotesUp = (int32)hUGCDetails.m_unVotesUp;
|
||||||
|
VotesDown = (int32)hUGCDetails.m_unVotesDown;
|
||||||
|
CalculatedScore = hUGCDetails.m_flScore;
|
||||||
|
bBanned = hUGCDetails.m_bBanned;
|
||||||
|
bAcceptedForUse = hUGCDetails.m_bAcceptedForUse;
|
||||||
|
bTagsTruncated = hUGCDetails.m_bTagsTruncated;
|
||||||
|
|
||||||
|
CreatorSteamID = FString::Printf(TEXT("%llu"), hUGCDetails.m_ulSteamIDOwner);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Result of obtaining the details
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
FBPSteamResult ResultOfRequest;
|
||||||
|
|
||||||
|
// Type of file
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
FBPWorkshopFileType FileType;
|
||||||
|
|
||||||
|
// These two are listed as baked to an int, but is stored as a uint, think its safe to keep int
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
int32 CreatorAppID;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
int32 ConsumerAppID;
|
||||||
|
|
||||||
|
// Title of item
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
FString Title;
|
||||||
|
|
||||||
|
// Description of item
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
FString Description;
|
||||||
|
|
||||||
|
//Url for a video of website
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
FString ItemUrl;
|
||||||
|
|
||||||
|
// Votes will be unlikely to go above signed limited
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
int32 VotesUp;
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
int32 VotesDown;
|
||||||
|
|
||||||
|
// Calculated score
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
float CalculatedScore;
|
||||||
|
|
||||||
|
// whether the file was banned
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
bool bBanned;
|
||||||
|
|
||||||
|
// developer has specifically flagged this item as accepted in the Workshop
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
bool bAcceptedForUse;
|
||||||
|
|
||||||
|
// whether the list of tags was too long to be returned in the provided buffer
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
bool bTagsTruncated;
|
||||||
|
|
||||||
|
// Steam ID of the user who created this content.
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
FString CreatorSteamID;
|
||||||
|
|
||||||
|
/*
|
||||||
|
PublishedFileId_t m_nPublishedFileId;
|
||||||
|
uint32 m_rtimeCreated; // time when the published file was created
|
||||||
|
uint32 m_rtimeUpdated; // time when the published file was last updated
|
||||||
|
uint32 m_rtimeAddedToUserList; // time when the user added the published file to their list (not always applicable)
|
||||||
|
ERemoteStoragePublishedFileVisibility m_eVisibility; // visibility
|
||||||
|
char m_rgchTags[k_cchTagListMax]; // comma separated list of all tags associated with this file
|
||||||
|
// file/url information
|
||||||
|
UGCHandle_t m_hFile; // The handle of the primary file
|
||||||
|
UGCHandle_t m_hPreviewFile; // The handle of the preview file
|
||||||
|
char m_pchFileName[k_cchFilenameMax]; // The cloud filename of the primary file
|
||||||
|
int32 m_nFileSize; // Size of the primary file
|
||||||
|
int32 m_nPreviewFileSize; // Size of the preview file
|
||||||
|
uint32 m_unNumChildren; // if m_eFileType == k_EWorkshopFileTypeCollection, then this number will be the number of children contained within the collection
|
||||||
|
*/
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class UAdvancedSteamWorkshopLibrary : public UBlueprintFunctionLibrary
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
|
||||||
|
//********* Steam Functions *************//
|
||||||
|
|
||||||
|
// Returns IDs for subscribed workshop items, TArray length dictates how many
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
static TArray<FBPSteamWorkshopID> GetSubscribedWorkshopItems(int32 & NumberOfItems);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
static void GetNumSubscribedWorkshopItems(int32 & NumberOfItems);
|
||||||
|
|
||||||
|
};
|
@ -0,0 +1,101 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Subsystems/GameInstanceSubsystem.h"
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
|
||||||
|
#include <steam/steam_api.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "SteamNotificationsSubsystem.generated.h"
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnSteamOverlayActivated, bool, bOverlayState);
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class ADVANCEDSTEAMSESSIONS_API USteamNotificationsSubsystem : public UGameInstanceSubsystem
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Event thrown when the steam overlay switches states
|
||||||
|
UPROPERTY(BlueprintAssignable, Category = "SteamEvents")
|
||||||
|
FOnSteamOverlayActivated OnSteamOverlayActivated_Bind;
|
||||||
|
|
||||||
|
USteamNotificationsSubsystem() : Super()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class cSteamEventsStore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
USteamNotificationsSubsystem* ParentSubsystem = nullptr;
|
||||||
|
void Initialize(USteamNotificationsSubsystem* MyParent)
|
||||||
|
{
|
||||||
|
ParentSubsystem = MyParent;
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
OnExternalUITriggeredCallback.Register(this, &USteamNotificationsSubsystem::cSteamEventsStore::OnExternalUITriggered);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnInitialize(USteamNotificationsSubsystem* MyParent)
|
||||||
|
{
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
OnExternalUITriggeredCallback.Unregister();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
cSteamEventsStore()
|
||||||
|
{}
|
||||||
|
//:
|
||||||
|
/*OnExternalUITriggeredCallback(this, &cSteamEventsStore::OnExternalUITriggered)
|
||||||
|
{
|
||||||
|
|
||||||
|
}*/
|
||||||
|
#else
|
||||||
|
//cSteamEventsStore()
|
||||||
|
//{
|
||||||
|
|
||||||
|
//}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//~cSteamEventsStore(){}
|
||||||
|
|
||||||
|
private:
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
//STEAM_CALLBACK(cSteamEventsStore, OnExternalUITriggered, GameOverlayActivated_t, OnExternalUITriggeredCallback);
|
||||||
|
STEAM_CALLBACK_MANUAL(cSteamEventsStore, OnExternalUITriggered, GameOverlayActivated_t, OnExternalUITriggeredCallback);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
cSteamEventsStore MyEvents;
|
||||||
|
|
||||||
|
/** Implement this for initialization of instances of the system */
|
||||||
|
virtual void Initialize(FSubsystemCollectionBase& Collection) override
|
||||||
|
{
|
||||||
|
MyEvents.Initialize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Implement this for deinitialization of instances of the system */
|
||||||
|
virtual void Deinitialize() override
|
||||||
|
{
|
||||||
|
MyEvents.UnInitialize(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
void USteamNotificationsSubsystem::cSteamEventsStore::OnExternalUITriggered(GameOverlayActivated_t* CallbackData)
|
||||||
|
{
|
||||||
|
if (ParentSubsystem)
|
||||||
|
{
|
||||||
|
ParentSubsystem->OnSteamOverlayActivated_Bind.Broadcast((bool)CallbackData->m_bActive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -0,0 +1,100 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
|
||||||
|
// This is taken directly from UE4 - OnlineSubsystemSteamPrivatePCH.h as a fix for the array_count macro
|
||||||
|
|
||||||
|
// @todo Steam: Steam headers trigger secure-C-runtime warnings in Visual C++. Rather than mess with _CRT_SECURE_NO_WARNINGS, we'll just
|
||||||
|
// disable the warnings locally. Remove when this is fixed in the SDK
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
// #TODO check back on this at some point
|
||||||
|
#pragma warning(disable:4265) // SteamAPI CCallback< specifically, this warning is off by default but 4.17 turned it on....
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
|
||||||
|
//#include "OnlineSubsystemSteam.h"
|
||||||
|
|
||||||
|
#pragma push_macro("ARRAY_COUNT")
|
||||||
|
#undef ARRAY_COUNT
|
||||||
|
|
||||||
|
#if USING_CODE_ANALYSIS
|
||||||
|
MSVC_PRAGMA(warning(push))
|
||||||
|
MSVC_PRAGMA(warning(disable : ALL_CODE_ANALYSIS_WARNINGS))
|
||||||
|
#endif // USING_CODE_ANALYSIS
|
||||||
|
|
||||||
|
#include <steam/steam_api.h>
|
||||||
|
|
||||||
|
#if USING_CODE_ANALYSIS
|
||||||
|
MSVC_PRAGMA(warning(pop))
|
||||||
|
#endif // USING_CODE_ANALYSIS
|
||||||
|
|
||||||
|
|
||||||
|
#pragma pop_macro("ARRAY_COUNT")
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// @todo Steam: See above
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "SteamRequestGroupOfficersCallbackProxy.generated.h"
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType, Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
struct FBPSteamGroupOfficer
|
||||||
|
{
|
||||||
|
GENERATED_USTRUCT_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
FBPUniqueNetId OfficerUniqueNetID; // Uint64 representation
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
bool bIsOwner = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintGroupOfficerDetailsDelegate, const TArray<FBPSteamGroupOfficer> &, OfficerList);
|
||||||
|
|
||||||
|
UCLASS(MinimalAPI)
|
||||||
|
class USteamRequestGroupOfficersCallbackProxy : public UOnlineBlueprintCallProxyBase
|
||||||
|
{
|
||||||
|
GENERATED_UCLASS_BODY()
|
||||||
|
|
||||||
|
virtual ~USteamRequestGroupOfficersCallbackProxy();
|
||||||
|
|
||||||
|
// Called when there is a successful results return
|
||||||
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FBlueprintGroupOfficerDetailsDelegate OnSuccess;
|
||||||
|
|
||||||
|
// Called when there is an unsuccessful results return
|
||||||
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FBlueprintGroupOfficerDetailsDelegate OnFailure;
|
||||||
|
|
||||||
|
// Returns a list of steam group officers
|
||||||
|
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|SteamAPI|SteamGroups")
|
||||||
|
static USteamRequestGroupOfficersCallbackProxy* GetSteamGroupOfficerList(UObject* WorldContextObject, FBPUniqueNetId GroupUniqueNetID);
|
||||||
|
|
||||||
|
// UOnlineBlueprintCallProxyBase interface
|
||||||
|
virtual void Activate() override;
|
||||||
|
// End of UOnlineBlueprintCallProxyBase interface
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
void OnRequestGroupOfficerDetails( ClanOfficerListResponse_t *pResult, bool bIOFailure);
|
||||||
|
CCallResult<USteamRequestGroupOfficersCallbackProxy, ClanOfficerListResponse_t> m_callResultGroupOfficerRequestDetails;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
FBPUniqueNetId GroupUniqueID;
|
||||||
|
UObject* WorldContextObject;
|
||||||
|
};
|
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "AdvancedSteamWorkshopLibrary.h"
|
||||||
|
#include "BlueprintDataDefinitions.h"
|
||||||
|
|
||||||
|
// This is taken directly from UE4 - OnlineSubsystemSteamPrivatePCH.h as a fix for the array_count macro
|
||||||
|
|
||||||
|
// @todo Steam: Steam headers trigger secure-C-runtime warnings in Visual C++. Rather than mess with _CRT_SECURE_NO_WARNINGS, we'll just
|
||||||
|
// disable the warnings locally. Remove when this is fixed in the SDK
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
// #TODO check back on this at some point
|
||||||
|
#pragma warning(disable:4265) // SteamAPI CCallback< specifically, this warning is off by default but 4.17 turned it on....
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
|
||||||
|
//#include "OnlineSubsystemSteam.h"
|
||||||
|
|
||||||
|
#pragma push_macro("ARRAY_COUNT")
|
||||||
|
#undef ARRAY_COUNT
|
||||||
|
|
||||||
|
#if USING_CODE_ANALYSIS
|
||||||
|
MSVC_PRAGMA(warning(push))
|
||||||
|
MSVC_PRAGMA(warning(disable : ALL_CODE_ANALYSIS_WARNINGS))
|
||||||
|
#endif // USING_CODE_ANALYSIS
|
||||||
|
|
||||||
|
#include <steam/steam_api.h>
|
||||||
|
|
||||||
|
#if USING_CODE_ANALYSIS
|
||||||
|
MSVC_PRAGMA(warning(pop))
|
||||||
|
#endif // USING_CODE_ANALYSIS
|
||||||
|
|
||||||
|
|
||||||
|
#pragma pop_macro("ARRAY_COUNT")
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// @todo Steam: See above
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "SteamWSRequestUGCDetailsCallbackProxy.generated.h"
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBlueprintWorkshopDetailsDelegate, const FBPSteamWorkshopItemDetails&, WorkShopDetails);
|
||||||
|
|
||||||
|
UCLASS(MinimalAPI)
|
||||||
|
class USteamWSRequestUGCDetailsCallbackProxy : public UOnlineBlueprintCallProxyBase
|
||||||
|
{
|
||||||
|
GENERATED_UCLASS_BODY()
|
||||||
|
|
||||||
|
// Called when there is a successful results return
|
||||||
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FBlueprintWorkshopDetailsDelegate OnSuccess;
|
||||||
|
|
||||||
|
// Called when there is an unsuccessful results return
|
||||||
|
UPROPERTY(BlueprintAssignable)
|
||||||
|
FBlueprintWorkshopDetailsDelegate OnFailure;
|
||||||
|
|
||||||
|
// Ends the current session
|
||||||
|
UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true", WorldContext="WorldContextObject"), Category = "Online|AdvancedSteamWorkshop")
|
||||||
|
static USteamWSRequestUGCDetailsCallbackProxy* GetWorkshopItemDetails(UObject* WorldContextObject, FBPSteamWorkshopID WorkShopID);
|
||||||
|
|
||||||
|
// UOnlineBlueprintCallProxyBase interface
|
||||||
|
virtual void Activate() override;
|
||||||
|
// End of UOnlineBlueprintCallProxyBase interface
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
// Internal callback when the operation completes, calls out to the public success/failure callbacks
|
||||||
|
|
||||||
|
void OnUGCRequestUGCDetails(SteamUGCQueryCompleted_t *pResult, bool bIOFailure);
|
||||||
|
CCallResult<USteamWSRequestUGCDetailsCallbackProxy, SteamUGCQueryCompleted_t> m_callResultUGCRequestDetails;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
FBPSteamWorkshopID WorkShopID;
|
||||||
|
UObject* WorldContextObject;
|
||||||
|
};
|
@ -0,0 +1,442 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
#include "AdvancedSteamFriendsLibrary.h"
|
||||||
|
#include "OnlineSubSystemHeader.h"
|
||||||
|
#include "Engine/Texture.h"
|
||||||
|
#include "Engine/Texture2D.h"
|
||||||
|
#include "TextureResource.h"
|
||||||
|
#include "PixelFormat.h"
|
||||||
|
|
||||||
|
//General Log
|
||||||
|
DEFINE_LOG_CATEGORY(AdvancedSteamFriendsLog);
|
||||||
|
|
||||||
|
|
||||||
|
// Clan functions, add in soon
|
||||||
|
/*int32 UAdvancedSteamFriendsLibrary::GetFriendSteamLevel(const FBPUniqueNetId UniqueNetId)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("IsAFriend Had a bad UniqueNetId!"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes());
|
||||||
|
|
||||||
|
|
||||||
|
// clan (group) iteration and access functions
|
||||||
|
//virtual int GetClanCount() = 0;
|
||||||
|
//virtual CSteamID GetClanByIndex(int iClan) = 0;
|
||||||
|
//virtual const char *GetClanName(CSteamID steamIDClan) = 0;
|
||||||
|
//virtual const char *GetClanTag(CSteamID steamIDClan) = 0;
|
||||||
|
// returns the most recent information we have about what's happening in a clan
|
||||||
|
//virtual bool GetClanActivityCounts(CSteamID steamIDClan, int *pnOnline, int *pnInGame, int *pnChatting) = 0;
|
||||||
|
// for clans a user is a member of, they will have reasonably up-to-date information, but for others you'll have to download the info to have the latest
|
||||||
|
//virtual SteamAPICall_t DownloadClanActivityCounts(ARRAY_COUNT(cClansToRequest) CSteamID *psteamIDClans, int cClansToRequest) = 0;
|
||||||
|
|
||||||
|
// requests information about a clan officer list
|
||||||
|
// when complete, data is returned in ClanOfficerListResponse_t call result
|
||||||
|
// this makes available the calls below
|
||||||
|
// you can only ask about clans that a user is a member of
|
||||||
|
// note that this won't download avatars automatically; if you get an officer,
|
||||||
|
// and no avatar image is available, call RequestUserInformation( steamID, false ) to download the avatar
|
||||||
|
//virtual SteamAPICall_t RequestClanOfficerList(CSteamID steamIDClan) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// returns the steamID of the clan owner
|
||||||
|
//virtual CSteamID GetClanOwner(CSteamID steamIDClan) = 0;
|
||||||
|
// returns the number of officers in a clan (including the owner)
|
||||||
|
//virtual int GetClanOfficerCount(CSteamID steamIDClan) = 0;
|
||||||
|
// returns the steamID of a clan officer, by index, of range [0,GetClanOfficerCount)
|
||||||
|
//virtual CSteamID GetClanOfficerByIndex(CSteamID steamIDClan, int iOfficer) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
return SteamFriends()->GetFriendSteamLevel(id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void UAdvancedSteamFriendsLibrary::GetSteamGroups(TArray<FBPSteamGroupInfo> & SteamGroups)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
int numClans = SteamFriends()->GetClanCount();
|
||||||
|
|
||||||
|
for (int i = 0; i < numClans; i++)
|
||||||
|
{
|
||||||
|
CSteamID SteamGroupID = SteamFriends()->GetClanByIndex(i);
|
||||||
|
|
||||||
|
if(!SteamGroupID.IsValid())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FBPSteamGroupInfo GroupInfo;
|
||||||
|
|
||||||
|
TSharedPtr<const FUniqueNetId> ValueID(new const FUniqueNetIdSteam2(SteamGroupID));
|
||||||
|
GroupInfo.GroupID.SetUniqueNetId(ValueID);
|
||||||
|
SteamFriends()->GetClanActivityCounts(SteamGroupID, &GroupInfo.numOnline, &GroupInfo.numInGame, &GroupInfo.numChatting);
|
||||||
|
GroupInfo.GroupName = FString(UTF8_TO_TCHAR(SteamFriends()->GetClanName(SteamGroupID)));
|
||||||
|
GroupInfo.GroupTag = FString(UTF8_TO_TCHAR(SteamFriends()->GetClanTag(SteamGroupID)));
|
||||||
|
|
||||||
|
SteamGroups.Add(GroupInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAdvancedSteamFriendsLibrary::GetSteamFriendGamePlayed(const FBPUniqueNetId UniqueNetId, EBlueprintResultSwitch &Result/*, FString & GameName*/, int32 & AppID)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("GetSteamFriendGamePlayed Had a bad UniqueNetId!"));
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes());
|
||||||
|
|
||||||
|
FriendGameInfo_t GameInfo;
|
||||||
|
bool bIsInGame = SteamFriends()->GetFriendGamePlayed(id, &GameInfo);
|
||||||
|
|
||||||
|
if (bIsInGame && GameInfo.m_gameID.IsValid())
|
||||||
|
{
|
||||||
|
AppID = GameInfo.m_gameID.AppID();
|
||||||
|
|
||||||
|
// Forgot this test and left it in, it is incorrect, you would need restricted access
|
||||||
|
// And it would only find games in the local library anyway
|
||||||
|
/*char NameBuffer[512];
|
||||||
|
int Len = SteamAppList()->GetAppName(GameInfo.m_gameID.AppID(), NameBuffer, 512);
|
||||||
|
|
||||||
|
if (Len != -1) // Invalid
|
||||||
|
{
|
||||||
|
GameName = FString(UTF8_TO_TCHAR(NameBuffer));
|
||||||
|
}*/
|
||||||
|
|
||||||
|
Result = EBlueprintResultSwitch::OnSuccess;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Result = EBlueprintResultSwitch::OnFailure;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 UAdvancedSteamFriendsLibrary::GetFriendSteamLevel(const FBPUniqueNetId UniqueNetId)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("IsAFriend Had a bad UniqueNetId!"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes());
|
||||||
|
|
||||||
|
return SteamFriends()->GetFriendSteamLevel(id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FString UAdvancedSteamFriendsLibrary::GetSteamPersonaName(const FBPUniqueNetId UniqueNetId)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("GetSteamPersonaName Had a bad UniqueNetId!"));
|
||||||
|
return FString(TEXT(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes());
|
||||||
|
const char* PersonaName = SteamFriends()->GetFriendPersonaName(id);
|
||||||
|
return FString(UTF8_TO_TCHAR(PersonaName));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return FString(TEXT(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
FBPUniqueNetId UAdvancedSteamFriendsLibrary::CreateSteamIDFromString(const FString SteamID64)
|
||||||
|
{
|
||||||
|
FBPUniqueNetId netId;
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (!(SteamID64.Len() > 0))
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("CreateSteamIDFromString Had a bad UniqueNetId!"));
|
||||||
|
return netId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
// Already does the conversion
|
||||||
|
TSharedPtr<const FUniqueNetId> ValueID(new const FUniqueNetIdSteam2(SteamID64));
|
||||||
|
//FCString::Atoi64(*SteamID64));
|
||||||
|
|
||||||
|
netId.SetUniqueNetId(ValueID);
|
||||||
|
return netId;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return netId;
|
||||||
|
}
|
||||||
|
|
||||||
|
FBPUniqueNetId UAdvancedSteamFriendsLibrary::GetLocalSteamIDFromSteam()
|
||||||
|
{
|
||||||
|
FBPUniqueNetId netId;
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
TSharedPtr<const FUniqueNetId> SteamID(new const FUniqueNetIdSteam2(SteamUser()->GetSteamID()));
|
||||||
|
netId.SetUniqueNetId(SteamID);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return netId;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedSteamFriendsLibrary::RequestSteamFriendInfo(const FBPUniqueNetId UniqueNetId, bool bRequireNameOnly)
|
||||||
|
{
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("RequestSteamFriendInfo Had a bad UniqueNetId!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes());
|
||||||
|
|
||||||
|
return !SteamFriends()->RequestUserInformation(id, bRequireNameOnly);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("RequestSteamFriendInfo Couldn't init steamAPI!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool UAdvancedSteamFriendsLibrary::OpenSteamUserOverlay(const FBPUniqueNetId UniqueNetId, ESteamUserOverlayType DialogType)
|
||||||
|
{
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("OpenSteamUserOverlay Had a bad UniqueNetId!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes());
|
||||||
|
if (DialogType == ESteamUserOverlayType::invitetolobby)
|
||||||
|
{
|
||||||
|
SteamFriends()->ActivateGameOverlayInviteDialog(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FString DialogName = EnumToString("ESteamUserOverlayType", (uint8)DialogType);
|
||||||
|
SteamFriends()->ActivateGameOverlayToUser(TCHAR_TO_ANSI(*DialogName), id);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("OpenSteamUserOverlay Couldn't init steamAPI!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedSteamFriendsLibrary::IsOverlayEnabled()
|
||||||
|
{
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
return SteamUtils()->IsOverlayEnabled();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("OpenSteamUserOverlay Couldn't init steamAPI!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UTexture2D * UAdvancedSteamFriendsLibrary::GetSteamFriendAvatar(const FBPUniqueNetId UniqueNetId, EBlueprintAsyncResultSwitch &Result, SteamAvatarSize AvatarSize)
|
||||||
|
{
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (!UniqueNetId.IsValid() || !UniqueNetId.UniqueNetId->IsValid() || UniqueNetId.UniqueNetId->GetType() != STEAM_SUBSYSTEM)
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("GetSteamFriendAvatar Had a bad UniqueNetId!"));
|
||||||
|
Result = EBlueprintAsyncResultSwitch::OnFailure;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Width = 0;
|
||||||
|
uint32 Height = 0;
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
//Getting the PictureID from the SteamAPI and getting the Size with the ID
|
||||||
|
//virtual bool RequestUserInformation( CSteamID steamIDUser, bool bRequireNameOnly ) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
uint64 id = *((uint64*)UniqueNetId.UniqueNetId->GetBytes());
|
||||||
|
int Picture = 0;
|
||||||
|
|
||||||
|
switch(AvatarSize)
|
||||||
|
{
|
||||||
|
case SteamAvatarSize::SteamAvatar_Small: Picture = SteamFriends()->GetSmallFriendAvatar(id); break;
|
||||||
|
case SteamAvatarSize::SteamAvatar_Medium: Picture = SteamFriends()->GetMediumFriendAvatar(id); break;
|
||||||
|
case SteamAvatarSize::SteamAvatar_Large: Picture = SteamFriends()->GetLargeFriendAvatar(id); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Picture == -1)
|
||||||
|
{
|
||||||
|
Result = EBlueprintAsyncResultSwitch::AsyncLoading;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SteamUtils()->GetImageSize(Picture, &Width, &Height);
|
||||||
|
|
||||||
|
// STOLEN FROM ANSWERHUB :p, then fixed because answerhub wasn't releasing the memory O.o
|
||||||
|
// Also fixed image pixel format and switched to a memcpy instead of manual iteration.
|
||||||
|
// At some point I should probably reply to that answerhub post with these fixes to prevent people killing their games.....
|
||||||
|
|
||||||
|
if (Width > 0 && Height > 0)
|
||||||
|
{
|
||||||
|
//Creating the buffer "oAvatarRGBA" and then filling it with the RGBA Stream from the Steam Avatar
|
||||||
|
uint8 *oAvatarRGBA = new uint8[Width * Height * 4];
|
||||||
|
|
||||||
|
|
||||||
|
//Filling the buffer with the RGBA Stream from the Steam Avatar and creating a UTextur2D to parse the RGBA Steam in
|
||||||
|
SteamUtils()->GetImageRGBA(Picture, (uint8*)oAvatarRGBA, 4 * Height * Width * sizeof(char));
|
||||||
|
|
||||||
|
|
||||||
|
// Removed as I changed the image bit code to be RGB, I think the original author was unaware that there were different pixel formats
|
||||||
|
/*
|
||||||
|
//Swap R and B channels because for some reason the games whack
|
||||||
|
for (uint32 i = 0; i < (Width * Height * 4); i += 4)
|
||||||
|
{
|
||||||
|
uint8 Temp = oAvatarRGBA[i + 0];
|
||||||
|
oAvatarRGBA[i + 0] = oAvatarRGBA[i + 2];
|
||||||
|
oAvatarRGBA[i + 2] = Temp;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
UTexture2D* Avatar = UTexture2D::CreateTransient(Width, Height, PF_R8G8B8A8);
|
||||||
|
// Switched to a Memcpy instead of byte by byte transer
|
||||||
|
|
||||||
|
if (FTexturePlatformData* PlatformData = Avatar->GetPlatformData())
|
||||||
|
{
|
||||||
|
uint8* MipData = (uint8*)PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
|
||||||
|
FMemory::Memcpy(MipData, (void*)oAvatarRGBA, Height * Width * 4);
|
||||||
|
PlatformData->Mips[0].BulkData.Unlock();
|
||||||
|
|
||||||
|
//Setting some Parameters for the Texture and finally returning it
|
||||||
|
PlatformData->SetNumSlices(1);
|
||||||
|
Avatar->NeverStream = true;
|
||||||
|
//Avatar->CompressionSettings = TC_EditorIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free RGBA buffer regardless of whether it was used or not
|
||||||
|
delete[] oAvatarRGBA;
|
||||||
|
|
||||||
|
Avatar->UpdateResource();
|
||||||
|
|
||||||
|
Result = EBlueprintAsyncResultSwitch::OnSuccess;
|
||||||
|
return Avatar;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("Bad Height / Width with steam avatar!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = EBlueprintAsyncResultSwitch::OnFailure;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UE_LOG(AdvancedSteamFriendsLog, Warning, TEXT("STEAM Couldn't be verified as initialized"));
|
||||||
|
Result = EBlueprintAsyncResultSwitch::OnFailure;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedSteamFriendsLibrary::InitTextFiltering()
|
||||||
|
{
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
return SteamUtils()->InitFilterText();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedSteamFriendsLibrary::FilterText(FString TextToFilter, EBPTextFilteringContext Context, const FBPUniqueNetId TextSourceID, FString& FilteredText)
|
||||||
|
{
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
uint32 BufferLen = TextToFilter.Len() + 10; // Docs say 1 byte excess min, going with 10
|
||||||
|
char* OutText = new char[BufferLen];
|
||||||
|
|
||||||
|
uint64 id = 0;
|
||||||
|
|
||||||
|
if (TextSourceID.IsValid())
|
||||||
|
{
|
||||||
|
id = *((uint64*)TextSourceID.UniqueNetId->GetBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
int FilterCount = SteamUtils()->FilterText((ETextFilteringContext)Context, id, TCHAR_TO_ANSI(*TextToFilter), OutText, BufferLen);
|
||||||
|
|
||||||
|
if (FilterCount > 0)
|
||||||
|
{
|
||||||
|
FilteredText = FString(UTF8_TO_TCHAR(OutText));
|
||||||
|
delete[] OutText;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] OutText;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FilteredText = TextToFilter;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAdvancedSteamFriendsLibrary::IsSteamInBigPictureMode()
|
||||||
|
{
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
return SteamUtils()->IsSteamInBigPictureMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
//#include "StandAlonePrivatePCH.h"
|
||||||
|
#include "AdvancedSteamSessions.h"
|
||||||
|
|
||||||
|
void AdvancedSteamSessions::StartupModule()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AdvancedSteamSessions::ShutdownModule()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPLEMENT_MODULE(AdvancedSteamSessions, AdvancedSteamSessions)
|
@ -0,0 +1,69 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
#include "AdvancedSteamWorkshopLibrary.h"
|
||||||
|
#include "OnlineSubSystemHeader.h"
|
||||||
|
//General Log
|
||||||
|
DEFINE_LOG_CATEGORY(AdvancedSteamWorkshopLog);
|
||||||
|
|
||||||
|
|
||||||
|
void UAdvancedSteamWorkshopLibrary::GetNumSubscribedWorkshopItems(int32 & NumberOfItems)
|
||||||
|
{
|
||||||
|
NumberOfItems = 0;
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
NumberOfItems = SteamUGC()->GetNumSubscribedItems();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSteamWorkshopLog, Warning, TEXT("Error in GetNumSubscribedWorkshopItemCount : SteamAPI is not Inited!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
UE_LOG(AdvancedSteamWorkshopLog, Warning, TEXT("Error in GetNumSubscribedWorkshopItemCount : Called on an incompatible platform"));
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
TArray<FBPSteamWorkshopID> UAdvancedSteamWorkshopLibrary::GetSubscribedWorkshopItems(int32 & NumberOfItems)
|
||||||
|
{
|
||||||
|
TArray<FBPSteamWorkshopID> outArray;
|
||||||
|
NumberOfItems = 0;
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
uint32 NumItems = SteamUGC()->GetNumSubscribedItems();
|
||||||
|
|
||||||
|
if (NumItems == 0)
|
||||||
|
return outArray;
|
||||||
|
|
||||||
|
// Not using the actual variable above in case someone somehow goes past int32 limits
|
||||||
|
// Don't want to go negative on the iteration.
|
||||||
|
NumberOfItems = NumItems;
|
||||||
|
|
||||||
|
PublishedFileId_t *fileIds = new PublishedFileId_t[NumItems];
|
||||||
|
|
||||||
|
uint32 subItems = SteamUGC()->GetSubscribedItems(fileIds, NumItems);
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < subItems; ++i)
|
||||||
|
{
|
||||||
|
outArray.Add(FBPSteamWorkshopID(fileIds[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] fileIds;
|
||||||
|
|
||||||
|
return outArray;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(AdvancedSteamWorkshopLog, Warning, TEXT("Error in GetSubscribedWorkshopItemCount : SteamAPI is not Inited!"));
|
||||||
|
return outArray;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
UE_LOG(AdvancedSteamWorkshopLog, Warning, TEXT("Error in GetSubscribedWorkshopItemCount : Called on an incompatible platform"));
|
||||||
|
return outArray;
|
||||||
|
#endif
|
||||||
|
}
|
@ -0,0 +1,121 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "SteamRequestGroupOfficersCallbackProxy.h"
|
||||||
|
#include "Online/CoreOnline.h"
|
||||||
|
#include "AdvancedSteamFriendsLibrary.h"
|
||||||
|
#include "OnlineSubSystemHeader.h"
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
#include "steam/isteamfriends.h"
|
||||||
|
#endif
|
||||||
|
//#include "OnlineSubsystemSteamTypes.h"
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// UEndSessionCallbackProxy
|
||||||
|
|
||||||
|
USteamRequestGroupOfficersCallbackProxy::USteamRequestGroupOfficersCallbackProxy(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
USteamRequestGroupOfficersCallbackProxy::~USteamRequestGroupOfficersCallbackProxy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
USteamRequestGroupOfficersCallbackProxy* USteamRequestGroupOfficersCallbackProxy::GetSteamGroupOfficerList(UObject* WorldContextObject, FBPUniqueNetId GroupUniqueNetID)
|
||||||
|
{
|
||||||
|
USteamRequestGroupOfficersCallbackProxy* Proxy = NewObject<USteamRequestGroupOfficersCallbackProxy>();
|
||||||
|
|
||||||
|
Proxy->GroupUniqueID = GroupUniqueNetID;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USteamRequestGroupOfficersCallbackProxy::Activate()
|
||||||
|
{
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
uint64 id = *((uint64*)GroupUniqueID.UniqueNetId->GetBytes());
|
||||||
|
SteamAPICall_t hSteamAPICall = SteamFriends()->RequestClanOfficerList(id);
|
||||||
|
|
||||||
|
m_callResultGroupOfficerRequestDetails.Set(hSteamAPICall, this, &USteamRequestGroupOfficersCallbackProxy::OnRequestGroupOfficerDetails);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
TArray<FBPSteamGroupOfficer> EmptyArray;
|
||||||
|
OnFailure.Broadcast(EmptyArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
void USteamRequestGroupOfficersCallbackProxy::OnRequestGroupOfficerDetails(ClanOfficerListResponse_t *pResult, bool bIOFailure)
|
||||||
|
{
|
||||||
|
TArray<FBPSteamGroupOfficer> OfficerArray;
|
||||||
|
|
||||||
|
//FOnlineSubsystemSteam* SteamSubsystem = (FOnlineSubsystemSteam*)(IOnlineSubsystem::Get(STEAM_SUBSYSTEM));
|
||||||
|
|
||||||
|
if (bIOFailure || !pResult || !pResult->m_bSuccess)
|
||||||
|
{
|
||||||
|
//if (SteamSubsystem != nullptr)
|
||||||
|
{
|
||||||
|
// SteamSubsystem->ExecuteNextTick([this]()
|
||||||
|
//{
|
||||||
|
TArray<FBPSteamGroupOfficer> FailureArray;
|
||||||
|
OnFailure.Broadcast(FailureArray);
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
//OnFailure.Broadcast(OfficerArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
uint64 id = *((uint64*)GroupUniqueID.UniqueNetId->GetBytes());
|
||||||
|
|
||||||
|
FBPSteamGroupOfficer Officer;
|
||||||
|
CSteamID ClanOwner = SteamFriends()->GetClanOwner(id);
|
||||||
|
|
||||||
|
Officer.bIsOwner = true;
|
||||||
|
|
||||||
|
TSharedPtr<const FUniqueNetId> ValueID(new const FUniqueNetIdSteam2(ClanOwner));
|
||||||
|
Officer.OfficerUniqueNetID.SetUniqueNetId(ValueID);
|
||||||
|
OfficerArray.Add(Officer);
|
||||||
|
|
||||||
|
for (int i = 0; i < pResult->m_cOfficers; i++)
|
||||||
|
{
|
||||||
|
CSteamID OfficerSteamID = SteamFriends()->GetClanOfficerByIndex(id, i);
|
||||||
|
|
||||||
|
Officer.bIsOwner = false;
|
||||||
|
|
||||||
|
TSharedPtr<const FUniqueNetId> newValueID(new const FUniqueNetIdSteam2(OfficerSteamID));
|
||||||
|
Officer.OfficerUniqueNetID.SetUniqueNetId(newValueID);
|
||||||
|
|
||||||
|
OfficerArray.Add(Officer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (SteamSubsystem != nullptr)
|
||||||
|
//{
|
||||||
|
//SteamSubsystem->ExecuteNextTick([OfficerArray, this]()
|
||||||
|
//{
|
||||||
|
OnSuccess.Broadcast(OfficerArray);
|
||||||
|
//});
|
||||||
|
//}
|
||||||
|
|
||||||
|
//OnSuccess.Broadcast(OfficerArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//if (SteamSubsystem != nullptr)
|
||||||
|
{
|
||||||
|
//SteamSubsystem->ExecuteNextTick([this]()
|
||||||
|
//{
|
||||||
|
TArray<FBPSteamGroupOfficer> FailureArray;
|
||||||
|
OnFailure.Broadcast(FailureArray);
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should never hit this anyway
|
||||||
|
//OnFailure.Broadcast(OfficerArray);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,101 @@
|
|||||||
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "SteamWSRequestUGCDetailsCallbackProxy.h"
|
||||||
|
#include "OnlineSubSystemHeader.h"
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
#include "steam/isteamugc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// UEndSessionCallbackProxy
|
||||||
|
|
||||||
|
USteamWSRequestUGCDetailsCallbackProxy::USteamWSRequestUGCDetailsCallbackProxy(const FObjectInitializer& ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
USteamWSRequestUGCDetailsCallbackProxy* USteamWSRequestUGCDetailsCallbackProxy::GetWorkshopItemDetails(UObject* WorldContextObject, FBPSteamWorkshopID WorkShopID/*, int32 NumSecondsBeforeTimeout*/)
|
||||||
|
{
|
||||||
|
USteamWSRequestUGCDetailsCallbackProxy* Proxy = NewObject<USteamWSRequestUGCDetailsCallbackProxy>();
|
||||||
|
|
||||||
|
Proxy->WorkShopID = WorkShopID;
|
||||||
|
return Proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USteamWSRequestUGCDetailsCallbackProxy::Activate()
|
||||||
|
{
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
// #TODO: Support arrays instead in the future?
|
||||||
|
UGCQueryHandle_t hQueryHandle = SteamUGC()->CreateQueryUGCDetailsRequest((PublishedFileId_t *)&WorkShopID.SteamWorkshopID, 1);
|
||||||
|
// #TODO: add search settings here by calling into the handle?
|
||||||
|
SteamAPICall_t hSteamAPICall = SteamUGC()->SendQueryUGCRequest(hQueryHandle);
|
||||||
|
|
||||||
|
// Need to release the query
|
||||||
|
SteamUGC()->ReleaseQueryUGCRequest(hQueryHandle);
|
||||||
|
|
||||||
|
if (hSteamAPICall == k_uAPICallInvalid)
|
||||||
|
{
|
||||||
|
OnFailure.Broadcast(FBPSteamWorkshopItemDetails());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_callResultUGCRequestDetails.Set(hSteamAPICall, this, &USteamWSRequestUGCDetailsCallbackProxy::OnUGCRequestUGCDetails);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
OnFailure.Broadcast(FBPSteamWorkshopItemDetails());
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (PLATFORM_WINDOWS || PLATFORM_MAC || PLATFORM_LINUX) && STEAM_SDK_INSTALLED
|
||||||
|
void USteamWSRequestUGCDetailsCallbackProxy::OnUGCRequestUGCDetails(SteamUGCQueryCompleted_t *pResult, bool bIOFailure)
|
||||||
|
{
|
||||||
|
//FOnlineSubsystemSteam* SteamSubsystem = (FOnlineSubsystemSteam*)(IOnlineSubsystem::Get(STEAM_SUBSYSTEM));
|
||||||
|
|
||||||
|
if (bIOFailure || !pResult || pResult->m_unNumResultsReturned <= 0)
|
||||||
|
{
|
||||||
|
//if (SteamSubsystem != nullptr)
|
||||||
|
{
|
||||||
|
// SteamSubsystem->ExecuteNextTick([this]()
|
||||||
|
//{
|
||||||
|
OnFailure.Broadcast(FBPSteamWorkshopItemDetails());
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
//OnFailure.Broadcast(FBPSteamWorkshopItemDetails());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (SteamAPI_Init())
|
||||||
|
{
|
||||||
|
SteamUGCDetails_t Details;
|
||||||
|
if (SteamUGC()->GetQueryUGCResult(pResult->m_handle, 0, &Details))
|
||||||
|
{
|
||||||
|
//if (SteamSubsystem != nullptr)
|
||||||
|
{
|
||||||
|
//SteamSubsystem->ExecuteNextTick([Details, this]()
|
||||||
|
//{
|
||||||
|
OnSuccess.Broadcast(FBPSteamWorkshopItemDetails(Details));
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
|
||||||
|
//OnSuccess.Broadcast(FBPSteamWorkshopItemDetails(Details));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//if (SteamSubsystem != nullptr)
|
||||||
|
{
|
||||||
|
//SteamSubsystem->ExecuteNextTick([this]()
|
||||||
|
//{
|
||||||
|
OnFailure.Broadcast(FBPSteamWorkshopItemDetails());
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not needed, should never hit here
|
||||||
|
//OnFailure.Broadcast(FBPSteamWorkshopItemDetails());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user