Commit 56a3b326 by Minhan Jeong

화웨이 로그인 시스템 추가중

parent b9a8ea41
......@@ -145,8 +145,10 @@ KeyAlias=rmvw2021
KeyStorePassword=3df1q2w3e
KeyPassword=3df1q2w3e
ApplicationDisplayName=Real Madrid Virtual World
bBuildForArmV7=False
bBuildForArm64=True
bBuildForArmV7=True
bBuildForArm64=False
MinSDKVersion=26
TargetSDKVersion=30
[/Script/GooglePADEditor.GooglePADRuntimeSettings]
bOnlyDistribution=False
......
......@@ -33,6 +33,11 @@
"Linux",
"Mac"
]
},
{
"Name": "AndroidPlayBilling",
"Enabled": true,
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/ad0040f7dbbc45cebdcbc4b2c5982904"
}
]
}
\ No newline at end of file
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "Android Play Billing",
"Description": "Android Play Billing plugin for Unreal Engine provides Google Play Billing methods for buying consumable, non-consumable products and subscriptions.",
"Category": "Android",
"CreatedBy": "Nikita Klimov",
"CreatedByURL": "https://github.com/kulichin",
"DocsURL": "https://github.com/kulichin/UnrealAndroidPlayBilling/wiki",
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/ad0040f7dbbc45cebdcbc4b2c5982904",
"SupportURL": "https://github.com/kulichin/UnrealAndroidPlayBilling/issues",
"EngineVersion": "4.25.0",
"CanContainContent": false,
"IsBetaVersion": true,
"Installed": true,
"Modules": [
{
"Name": "AndroidPlayBilling",
"Type": "Runtime",
"LoadingPhase": "Default",
"WhitelistPlatforms": [
"Win64",
"Mac",
"Android"
]
}
]
}
\ No newline at end of file
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Allman
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 132
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
FixNamespaceComments: true
ForEachMacros:
- for
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '.*\.generated\.h'
Priority: 100
- Regex: '.*(PCH).*'
Priority: -1
- Regex: '".*"'
Priority: 1
- Regex: '^<.*\.(h)>'
Priority: 3
- Regex: '^<.*>'
Priority: 4
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
CanonicalDelimiter: ''
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 4
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 4
UseTab: Always
...
// Copyright (C) 2021. Nikita Klimov. All rights reserved.
using UnrealBuildTool;
public class AndroidPlayBilling : ModuleRules
{
public AndroidPlayBilling(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine" });
string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath);
if (Target.Platform == UnrealTargetPlatform.Android)
{
PrivateDependencyModuleNames.Add("Launch");
AdditionalPropertiesForReceipt.Add("AndroidPlugin", System.IO.Path.Combine(PluginPath, "AndroidPlayBilling_UPL_Android.xml"));
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Add dependencies -->
<androidManifestUpdates>
<addPermission android:name="android.permission.INTERNET" />
<addPermission android:name="com.android.vending.BILLING" />
</androidManifestUpdates>
<!-- Copy Library directory & google-services.json -->
<gradleCopies>
<copyDir
src="$S(PluginDir)/Android/"
dst="$S(BuildDir)/gradle/app/src/main/java/com/kulichin/androidplaybilling/" />
</gradleCopies>
<!-- Import dependencies -->
<AARImports>
<insertValue value="com.android.billingclient,billing,4.0.0" />
<insertNewline />
</AARImports>
<!--Enable AndroidX support-->
<gradleProperties>
<insert>
android.useAndroidX = true
android.enableJetifier = true
</insert>
</gradleProperties>
<!-- Replace supportlib imports with AndroidX in engine source files -->
<baseBuildGradleAdditions>
<insert>
allprojects
{
def mappings =
[
'android.arch.lifecycle.Lifecycle': 'androidx.lifecycle.Lifecycle',
'android.arch.lifecycle.LifecycleObserver': 'androidx.lifecycle.LifecycleObserver',
'android.arch.lifecycle.OnLifecycleEvent': 'androidx.lifecycle.OnLifecycleEvent',
'android.arch.lifecycle.ProcessLifecycleOwner': 'androidx.lifecycle.ProcessLifecycleOwner',
'android.arch.lifecycle': 'androidx.lifecycle',
'android.support.annotation': 'androidx.annotation',
'android.support.v13.app.FragmentCompat': 'androidx.legacy.app.FragmentCompat',
'android.support.v4.app.ActivityCompat': 'androidx.core.app.ActivityCompat',
'android.support.v4.app.NotificationCompat': 'androidx.core.app.NotificationCompat',
'android.support.v4.app.NotificationManagerCompat': 'androidx.core.app.NotificationManagerCompat',
'android.support.v4.content.ContextCompat': 'androidx.core.content.ContextCompat',
'android.support.v4.content.FileProvider': 'androidx.core.content.FileProvider',
'constProduct.getSku()': 'constProduct.getSkus().get(0)',
'ownedProduct.getSku()': 'ownedProduct.getSkus().get(0)',
'purchase.getSku()': 'purchase.getSkus().get(0)',
]
beforeEvaluate { project ->
project.rootProject.projectDir.traverse(type: groovy.io.FileType.FILES, nameFilter: ~/.*\.java$/) { f ->
mappings.each { entry ->
if (f.getText('UTF-8').contains(entry.key)) {
println "Updating ${entry.key} to ${entry.value} in file ${f}"
ant.replace(file: f, token: entry.key, value: entry.value)
}
}
}
}
}
</insert>
</baseBuildGradleAdditions>
<!-- Gradle additions -->
<buildGradleAdditions>
<insert>
android
{
compileOptions
{
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
}
</insert>
</buildGradleAdditions>
<!-- ProGuard additions -->
<proguardAdditions>
<insert>
-dontwarn com.kulichin.**
-keep class com.kulichin.** { *; }
-keep interface com.kulichin.** { *; }
-dontwarn com.android.billingclient.**
-keep class com.android.billingclient.** { *; }
-keep interface com.android.billingclient.** { *; }
</insert>
</proguardAdditions>
<!-- GameActivity.java additions -->
<gameActivityImportAdditions>
<insert>
import com.kulichin.androidplaybilling.AndroidPlayBilling;
</insert>
</gameActivityImportAdditions>
<!-- GameActivity.java additions -->
<gameActivityOnCreateAdditions>
<insert>
// Initialize billing class
<!-- PlayBilling = new AndroidPlayBilling(this);-->
</insert>
</gameActivityOnCreateAdditions>
<!-- GameActivity.java additions -->
<gameActivityOnDestroyAdditions>
<insert>
PlayBilling.OnDestroy();
</insert>
</gameActivityOnDestroyAdditions>
<!-- GameActivity.java additions -->
<gameActivityClassAdditions>
<insert>
private AndroidPlayBilling PlayBilling;
public void AndroidThunkJava_LaunchBillingFlow(String ProductID, int ProductType)
{
PlayBilling.LaunchBillingFlow(ProductID, ProductType);
}
public void AndroidThunkJava_LaunchPriceChangeConfirmationFlow(String ProductID, int ProductType)
{
PlayBilling.LaunchPriceChangeConfirmationFlow(ProductID, ProductType);
}
public void AndroidThunkJava_QueryPurchases(int ProductType)
{
PlayBilling.QueryPurchases(ProductType);
}
public void AndroidThunkJava_QuerySkuDetails(String[] ProductIDs, int ProductType)
{
PlayBilling.QuerySkuDetails(ProductIDs, ProductType);
}
public void AndroidThunkJava_QueryPurchaseHistory(int ProductType)
{
PlayBilling.QueryPurchaseHistory(ProductType);
}
public int AndroidThunkJava_IsFeatureSupported(int FeatureType)
{
return PlayBilling.IsFeatureSupported(FeatureType);
}
public boolean AndroidThunkJava_IsIAPInitialized()
{
return PlayBilling.IsIAPInitialized();
}
public boolean AndroidThunkJava_IsPurchased(String ProductID)
{
return PlayBilling.IsPurchased(ProductID);
}
</insert>
</gameActivityClassAdditions>
</root>
// Copyright (C) 2021. Nikita Klimov. All rights reserved.
#include "AndroidPlayBilling.h"
#include "AndroidPlayBillingSettings.h"
#include "Settings/Public/ISettingsModule.h"
#define LOCTEXT_NAMESPACE "FAndroidPlayBillingModule"
void FAndroidPlayBillingModule::StartupModule()
{
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
{
SettingsModule->RegisterSettings(
TEXT("Project"),
TEXT("Plugins"),
TEXT("Android Play Billing"),
LOCTEXT("Android Play Billing", "Android Play Billing"),
LOCTEXT("Android Play Billing", "Settings for Android Play Billing"),
GetMutableDefault<UAndroidPlayBillingSettings>());
}
}
void FAndroidPlayBillingModule::ShutdownModule()
{
if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
{
SettingsModule->UnregisterSettings(
TEXT("Project"),
TEXT("Plugins"),
TEXT("AndroidPlayBilling"));
}
}
FAndroidPlayBillingModule* FAndroidPlayBillingModule::GetModule()
{
return FModuleManager::Get().GetModulePtr<FAndroidPlayBillingModule>("AndroidPlayBilling");
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FAndroidPlayBillingModule, AndroidPlayBilling)
// Copyright (C) 2021. Nikita Klimov. All rights reserved.
#include "AndroidPlayBillingSettings.h"
#if WITH_EDITOR
void UAndroidPlayBillingSettings::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
SaveConfig(CPF_Config, *GetDefaultConfigFilename());
}
#endif
// Copyright (C) 2021. Nikita Klimov. All rights reserved.
#pragma once
#include "AndroidPlayBillingSubsystem.h"
#include "Engine.h"
#define INITIALIZE_DELEGATE_HANDLER_Base(DelegateClass, DelegateName) \
public: \
DelegateClass DelegateName; \
void Add##DelegateName##_Handle(const DelegateClass& Delegate) \
{ \
ClearAll##DelegateName(); \
DelegateName = Delegate; \
} \
void ClearAll##DelegateName() \
{ \
if(DelegateName.IsBound()) \
{ \
DelegateName.Clear(); \
} \
}
#define INITIALIZE_DELEGATE_HANDLER_TwoParams( \
DelegateClass, DelegateName, \
FirstParamType, FirstParamName, SecondParamType, SecondParamName) \
INITIALIZE_DELEGATE_HANDLER_Base(DelegateClass, DelegateName) \
void Trigger##DelegateName(FirstParamType FirstParamName, SecondParamType SecondParamName) \
{ \
if (DelegateName.IsBound()) \
{ \
FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( \
FSimpleDelegateGraphTask::FDelegate::CreateLambda([FirstParamName, SecondParamName, this]() \
{ \
DelegateName.Execute(FirstParamName, SecondParamName); \
ClearAll##DelegateName(); \
}), \
TStatId(), nullptr, ENamedThreads::GameThread); \
} \
}
#define INITIALIZE_DELEGATE_HANDLER_ThreeParams( \
DelegateClass, DelegateName, \
FirstParamType, FirstParamName, SecondParamType, SecondParamName, ThirdParamType, ThirdParamName) \
INITIALIZE_DELEGATE_HANDLER_Base(DelegateClass, DelegateName) \
void Trigger##DelegateName(FirstParamType FirstParamName, SecondParamType SecondParamName, ThirdParamType ThirdParamName) \
{ \
if (DelegateName.IsBound()) \
{ \
FSimpleDelegateGraphTask::CreateAndDispatchWhenReady( \
FSimpleDelegateGraphTask::FDelegate::CreateLambda([FirstParamName, SecondParamName, ThirdParamName, this]() \
{ \
DelegateName.Execute(FirstParamName, SecondParamName, ThirdParamName); \
ClearAll##DelegateName(); \
}), \
TStatId(), nullptr, ENamedThreads::GameThread); \
} \
}
class FAndroidPlayBillingModule : public IModuleInterface
{
public:
virtual void StartupModule() override;
virtual void ShutdownModule() override;
static FAndroidPlayBillingModule* GetModule();
#if PLATFORM_ANDROID
INITIALIZE_DELEGATE_HANDLER_TwoParams(
FOnOperationCompleted, OnOperationCompleted,
const EBillingResponseCode, ResponseCode,
const FString&, ResponseMessage)
INITIALIZE_DELEGATE_HANDLER_ThreeParams(
FOnLaunchBillingFlowCompleted, OnLaunchBillingFlowCompleted,
const EBillingResponseCode, ResponseCode,
const FString&, ResponseMessage,
const TArray<FPurchaseRecord>&, UpdatedPurchaseRecords);
INITIALIZE_DELEGATE_HANDLER_ThreeParams(
FOnQueryPurchaseHistoryCompleted, OnQueryPurchaseHistoryCompleted,
const EBillingResponseCode, ResponseCode,
const FString&, ResponseMessage,
const TArray<FPurchaseRecordFromHistory>&, PurchaseRecordsFromHistory);
INITIALIZE_DELEGATE_HANDLER_ThreeParams(
FOnQuerySkuDetailsCompleted, OnQuerySkuDetailsCompleted,
const EBillingResponseCode, ResponseCode,
const FString&, ResponseMessage,
const TArray<FSkuDetailsRecord>&, SkuDetailsRecords);
INITIALIZE_DELEGATE_HANDLER_ThreeParams(
FOnQueryPurchasesCompleted, OnQueryPurchasesCompleted,
const EBillingResponseCode, ResponseCode,
const FString&, ResponseMessage,
const TArray<FPurchaseRecord>&, PurchaseRecords);
#endif
};
// Copyright (C) 2021. Nikita Klimov. All rights reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "AndroidPlayBillingSettings.generated.h"
UCLASS(transient, config = Engine)
class UAndroidPlayBillingSettings : public UObject
{
GENERATED_BODY()
UPROPERTY(Config, EditAnywhere, Category = "Android Play Billing")
FString BillingLicenseKey;
#if WITH_EDITOR
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
};
......@@ -89,6 +89,15 @@
<buildGradleAdditions>
<insert>
android
{
compileOptions
{
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
}
apply plugin: 'com.android.application'
dependencies
......@@ -139,6 +148,7 @@
import com.Plugins.HuaweiSDK.activity.ConsumptionActivity;
import com.Plugins.HuaweiSDK.activity.EntryActivity;
import com.Plugins.HuaweiSDK.activity.AccountActivity;
</insert>
</gameActivityImportAdditions>
......@@ -147,10 +157,18 @@
</insert>
</gameActivityPostImportAdditions>
<gameActivityOnCreateAdditions>
<insert>
mAccountActivity = new AccountActivity(this);
</insert>
</gameActivityOnCreateAdditions>
<gameActivityClassAdditions>
<insert>
private ConsumptionActivity mConsumptionActivity;
private EntryActivity mEntryActivity;
private AccountActivity mAccountActivity;
public void AndroidThunkJava_CreateHuaweiIap()
{
mConsumptionActivity = new ConsumptionActivity(this);
......@@ -170,18 +188,19 @@
{
mEntryActivity.Payment(productId);
}
</insert>
</gameActivityClassAdditions>
<gameActivityOnCreateAdditions>
<insert>
public void AndroidThunkJava_SignIn()
{
mAccountActivity = new AccountActivity(this);
mAccountActivity.signIn();
}
</insert>
</gameActivityOnCreateAdditions>
</gameActivityClassAdditions>
<gameActivityOnActivityResultAdditions>
<insert>
mEntryActivity.onActivityResult(requestCode, resultCode, data);
mAccountActivity.onActivityResult(requestCode, resultCode, data);
</insert>
</gameActivityOnActivityResultAdditions>
......
package com.Plugins.HuaweiSDK.activity;
import android.app.Activity;
import android.content.Intent;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.util.Log;
import com.huawei.hmf.tasks.Task;
import com.huawei.hms.common.ApiException;
import com.huawei.hms.support.account.AccountAuthManager;
import com.huawei.hms.support.account.request.AccountAuthParams;
import com.huawei.hms.support.account.request.AccountAuthParamsHelper;
import com.huawei.hms.support.account.result.AuthAccount;
import com.huawei.hms.support.account.service.AccountAuthService;
public class AccountActivity extends activity {
public class AccountActivity extends Activity {
private String TAG = "HuaweiAccountActivity";
private AccountAuthService mAuthManager;
......@@ -20,13 +26,15 @@ public class AccountActivity extends activity {
mActivity = activity;
}
private void signIn() {
public void signIn() {
Log.i(TAG, "AccountActivity.signIn");
mAuthParam = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setIdToken()
.setAccessToken()
.createParams();
mAuthManager = AccountAuthManager.getService(mActivity, mAuthParam);
startActivityForResult(mAuthManager.getSignInIntent(), Constant.REQUEST_SIGN_IN_LOGIN);
startActivityForResult(mAuthManager.getSignInIntent(), 1002);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
......@@ -45,10 +53,10 @@ public class AccountActivity extends activity {
} else {
Log.i(TAG, "signIn failed: " + ((ApiException) authAccountTask.getException()).getStatusCode());
nativeSignInResult(false, 0);
nativeSignInResult(false, "0");
}
}
if (requestCode == Constant.REQUEST_SIGN_IN_LOGIN_CODE) {
if (requestCode == 1003) {
//login success
Task<AuthAccount> authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data);
if (authAccountTask.isSuccessful()) {
......
......@@ -2,7 +2,7 @@ package com.Plugins.HuaweiSDK.activity;
import android.app.Activity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
......
......@@ -38,8 +38,13 @@ static void ReqSignIn()
static jmethodID SignInMethod = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_SignIn", "()V", false);
if (SignInMethod)
{
UE_LOG(LogTemp, Log, TEXT("Find AndroidThunkJava_SignIn"));
FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, SignInMethod);
}
else
{
UE_LOG(LogTemp, Log, TEXT("!Find AndroidThunkJava_SignIn"));
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment