Skip to content

Commit 8cbf84c

Browse files
Byte Wars Build Pipelinedamarindraab
authored andcommitted
Merged in tutorialmodules-release-2.19.2 (pull request #477)
Update tutorialmodules to 2.19.2 * Update tutorialmodules to 2.19.2 * chore: version Approved-by: Nauval Muhammad Firdaus Approved-by: Damar Inderajati
1 parent 39d3e15 commit 8cbf84c

File tree

15 files changed

+349
-15
lines changed

15 files changed

+349
-15
lines changed

Config/Custom/EOS/DefaultEngine.ini

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ bEnabled=true
77
[/Script/OnlineSubsystemEOS.EOSSettings]
88
DefaultArtifactName=
99
+Artifacts=(ArtifactName="",ProductId="",SandboxId="",DeploymentId="",ClientId="",ClientSecret="",EncryptionKey="1111111111111111111111111111111111111111111111111111111")
10-
bUseEAS=True
10+
bUseEAS=True
11+
bEnableOverlay=True

Config/DefaultGame.ini

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[/Script/EngineSettings.GeneralProjectSettings]
2-
GitHash=fb254a2
2+
GitHash=4456143
33
ProjectID=8DAB8AD246B954A7292553AF4B4F50E5
4-
ProjectVersion=2.19.1
5-
BuildNumber=304
4+
ProjectVersion=2.19.2
5+
BuildNumber=312
66

77
[/Script/CommonInput.CommonInputSettings]
88
InputData=/Game/ByteWars/UI/Input/B_AccelByteWarsCommonInputData.B_AccelByteWarsCommonInputData_C

Plugins/AccelByte/AccelByteUe4Sdk

Submodule AccelByteUe4Sdk updated 147 files

Source/AccelByteWars/TutorialModules/Monetization/NativePlatformPurchase/NativePlatformPurchaseModels.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ class ACCELBYTEWARS_API FNativePlatformPurchaseUtils
4242
static inline FString RegionalCurrencyCode;
4343
};
4444

45+
UCLASS(Config = Engine, DefaultConfig) // reads/writes from DefaultEngine.ini
46+
class ACCELBYTEWARS_API UEpicGamesStoreItemConfig : public UObject
47+
{
48+
GENERATED_BODY()
49+
50+
public:
51+
// AGS required Audience Item ID, while Game Client can only fetch the OfferId.
52+
// Key = AudienceId, Value = OfferId
53+
UPROPERTY(Config, EditAnywhere, Category = "Offers")
54+
TMap<FString, FString> AudienceOffers;
55+
};
56+
4557
static inline TArray<TSharedRef<FAccelByteModelsItemMapping>> GooglePlayItemMapping =
4658
{
4759
MakeShared<FAccelByteModelsItemMapping>(FAccelByteModelsItemMapping{

Source/AccelByteWars/TutorialModules/Monetization/NativePlatformPurchase/NativePlatformPurchaseSubsystem.cpp

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
#include "NativePlatformPurchaseSubsystem.h"
66

77
#include "Algo/Transform.h"
8+
#include "Interfaces/OnlineStoreInterfaceV2.h"
9+
#include "Interfaces/OnlineIdentityInterface.h"
810
#include "OnlineStoreInterfaceV2AccelByte.h"
911
#include "OnlineEntitlementsInterfaceAccelByte.h"
1012
#include "OnlinePurchaseInterfaceAccelByte.h"
13+
#include "OnlineIdentityInterfaceAccelByte.h"
1114
#include "Monetization/InGameStoreEssentials/UI/ShopWidget.h"
1215
#include "Monetization/InGameStoreEssentials/InGameStoreEssentialsModel.h"
1316

@@ -19,6 +22,12 @@ void UNativePlatformPurchaseSubsystem::Initialize(FSubsystemCollectionBase& Coll
1922

2023
const IOnlineSubsystem* Subsystem = Online::GetSubsystem(GetWorld());
2124
ensure(Subsystem);
25+
26+
const IOnlineIdentityPtr IdentityPtr = Subsystem->GetIdentityInterface();
27+
ensure(IdentityPtr);
28+
IdentityInterface = StaticCastSharedPtr<FOnlineIdentityAccelByte>(IdentityPtr);
29+
ensure(IdentityInterface);
30+
2231
const IOnlineStoreV2Ptr StorePtr = Subsystem->GetStoreV2Interface();
2332
ensure(StorePtr);
2433
StoreInterface = StaticCastSharedPtr<FOnlineStoreV2AccelByte>(StorePtr);
@@ -149,6 +158,9 @@ void UNativePlatformPurchaseSubsystem::CheckoutItem(const APlayerController* Own
149158
* This is necessary because the AccelByte OSS does not natively support this setup.*/
150159
CheckoutItemWithGooglePlay(OwningPlayer, CheckoutRequest, StoreItemData->GetIsConsumable());
151160
return;
161+
#elif PLATFORM_EOS
162+
CheckoutItemWithEpic(OwningPlayer, CheckoutRequest);
163+
return;
152164
#endif
153165

154166
const FAccelByteModelsEntitlementSyncBase EntitlementSyncBase = { *NativeProductId };
@@ -212,6 +224,15 @@ void UNativePlatformPurchaseSubsystem::OnQueryItemMappingComplete(
212224

213225
#if PLATFORM_STEAM
214226
OnQueryItemMappingCompleted.ExecuteIfBound(GetSteamItemPricing(ItemMappings));
227+
#elif PLATFORM_EOS
228+
if (!GetItemPrices().IsEmpty())
229+
{
230+
OnQueryItemMappingCompleted.ExecuteIfBound(GetItemPrices());
231+
}
232+
else
233+
{
234+
QueryEpicItems(UserId, ItemMappings);
235+
}
215236
#elif PLATFORM_ANDROID
216237
// Query native item information from Google Play Games Services (GPGS) if not yet.
217238
if (!GetItemPrices().IsEmpty())
@@ -436,6 +457,179 @@ void UNativePlatformPurchaseSubsystem::HandleSteamPurchaseOverlay(GameOverlayAct
436457
#endif
437458
#pragma endregion
438459

460+
#pragma region "Epic Games Store"
461+
#if PLATFORM_EOS
462+
void UNativePlatformPurchaseSubsystem::QueryEpicItems(const FUniqueNetIdPtr UserId, const TArray<TSharedRef<FAccelByteModelsItemMapping>>& ItemMappings)
463+
{
464+
const IOnlineSubsystem* PlatformSubsystem = IOnlineSubsystem::GetByPlatform();
465+
if (!PlatformSubsystem)
466+
{
467+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("Failed to query native pricing. The native platform subsystem is invalid."));
468+
return;
469+
}
470+
471+
IOnlineStoreV2Ptr PlatformStore = PlatformSubsystem->GetStoreV2Interface();
472+
if (!PlatformStore)
473+
{
474+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("Failed to query native pricing. The native store v2 interface is invalid."));
475+
return;
476+
}
477+
478+
IOnlineIdentityPtr PlatformIdentity = PlatformSubsystem->GetIdentityInterface();
479+
if (!PlatformIdentity)
480+
{
481+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("Failed to query native pricing. The native identity interface is invalid."));
482+
return;
483+
}
484+
485+
TArray<FString> OfferIds;
486+
const UEpicGamesStoreItemConfig* ItemConfigs = GetDefault<UEpicGamesStoreItemConfig>();
487+
if (!ItemConfigs)
488+
{
489+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("Failed to query native pricing. Unable to load UEpicGamesStoreItemConfig."));
490+
return;
491+
}
492+
493+
for (const TSharedRef<FAccelByteModelsItemMapping>& OfferId : ItemMappings)
494+
{
495+
if (OfferId->Platform == EAccelBytePlatformMapping::EPIC_GAMES)
496+
{
497+
OfferIds.Add(ItemConfigs->AudienceOffers[OfferId->PlatformProductId]);
498+
}
499+
}
500+
501+
FPlatformUserId PlatformUserId = IdentityInterface->GetPlatformUserIdFromUniqueNetId(UserId.ToSharedRef().Get());
502+
ensure(PlatformUserId.IsValid());
503+
const int32 LocalUserNum = IdentityInterface->GetLocalUserNumFromPlatformUserId(PlatformUserId);
504+
505+
FUniqueNetIdPtr PlatformUniqueId = PlatformIdentity->GetUniquePlayerId(LocalUserNum);
506+
ensure(PlatformUniqueId.IsValid());
507+
508+
PlatformStore->QueryOffersById(*PlatformUniqueId, OfferIds, FOnQueryOnlineStoreOffersComplete::CreateUObject(this, &ThisClass::OnEpicQueryOfferCompleted));
509+
}
510+
511+
void UNativePlatformPurchaseSubsystem::OnEpicQueryOfferCompleted(bool bWasSuccessful, const TArray<FUniqueOfferId>& OfferIds, const FString& Error)
512+
{
513+
if (!bWasSuccessful)
514+
{
515+
OnQueryItemMappingCompleted.ExecuteIfBound({});
516+
return;
517+
}
518+
519+
const IOnlineSubsystem* PlatformSubsystem = IOnlineSubsystem::GetByPlatform();
520+
if (!PlatformSubsystem)
521+
{
522+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("Failed to query native pricing. The native platform subsystem is invalid."));
523+
return;
524+
}
525+
526+
IOnlineStoreV2Ptr PlatformStore = PlatformSubsystem->GetStoreV2Interface();
527+
if (!PlatformStore)
528+
{
529+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("Failed to query native pricing. The native store v2 interface is invalid."));
530+
return;
531+
}
532+
533+
const UEpicGamesStoreItemConfig* ItemConfigs = GetDefault<UEpicGamesStoreItemConfig>();
534+
if (!ItemConfigs)
535+
{
536+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("Failed to query native pricing. Unable to load UEpicGamesStoreItemConfig."));
537+
return;
538+
}
539+
540+
TArray<FOnlineStoreOfferRef> Offers;
541+
PlatformStore->GetOffers(Offers);
542+
543+
TMap<FString, FString> AbItemMapping;
544+
for (const TSharedRef<FAccelByteModelsItemMapping>& OfferId : GetItemMapping())
545+
{
546+
if (OfferId->Platform == EAccelBytePlatformMapping::EPIC_GAMES)
547+
{
548+
if (const FString* EpicOfferId = ItemConfigs->AudienceOffers.Find(OfferId->PlatformProductId))
549+
{
550+
AbItemMapping.Add(**EpicOfferId, OfferId->ItemIdentity);
551+
}
552+
}
553+
}
554+
555+
ItemPriceMap.Empty();
556+
for (const FOnlineStoreOfferRef& Offer : Offers)
557+
{
558+
const FString& PlatformProductId = Offer->OfferId;
559+
if (!PlatformProductId.IsEmpty() && AbItemMapping.Contains(PlatformProductId))
560+
{
561+
ItemPriceMap.Add(AbItemMapping[PlatformProductId], {PlatformProductId, (uint64)Offer->NumericPrice});
562+
FNativePlatformPurchaseUtils::RegionalCurrencyCode = Offer->CurrencyCode;
563+
}
564+
}
565+
566+
OnQueryItemMappingCompleted.ExecuteIfBound(ItemPriceMap);
567+
}
568+
569+
void UNativePlatformPurchaseSubsystem::CheckoutItemWithEpic(const APlayerController* OwningPlayer, const FPurchaseCheckoutRequest CheckoutRequest)
570+
{
571+
FString ErrorMessage = TEXT("");
572+
573+
const IOnlineSubsystem* PlatformSubsystem = IOnlineSubsystem::GetByPlatform();
574+
if (!PlatformSubsystem)
575+
{
576+
ErrorMessage = TEXT("Failed to checkout item using Epic Online Service. Identity interface is invalid.");
577+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("%s"), *ErrorMessage);
578+
OnSyncPurchaseCompleteDelegates.ExecuteIfBound(false, ErrorMessage);
579+
return;
580+
}
581+
582+
IOnlinePurchasePtr PlatformPurchase = PlatformSubsystem->GetPurchaseInterface();
583+
if (!PlatformPurchase)
584+
{
585+
ErrorMessage = TEXT("Failed to checkout item using Epic Online Service. Purchase interface is invalid.");
586+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("%s"), *ErrorMessage);
587+
OnSyncPurchaseCompleteDelegates.ExecuteIfBound(false, ErrorMessage);
588+
return;
589+
}
590+
591+
const ULocalPlayer* LocalPlayer = OwningPlayer->GetLocalPlayer();
592+
if (!LocalPlayer)
593+
{
594+
ErrorMessage = TEXT("Failed to checkout item using Epic Online Services. Local Player is invalid.");
595+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("%s"), *ErrorMessage);
596+
OnSyncPurchaseCompleteDelegates.ExecuteIfBound(false, ErrorMessage);
597+
return;
598+
}
599+
600+
const int32 LocalUserNum = LocalPlayer->GetControllerId();
601+
IOnlineIdentityPtr PlatformIdentity = PlatformSubsystem->GetIdentityInterface();
602+
const FUniqueNetIdPtr UserId = PlatformIdentity->GetUniquePlayerId(LocalUserNum);
603+
if (!UserId)
604+
{
605+
ErrorMessage = TEXT("Failed to checkout item using Epic Online Services. User ID is invalid.");
606+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("%s"), *ErrorMessage);
607+
OnSyncPurchaseCompleteDelegates.ExecuteIfBound(false, ErrorMessage);
608+
return;
609+
}
610+
611+
PlatformPurchase->Checkout(*UserId, CheckoutRequest,
612+
FOnPurchaseCheckoutComplete::CreateWeakLambda(this,
613+
[this, LocalUserNum, PlatformIdentity]
614+
(const FOnlineError& Result, const TSharedRef<FPurchaseReceipt>& Receipt)
615+
{
616+
if (!Result.bSucceeded)
617+
{
618+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Warning, TEXT("Failed to purchase item using Epic Online Services. Error: %s"), *Result.ErrorMessage.ToString());
619+
OnSyncPurchaseCompleteDelegates.ExecuteIfBound(false, Result.ErrorMessage.ToString());
620+
return;
621+
}
622+
623+
// Sync Epic Online Services purchase with AccelByte.
624+
UE_LOG_NATIVE_PLATFORM_PURCHASE(Log, TEXT("Success to purchase item using Epic Online Services. Synching purchase to AccelByte"));
625+
PurchaseSyncState = EPurchaseState::SyncInProgress;
626+
EntitlementInterface->SyncPlatformPurchase(LocalUserNum, FAccelByteModelsEntitlementSyncBase{}, OnSyncPurchaseCompleteDelegates);
627+
})
628+
);
629+
}
630+
#endif
631+
#pragma endregion
632+
439633
#pragma region "Google Play"
440634
#if PLATFORM_ANDROID
441635
void UNativePlatformPurchaseSubsystem::CheckoutItemWithGooglePlay(

Source/AccelByteWars/TutorialModules/Monetization/NativePlatformPurchase/NativePlatformPurchaseSubsystem.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class ACCELBYTEWARS_API UNativePlatformPurchaseSubsystem : public UTutorialModul
5959
FOnQueryItemMappingCompleted OnQueryItemMappingCompleted;
6060

6161
private:
62+
FOnlineIdentityAccelBytePtr IdentityInterface;
6263
FOnlineStoreV2AccelBytePtr StoreInterface;
6364
FOnlineEntitlementsAccelBytePtr EntitlementInterface;
6465
FOnlinePurchaseAccelBytePtr PurchaseInterface;
@@ -104,7 +105,17 @@ class ACCELBYTEWARS_API UNativePlatformPurchaseSubsystem : public UTutorialModul
104105
TMap<int32, uint64> SteamItemPrices;
105106
#endif
106107
#pragma endregion
107-
108+
109+
#pragma region "Epic Games Store"
110+
#if PLATFORM_EOS
111+
void QueryEpicItems(const FUniqueNetIdPtr UserId, const TArray<TSharedRef<FAccelByteModelsItemMapping>>& ItemMappings);
112+
void OnEpicQueryOfferCompleted(bool bWasSuccessful, const TArray<FUniqueOfferId>& OfferIds, const FString& Error);
113+
void CheckoutItemWithEpic(
114+
const APlayerController* OwningPlayer,
115+
const FPurchaseCheckoutRequest CheckoutRequest);
116+
#endif
117+
#pragma endregion
118+
108119
#pragma region "Google Play"
109120
#if PLATFORM_ANDROID
110121
void CheckoutItemWithGooglePlay(
@@ -139,6 +150,7 @@ class ACCELBYTEWARS_API UNativePlatformPurchaseSubsystem : public UTutorialModul
139150
{ EAccelBytePlatformType::Steam, EAccelBytePlatformMapping::STEAM },
140151
{ EAccelBytePlatformType::Google, EAccelBytePlatformMapping::GOOGLE },
141152
{ EAccelBytePlatformType::GooglePlayGames, EAccelBytePlatformMapping::GOOGLE },
153+
{ EAccelBytePlatformType::EpicGames, EAccelBytePlatformMapping::EPIC_GAMES },
142154
};
143155

144156
const TArray<EAccelByteItemType> SupportedNativePlatformItem = { EAccelByteItemType::COINS };

Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/FriendsEssentialsModels.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "Interfaces/OnlinePresenceInterface.h"
1515
#include "FriendsEssentialsModels.generated.h"
1616

17+
#define INVALID_SEARCH_FRIEND_KEYWORD_LENGTH_MESSAGE NSLOCTEXT("AccelByteWars", "Invalid search friend keyword length", "Keyword must be between {0} and {1} characters long.")
1718
#define ALREADY_FRIEND_REASON_MESSAGE NSLOCTEXT("AccelByteWars", "Already friend", "Already friend")
1819
#define BEEN_INVITED_REASON_MESSAGE NSLOCTEXT("AccelByteWars", "You've been invited", "You've been invited")
1920
#define ALREADY_INVITED_REASON_MESSAGE NSLOCTEXT("AccelByteWars", "Already invited", "Already invited")

Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/FriendsSubsystem.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "Core/UI/Components/Prompt/PromptSubsystem.h"
88
#include "OnlineSubsystemUtils.h"
99
#include "TutorialModuleUtilities/StartupSubsystem.h"
10+
#include "TutorialModuleUtilities/TutorialModuleOnlineUtility.h"
1011

1112
#define LOCTEXT_NAMESPACE "AccelByteWars"
1213

@@ -217,6 +218,15 @@ void UFriendsSubsystem::GetSelfFriendCode(const APlayerController* PC, const FOn
217218
// @@@SNIPSTART FriendsSubsystem.cpp-FindFriend
218219
void UFriendsSubsystem::FindFriend(const APlayerController* PC, const FString& InKeyword, const FOnFindFriendComplete& OnComplete)
219220
{
221+
const FIAMPublicSystemConfigResponse& PublicSystemConfig = UTutorialModuleOnlineUtility::GetPublicSystemConfig();
222+
const int32 MinLen = PublicSystemConfig.SearchQueryMinLength, MaxLen = PublicSystemConfig.SearchQueryMaxLength;
223+
if (InKeyword.Len() < MinLen || InKeyword.Len() > MaxLen)
224+
{
225+
UE_LOG_FRIENDS_ESSENTIALS(Warning, TEXT("Cannot find a friend. Keyword must be between %d and %d characters long."), MinLen, MaxLen);
226+
OnComplete.ExecuteIfBound(false, nullptr, FText::Format(INVALID_SEARCH_FRIEND_KEYWORD_LENGTH_MESSAGE, FText::AsNumber(MinLen), FText::AsNumber(MaxLen)).ToString());
227+
return;
228+
}
229+
220230
if (!ensure(FriendsInterface) || !ensure(UserInterface))
221231
{
222232
UE_LOG_FRIENDS_ESSENTIALS(Warning, TEXT("Cannot find a friend. Friends Interface or User Interface is not valid."));

Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/FriendsSubsystem_Starter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "Core/UI/Components/Prompt/PromptSubsystem.h"
88
#include "OnlineSubsystemUtils.h"
99
#include "TutorialModuleUtilities/StartupSubsystem.h"
10+
#include "TutorialModuleUtilities/TutorialModuleOnlineUtility.h"
1011

1112
#define LOCTEXT_NAMESPACE "AccelByteWars"
1213

0 commit comments

Comments
 (0)