First Version of AppLovin SDK Package
This commit is contained in:
commit
87170f3db9
106
.gitignore
vendored
Normal file
106
.gitignore
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
# This .gitignore file should be placed at the root of your Unity project directory
|
||||
#
|
||||
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
|
||||
#
|
||||
.utmp/
|
||||
/[Ll]ibrary/
|
||||
/[Tt]emp/
|
||||
/[Oo]bj/
|
||||
/[Bb]uild/
|
||||
/[Bb]uilds/
|
||||
/[Ll]ogs/
|
||||
/[Uu]ser[Ss]ettings/
|
||||
*.log
|
||||
|
||||
# By default unity supports Blender asset imports, *.blend1 blender files do not need to be commited to version control.
|
||||
*.blend1
|
||||
*.blend1.meta
|
||||
|
||||
# MemoryCaptures can get excessive in size.
|
||||
# They also could contain extremely sensitive data
|
||||
/[Mm]emoryCaptures/
|
||||
|
||||
# Recordings can get excessive in size
|
||||
/[Rr]ecordings/
|
||||
|
||||
# Uncomment this line if you wish to ignore the asset store tools plugin
|
||||
# /[Aa]ssets/AssetStoreTools*
|
||||
|
||||
# Autogenerated Jetbrains Rider plugin
|
||||
/[Aa]ssets/Plugins/Editor/JetBrains*
|
||||
# Jetbrains Rider personal-layer settings
|
||||
*.DotSettings.user
|
||||
|
||||
# Visual Studio cache directory
|
||||
.vs/
|
||||
|
||||
# Gradle cache directory
|
||||
.gradle/
|
||||
|
||||
# Autogenerated VS/MD/Consulo solution and project files
|
||||
ExportedObj/
|
||||
.consulo/
|
||||
*.csproj
|
||||
*.unityproj
|
||||
*.sln
|
||||
*.suo
|
||||
*.tmp
|
||||
*.user
|
||||
*.userprefs
|
||||
*.pidb
|
||||
*.booproj
|
||||
*.svd
|
||||
*.pdb
|
||||
*.mdb
|
||||
*.opendb
|
||||
*.VC.db
|
||||
|
||||
# Unity3D generated meta files
|
||||
*.pidb.meta
|
||||
*.pdb.meta
|
||||
*.mdb.meta
|
||||
|
||||
# Unity3D generated file on crash reports
|
||||
sysinfo.txt
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Builds
|
||||
*.apk
|
||||
*.aab
|
||||
*.unitypackage
|
||||
*.unitypackage.meta
|
||||
|
||||
# Crashlytics generated file
|
||||
crashlytics-build.properties
|
||||
|
||||
# TestRunner generated files
|
||||
InitTestScene*.unity*
|
||||
|
||||
# Addressables default ignores, before user customizations
|
||||
/ServerData
|
||||
/[Aa]ssets/StreamingAssets/aa*
|
||||
/[Aa]ssets/AddressableAssetsData/link.xml*
|
||||
/[Aa]ssets/Addressables_Temp*
|
||||
# By default, Addressables content builds will generate addressables_content_state.bin
|
||||
# files in platform-specific subfolders, for example:
|
||||
# /Assets/AddressableAssetsData/OSX/addressables_content_state.bin
|
||||
/[Aa]ssets/AddressableAssetsData/*/*.bin*
|
||||
|
||||
# Visual Scripting auto-generated files
|
||||
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Flow/UnitOptions.db
|
||||
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Flow/UnitOptions.db.meta
|
||||
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Core/Property Providers
|
||||
/[Aa]ssets/Unity.VisualScripting.Generated/VisualScripting.Core/Property Providers.meta
|
||||
|
||||
# Auto-generated scenes by play mode tests
|
||||
/[Aa]ssets/[Ii]nit[Tt]est[Ss]cene*.unity*
|
||||
|
||||
.vsconfig
|
||||
|
||||
Logs/
|
||||
[Aa]ssets/
|
||||
[Pp]ublish/
|
||||
.vscode/settings.json
|
||||
*.dat
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e25596c6ab236a542b261858f6937a72
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60b4f8b65f206b640bc4d6a7c2fa6646
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Editor
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<dependencies>
|
||||
<androidPackages>
|
||||
<androidPackage spec="com.applovin:applovin-sdk:13.5.1" />
|
||||
</androidPackages>
|
||||
<iosPods>
|
||||
<iosPod name="AppLovinSDK" version="13.5.1" />
|
||||
</iosPods>
|
||||
</dependencies>
|
||||
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ede6eb9517400ad4dafc9a1fe37ed1af
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Editor/Dependencies.xml
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d62b0762d7ed7640a36464589cae263
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Plugins
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fefcfd9452533604789894816f53cd04
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Plugins/Android
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@ -0,0 +1,35 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d8690973bbf016449fae79e94ef2e0b
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Plugins/Android/applovin-max-unity-plugin.aar
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0c19d2825cded141a754adf916bccbd
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Plugins/iOS
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,97 @@
|
||||
//
|
||||
// MAUnityAdManager.h
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppLovinSDK/AppLovinSDK.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
typedef const void *MAUnityRef;
|
||||
typedef void (*ALUnityBackgroundCallback)(const char* args);
|
||||
|
||||
@interface MAUnityAdManager : NSObject
|
||||
|
||||
- (void)initializeSdkWithConfiguration:(ALSdkInitializationConfiguration *)initConfig andCompletionHandler:(ALSdkInitializationCompletionHandler)completionHandler;
|
||||
|
||||
- (void)createBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier atPosition:(nullable NSString *)bannerPosition isAdaptive:(BOOL)isAdaptive;
|
||||
- (void)createBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier x:(CGFloat)xOffset y:(CGFloat)yOffset isAdaptive:(BOOL)isAdaptive;
|
||||
- (void)loadBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)setBannerBackgroundColorForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier hexColorCode:(nullable NSString *)hexColorCode;
|
||||
- (void)setBannerPlacement:(nullable NSString *)placement forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)startBannerAutoRefreshForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)stopBannerAutoRefreshForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)setBannerExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
|
||||
- (void)setBannerLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
|
||||
- (void)setBannerCustomData:(nullable NSString *)customData forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)setBannerWidth:(CGFloat)width forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)updateBannerPosition:(nullable NSString *)bannerPosition forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)updateBannerPosition:(CGFloat)xOffset y:(CGFloat)yOffset forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)showBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)destroyBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)hideBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (NSString *)bannerLayoutForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
+ (CGFloat)adaptiveBannerHeightForWidth:(CGFloat)width;
|
||||
|
||||
- (void)createMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier atPosition:(nullable NSString *)mrecPosition;
|
||||
- (void)createMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier x:(CGFloat)xOffset y:(CGFloat)yOffset;
|
||||
- (void)loadMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)setMRecPlacement:(nullable NSString *)placement forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)startMRecAutoRefreshForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)stopMRecAutoRefreshForAdUnitIdentifier:(nullable NSString *)adUnitIdentifer;
|
||||
- (void)setMRecExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
|
||||
- (void)setMRecLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
|
||||
- (void)setMRecCustomData:(nullable NSString *)customData forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)showMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)destroyMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)hideMRecWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)updateMRecPosition:(nullable NSString *)mrecPosition forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)updateMRecPosition:(CGFloat)xOffset y:(CGFloat)yOffset forAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (NSString *)mrecLayoutForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
|
||||
- (void)loadInterstitialWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (BOOL)isInterstitialReadyWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)showInterstitialWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier placement:(nullable NSString *)placement customData:(nullable NSString *)customData;
|
||||
- (void)setInterstitialExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
|
||||
- (void)setInterstitialLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
|
||||
|
||||
- (void)loadAppOpenAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (BOOL)isAppOpenAdReadyWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)showAppOpenAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier placement:(nullable NSString *)placement customData:(nullable NSString *)customData;
|
||||
- (void)setAppOpenAdExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
|
||||
- (void)setAppOpenAdLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
|
||||
|
||||
- (void)loadRewardedAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (BOOL)isRewardedAdReadyWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
|
||||
- (void)showRewardedAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier placement:(nullable NSString *)placement customData:(nullable NSString *)customData;
|
||||
- (void)setRewardedAdExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
|
||||
- (void)setRewardedAdLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
|
||||
|
||||
// Event Tracking
|
||||
- (void)trackEvent:(nullable NSString *)event parameters:(nullable NSString *)parameters;
|
||||
|
||||
// Ad Value
|
||||
- (NSString *)adValueForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier withKey:(nullable NSString *)key;
|
||||
|
||||
// User Service
|
||||
- (void)didDismissUserConsentDialog;
|
||||
|
||||
// CMP Service
|
||||
- (void)showCMPForExistingUser;
|
||||
|
||||
// Utils
|
||||
+ (NSString *)serializeParameters:(NSDictionary<NSString *, id> *)dict;
|
||||
+ (NSDictionary<NSString *, id> *)deserializeParameters:(nullable NSString *)serialized;
|
||||
|
||||
+ (void)setUnityBackgroundCallback:(ALUnityBackgroundCallback)unityBackgroundCallback;
|
||||
|
||||
/**
|
||||
* Creates an instance of @c MAUnityAdManager if needed and returns the singleton instance.
|
||||
*/
|
||||
+ (instancetype)shared;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@ -0,0 +1,115 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 504e736c718f98940b89dc1f9d2df5d5
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.h
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
'': Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 1
|
||||
Exclude Linux: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude LinuxUniversal: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 0
|
||||
Exclude tvOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: LinuxUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,109 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fce5b2f8f4b165649b3d7fbd88a101b8
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Plugins/iOS/MAUnityAdManager.m
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
'': Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 1
|
||||
Exclude Linux: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude LinuxUniversal: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 0
|
||||
Exclude tvOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,109 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c87e19d7749c16740bf44bd2063751b8
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/AppLovin/Plugins/iOS/MAUnityPlugin.mm
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
'': Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 1
|
||||
Exclude Linux: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude LinuxUniversal: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 0
|
||||
Exclude tvOS: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
- first:
|
||||
tvOS: tvOS
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,5 @@
|
||||
# AppLovin MAX Unity Plugin
|
||||
|
||||
To get the latest changes, see the [AppLovin MAX Unity Changelog](https://support.axon.ai/en/max/unity/changelog).
|
||||
|
||||
[BywayStudios] Modified: Find AppLovin Settings from Project Settings
|
||||
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7307274c16eff2e42ba988ed069e377c
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/CHANGELOG.md
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,5 @@
|
||||
# AppLovin MAX Copyright ©2024 AppLovin
|
||||
|
||||
This software is subject to, and made available under, the AppLovin Software Development Kit End User License Agreement (“SDK EULA”), see https://www.applovin.com/eula/.
|
||||
|
||||
Your use of the software and accompanying services constitutes your acceptance of such terms. Unless expressly provided otherwise, the software under this license is made available strictly on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. Please review the SDK EULA for details on these and other terms and conditions.
|
||||
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0aba2247c5934024eadc8517876a5a38
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/LICENSE.md
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6054ca66eb6c81c409b5c1a3f8f0f199
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Prefabs
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,402 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3149432657757030138
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5965516886513985157}
|
||||
- component: {fileID: 3167928293195730454}
|
||||
- component: {fileID: 6048907697713132302}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5965516886513985157
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 4118862295226300947}
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 84}
|
||||
m_SizeDelta: {x: 0, y: 168}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3167928293195730454
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &6048907697713132302
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &3829518492429360636
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4118862295226300947}
|
||||
- component: {fileID: 5582763645243389146}
|
||||
- component: {fileID: 1436650035481827287}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &4118862295226300947
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 5084927109723455527}
|
||||
- {fileID: 8189983859356672495}
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 1}
|
||||
m_AnchorMax: {x: 0.5, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -50}
|
||||
m_SizeDelta: {x: 640, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5582763645243389146
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &1436650035481827287
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &4772536868390647122
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8189983859356672495}
|
||||
- component: {fileID: 7216515036998124610}
|
||||
- component: {fileID: 3801875349924125266}
|
||||
m_Layer: 5
|
||||
m_Name: InfoText
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &8189983859356672495
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4772536868390647122}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4118862295226300947}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 3}
|
||||
m_SizeDelta: {x: 0, y: -6}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7216515036998124610
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4772536868390647122}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3801875349924125266
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4772536868390647122}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.29411766, g: 0.29411766, b: 0.29411766, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 18
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 1
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 7
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Actual banner size may vary on mobile devices
|
||||
--- !u!1 &7742712311334970126
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3413013686078446151}
|
||||
- component: {fileID: 2511819091764556577}
|
||||
- component: {fileID: 2638196187645015298}
|
||||
- component: {fileID: 633018877563332563}
|
||||
m_Layer: 5
|
||||
m_Name: BannerBottom
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3413013686078446151
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 5965516886513985157}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!223 &2511819091764556577
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 0
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 500
|
||||
m_TargetDisplay: 0
|
||||
--- !u!114 &2638196187645015298
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 0
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 800, y: 600}
|
||||
m_ScreenMatchMode: 0
|
||||
m_MatchWidthOrHeight: 0
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
--- !u!114 &633018877563332563
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!1 &8436952342056443077
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5084927109723455527}
|
||||
- component: {fileID: 7267203896389005665}
|
||||
- component: {fileID: 5500603550844857255}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5084927109723455527
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4118862295226300947}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -4}
|
||||
m_SizeDelta: {x: 0, y: -8}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7267203896389005665
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &5500603550844857255
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 26
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 0
|
||||
m_MaxSize: 71
|
||||
m_Alignment: 1
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: MAX Banner Ad
|
||||
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa5dd5d0c78b392429b3631b8fbe01ce
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Prefabs/BannerBottom.prefab
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,402 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3149432657757030138
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5965516886513985157}
|
||||
- component: {fileID: 3167928293195730454}
|
||||
- component: {fileID: 6048907697713132302}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5965516886513985157
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 4118862295226300947}
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -50}
|
||||
m_SizeDelta: {x: 0, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3167928293195730454
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &6048907697713132302
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &3829518492429360636
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 4118862295226300947}
|
||||
- component: {fileID: 5582763645243389146}
|
||||
- component: {fileID: 1436650035481827287}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &4118862295226300947
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 5084927109723455527}
|
||||
- {fileID: 7429934296583149777}
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0}
|
||||
m_AnchorMax: {x: 0.5, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 640, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &5582763645243389146
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &1436650035481827287
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3829518492429360636}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &5625059666589051168
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7429934296583149777}
|
||||
- component: {fileID: 6576623406533516677}
|
||||
- component: {fileID: 5405475098690228567}
|
||||
m_Layer: 5
|
||||
m_Name: InfoText
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &7429934296583149777
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5625059666589051168}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4118862295226300947}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 3}
|
||||
m_SizeDelta: {x: 0, y: -6}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6576623406533516677
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5625059666589051168}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &5405475098690228567
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5625059666589051168}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.29411766, g: 0.29411766, b: 0.29411766, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 18
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 1
|
||||
m_MaxSize: 40
|
||||
m_Alignment: 7
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Actual banner size may vary on mobile devices
|
||||
--- !u!1 &7742712311334970126
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3413013686078446151}
|
||||
- component: {fileID: 2511819091764556577}
|
||||
- component: {fileID: 2638196187645015298}
|
||||
- component: {fileID: 633018877563332563}
|
||||
m_Layer: 5
|
||||
m_Name: BannerTop
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3413013686078446151
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 5965516886513985157}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!223 &2511819091764556577
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 0
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 500
|
||||
m_TargetDisplay: 0
|
||||
--- !u!114 &2638196187645015298
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 0
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 800, y: 600}
|
||||
m_ScreenMatchMode: 0
|
||||
m_MatchWidthOrHeight: 0
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
--- !u!114 &633018877563332563
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!1 &8436952342056443077
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5084927109723455527}
|
||||
- component: {fileID: 7267203896389005665}
|
||||
- component: {fileID: 5500603550844857255}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5084927109723455527
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 4118862295226300947}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -4}
|
||||
m_SizeDelta: {x: 0, y: -8}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7267203896389005665
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &5500603550844857255
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 26
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 0
|
||||
m_MaxSize: 71
|
||||
m_Alignment: 1
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: MAX Banner Ad
|
||||
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bc9e21c557eab474eba3146904532852
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Prefabs/BannerTop.prefab
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,523 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &3149432657757030138
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5965516886513985157}
|
||||
- component: {fileID: 3167928293195730454}
|
||||
- component: {fileID: 6048907697713132302}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5965516886513985157
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 5084927109723455527}
|
||||
- {fileID: 8681486192829137138}
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3167928293195730454
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &6048907697713132302
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.88235295, g: 0.88235295, b: 0.88235295, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &5668641863723001099
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8681486192829137138}
|
||||
- component: {fileID: 8217482188885705039}
|
||||
- component: {fileID: 3177344817093501532}
|
||||
- component: {fileID: 4415703054918645549}
|
||||
m_Layer: 5
|
||||
m_Name: MaxInterstitialCloseButton
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &8681486192829137138
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 763654547095120985}
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 1}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: -200, y: -100}
|
||||
m_SizeDelta: {x: 250, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8217482188885705039
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3177344817093501532
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!114 &4415703054918645549
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 3177344817093501532}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &6155160063690407013
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1672649117655046507}
|
||||
- component: {fileID: 2484422763836779945}
|
||||
- component: {fileID: 1332063313327512547}
|
||||
- component: {fileID: 9160434328933334999}
|
||||
m_Layer: 5
|
||||
m_Name: EventSystem
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1672649117655046507
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6155160063690407013}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &2484422763836779945
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6155160063690407013}
|
||||
m_Enabled: 0
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_FirstSelected: {fileID: 0}
|
||||
m_sendNavigationEvents: 1
|
||||
m_DragThreshold: 10
|
||||
--- !u!114 &1332063313327512547
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6155160063690407013}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalAxis: Horizontal
|
||||
m_VerticalAxis: Vertical
|
||||
m_SubmitButton: Submit
|
||||
m_CancelButton: Cancel
|
||||
m_InputActionsPerSecond: 10
|
||||
m_RepeatDelay: 0.5
|
||||
m_ForceModuleActive: 0
|
||||
--- !u!114 &9160434328933334999
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6155160063690407013}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e0acf281ba86b4929a6942ecd998395b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &6462551400748024402
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 763654547095120985}
|
||||
- component: {fileID: 6719360953530842803}
|
||||
- component: {fileID: 4616290306121202327}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &763654547095120985
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 8681486192829137138}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6719360953530842803
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &4616290306121202327
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 40
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 4
|
||||
m_MaxSize: 47
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Close
|
||||
--- !u!1 &7742712311334970126
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3413013686078446151}
|
||||
- component: {fileID: 2511819091764556577}
|
||||
- component: {fileID: 2638196187645015298}
|
||||
- component: {fileID: 633018877563332563}
|
||||
m_Layer: 5
|
||||
m_Name: Interstitial
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3413013686078446151
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 5965516886513985157}
|
||||
- {fileID: 1672649117655046507}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!223 &2511819091764556577
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 0
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 999
|
||||
m_TargetDisplay: 0
|
||||
--- !u!114 &2638196187645015298
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 0
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 800, y: 600}
|
||||
m_ScreenMatchMode: 0
|
||||
m_MatchWidthOrHeight: 0
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
--- !u!114 &633018877563332563
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!1 &8436952342056443077
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5084927109723455527}
|
||||
- component: {fileID: 7267203896389005665}
|
||||
- component: {fileID: 5500603550844857255}
|
||||
m_Layer: 5
|
||||
m_Name: MaxInterstitialTitle
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5084927109723455527
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0.5}
|
||||
m_AnchorMax: {x: 1, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 300}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7267203896389005665
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &5500603550844857255
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 50
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 0
|
||||
m_MaxSize: 71
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: MAX Interstitial Ad
|
||||
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 555e214396bd3a14e87ff2f03ed77179
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Prefabs/Interstitial.prefab
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,795 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &288832541099509301
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6736833388881778366}
|
||||
- component: {fileID: 738723989743429661}
|
||||
- component: {fileID: 3366016410383180441}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &6736833388881778366
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 288832541099509301}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 2219183527695013266}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &738723989743429661
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 288832541099509301}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3366016410383180441
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 288832541099509301}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 35
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 3
|
||||
m_MaxSize: 48
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: 'Grant Reward
|
||||
|
||||
(5 coins)'
|
||||
--- !u!1 &2620135977249264498
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3035265698078104281}
|
||||
- component: {fileID: 7277178523579209441}
|
||||
- component: {fileID: 8085319417655039649}
|
||||
m_Layer: 5
|
||||
m_Name: MaxRewardStatus
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3035265698078104281
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2620135977249264498}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0.5}
|
||||
m_AnchorMax: {x: 1, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: -250}
|
||||
m_SizeDelta: {x: 0, y: 200}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7277178523579209441
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2620135977249264498}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &8085319417655039649
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2620135977249264498}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 40
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 10
|
||||
m_MaxSize: 69
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Reward not yet granted.
|
||||
--- !u!1 &3096027301306273604
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2219183527695013266}
|
||||
- component: {fileID: 3687429596110321440}
|
||||
- component: {fileID: 3757577222601629632}
|
||||
- component: {fileID: 87227930114769318}
|
||||
m_Layer: 5
|
||||
m_Name: MaxRewardButton
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2219183527695013266
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3096027301306273604}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 6736833388881778366}
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: -150}
|
||||
m_SizeDelta: {x: 300, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3687429596110321440
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3096027301306273604}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3757577222601629632
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3096027301306273604}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!114 &87227930114769318
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3096027301306273604}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 3757577222601629632}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &3149432657757030138
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5965516886513985157}
|
||||
- component: {fileID: 3167928293195730454}
|
||||
- component: {fileID: 6048907697713132302}
|
||||
m_Layer: 5
|
||||
m_Name: Panel
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5965516886513985157
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 5084927109723455527}
|
||||
- {fileID: 8681486192829137138}
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3167928293195730454
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &6048907697713132302
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 3149432657757030138}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.88235295, g: 0.88235295, b: 0.88235295, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!1 &4010021198786516228
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3074011789293951898}
|
||||
- component: {fileID: 301935380126337495}
|
||||
- component: {fileID: 535359239537776472}
|
||||
- component: {fileID: 1463999766055390634}
|
||||
m_Layer: 5
|
||||
m_Name: EventSystem
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &3074011789293951898
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4010021198786516228}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 3413013686078446151}
|
||||
m_RootOrder: 3
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &301935380126337495
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4010021198786516228}
|
||||
m_Enabled: 0
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -619905303, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_FirstSelected: {fileID: 0}
|
||||
m_sendNavigationEvents: 1
|
||||
m_DragThreshold: 10
|
||||
--- !u!114 &535359239537776472
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4010021198786516228}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1077351063, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_HorizontalAxis: Horizontal
|
||||
m_VerticalAxis: Vertical
|
||||
m_SubmitButton: Submit
|
||||
m_CancelButton: Cancel
|
||||
m_InputActionsPerSecond: 10
|
||||
m_RepeatDelay: 0.5
|
||||
m_ForceModuleActive: 0
|
||||
--- !u!114 &1463999766055390634
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 4010021198786516228}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: e0acf281ba86b4929a6942ecd998395b, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
--- !u!1 &5668641863723001099
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8681486192829137138}
|
||||
- component: {fileID: 8217482188885705039}
|
||||
- component: {fileID: 3177344817093501532}
|
||||
- component: {fileID: 4415703054918645549}
|
||||
m_Layer: 5
|
||||
m_Name: MaxRewardedCloseButton
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &8681486192829137138
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 763654547095120985}
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 1, y: 1}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: -200, y: -100}
|
||||
m_SizeDelta: {x: 250, y: 100}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &8217482188885705039
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &3177344817093501532
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Type: 1
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
--- !u!114 &4415703054918645549
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5668641863723001099}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Navigation:
|
||||
m_Mode: 3
|
||||
m_SelectOnUp: {fileID: 0}
|
||||
m_SelectOnDown: {fileID: 0}
|
||||
m_SelectOnLeft: {fileID: 0}
|
||||
m_SelectOnRight: {fileID: 0}
|
||||
m_Transition: 1
|
||||
m_Colors:
|
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
|
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
|
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
|
||||
m_ColorMultiplier: 1
|
||||
m_FadeDuration: 0.1
|
||||
m_SpriteState:
|
||||
m_HighlightedSprite: {fileID: 0}
|
||||
m_PressedSprite: {fileID: 0}
|
||||
m_DisabledSprite: {fileID: 0}
|
||||
m_AnimationTriggers:
|
||||
m_NormalTrigger: Normal
|
||||
m_HighlightedTrigger: Highlighted
|
||||
m_PressedTrigger: Pressed
|
||||
m_DisabledTrigger: Disabled
|
||||
m_Interactable: 1
|
||||
m_TargetGraphic: {fileID: 3177344817093501532}
|
||||
m_OnClick:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
--- !u!1 &6462551400748024402
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 763654547095120985}
|
||||
- component: {fileID: 6719360953530842803}
|
||||
- component: {fileID: 4616290306121202327}
|
||||
m_Layer: 5
|
||||
m_Name: Text
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &763654547095120985
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 8681486192829137138}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 1, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &6719360953530842803
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &4616290306121202327
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6462551400748024402}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 40
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 4
|
||||
m_MaxSize: 47
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Close
|
||||
--- !u!1 &7742712311334970126
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 3413013686078446151}
|
||||
- component: {fileID: 2511819091764556577}
|
||||
- component: {fileID: 2638196187645015298}
|
||||
- component: {fileID: 633018877563332563}
|
||||
m_Layer: 5
|
||||
m_Name: Rewarded
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &3413013686078446151
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||
m_Children:
|
||||
- {fileID: 5965516886513985157}
|
||||
- {fileID: 3035265698078104281}
|
||||
- {fileID: 2219183527695013266}
|
||||
- {fileID: 3074011789293951898}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0}
|
||||
m_AnchorMax: {x: 0, y: 0}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 0}
|
||||
m_Pivot: {x: 0, y: 0}
|
||||
--- !u!223 &2511819091764556577
|
||||
Canvas:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
serializedVersion: 3
|
||||
m_RenderMode: 0
|
||||
m_Camera: {fileID: 0}
|
||||
m_PlaneDistance: 100
|
||||
m_PixelPerfect: 0
|
||||
m_ReceivesEvents: 1
|
||||
m_OverrideSorting: 0
|
||||
m_OverridePixelPerfect: 0
|
||||
m_SortingBucketNormalizedSize: 0
|
||||
m_AdditionalShaderChannelsFlag: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingOrder: 999
|
||||
m_TargetDisplay: 0
|
||||
--- !u!114 &2638196187645015298
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_UiScaleMode: 0
|
||||
m_ReferencePixelsPerUnit: 100
|
||||
m_ScaleFactor: 1
|
||||
m_ReferenceResolution: {x: 800, y: 600}
|
||||
m_ScreenMatchMode: 0
|
||||
m_MatchWidthOrHeight: 0
|
||||
m_PhysicalUnit: 3
|
||||
m_FallbackScreenDPI: 96
|
||||
m_DefaultSpriteDPI: 96
|
||||
m_DynamicPixelsPerUnit: 1
|
||||
--- !u!114 &633018877563332563
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7742712311334970126}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_IgnoreReversedGraphics: 1
|
||||
m_BlockingObjects: 0
|
||||
m_BlockingMask:
|
||||
serializedVersion: 2
|
||||
m_Bits: 4294967295
|
||||
--- !u!1 &8436952342056443077
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5084927109723455527}
|
||||
- component: {fileID: 7267203896389005665}
|
||||
- component: {fileID: 5500603550844857255}
|
||||
m_Layer: 5
|
||||
m_Name: MaxRewardTitle
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &5084927109723455527
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 5965516886513985157}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 0.5}
|
||||
m_AnchorMax: {x: 1, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 0, y: 300}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &7267203896389005665
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &5500603550844857255
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8436952342056443077}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_FontData:
|
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
|
||||
m_FontSize: 50
|
||||
m_FontStyle: 0
|
||||
m_BestFit: 0
|
||||
m_MinSize: 0
|
||||
m_MaxSize: 71
|
||||
m_Alignment: 4
|
||||
m_AlignByGeometry: 0
|
||||
m_RichText: 1
|
||||
m_HorizontalOverflow: 0
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: MAX Rewarded Ad
|
||||
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5bad03fdefe62a45b0937e788d031c5
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Prefabs/Rewarded.prefab
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,5 @@
|
||||
# AppLovin MAX Unity Plugin
|
||||
|
||||
For more information, please visit our [AppLovin Mediated Networks Documentation](https://support.axon.ai/en/max/unity/overview/integration/).
|
||||
|
||||
[BywayStudios] Modified: Find AppLovin Settings from Project Settings
|
||||
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 898504e87bd2e524ea786120a7fde15c
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/README.md
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f387a278a9b21244a8596afd381c32d
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Resources
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4999cff8fc4b9144d89441188cc9075a
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Resources/Images
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,94 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e4c26f0ffb8f294d8ddc0cfb164a088
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Resources/Images/error_icon.png
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 576 B |
@ -0,0 +1,95 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac17b1534907fcc42a2b362381f9a467
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Resources/Images/info_icon.png
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 159 B |
@ -0,0 +1,94 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d725bdef3df338b4494deb9e6d0ba6d5
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Resources/Images/uninstall_icon.png
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 959 B |
@ -0,0 +1,91 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a976cf36b7d009a46933a6bb36c0a5ca
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Resources/Images/warning_icon.png
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 9
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7194ec31543b18743ae33df55efbd749
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: decf1b4f4765ea744a494cce026b0a4a
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e723bc4eacac03b40b68cb89acfd8b11
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,171 @@
|
||||
//
|
||||
// AppLovinAutoUpdater.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 1/27/20.
|
||||
// Copyright © 2020 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles auto updates for AppLovin MAX plugin.
|
||||
/// </summary>
|
||||
public static class AppLovinAutoUpdater
|
||||
{
|
||||
public const string KeyAutoUpdateEnabled = "com.applovin.auto_update_enabled";
|
||||
private const string KeyLastUpdateCheckTime = "com.applovin.last_update_check_time_v2"; // Updated to v2 to force adapter version checks in plugin version 3.1.10.
|
||||
private static readonly DateTime EpochTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
private static readonly int SecondsInADay = (int) TimeSpan.FromDays(1).TotalSeconds;
|
||||
|
||||
// TODO: Make this list dynamic.
|
||||
public static readonly Dictionary<string, string> MinAdapterVersions = new Dictionary<string, string>()
|
||||
{
|
||||
{"ADMOB_NETWORK", "android_23.3.0.1_ios_11.9.0.1"},
|
||||
{"BIDMACHINE_NETWORK", "android_3.0.1.1_ios_3.0.0.0.1"},
|
||||
{"CHARTBOOST_NETWORK", "android_9.7.0.3_ios_9.7.0.2"},
|
||||
{"FACEBOOK_MEDIATE", "android_6.17.0.1_ios_6.15.2.1"},
|
||||
{"FYBER_NETWORK", "android_8.3.1.1_ios_8.3.2.1"},
|
||||
{"GOOGLE_AD_MANAGER_NETWORK", "android_23.3.0.1_ios_11.9.0.1"},
|
||||
{"HYPRMX_NETWORK", "android_6.4.2.1_ios_6.4.1.0.1"},
|
||||
{"INMOBI_NETWORK", "android_10.7.7.1_ios_10.7.5.1"},
|
||||
{"IRONSOURCE_NETWORK", "android_8.3.0.0.2_ios_8.3.0.0.1"},
|
||||
{"LINE_NETWORK", "android_2024.8.27.1_ios_2.8.20240827.1"},
|
||||
{"MINTEGRAL_NETWORK", "android_16.8.51.1_ios_7.7.2.0.1"},
|
||||
{"MOBILEFUSE_NETWORK", "android_1.7.6.1_ios_1.7.6.1"},
|
||||
{"MOLOCO_NETWORK", "android_3.1.0.1_ios_3.1.3.1"},
|
||||
{"MYTARGET_NETWORK", "android_5.22.1.1_ios_5.21.7.1"},
|
||||
{"PUBMATIC_NETWORK", "android_3.9.0.2_ios_3.9.0.2"},
|
||||
{"SMAATO_NETWORK", "android_22.7.0.1_ios_22.8.4.1"},
|
||||
{"TIKTOK_NETWORK", "android_6.2.0.5.2_ios_6.2.0.7.2"},
|
||||
{"UNITY_NETWORK", "android_4.12.2.1_ios_4.12.2.1"},
|
||||
{"VERVE_NETWORK", "android_3.0.4.1_ios_3.0.4.1"},
|
||||
{"VUNGLE_NETWORK", "android_7.4.1.1_ios_7.4.1.1"},
|
||||
{"YANDEX_NETWORK", "android_7.4.0.1_ios_2.18.0.1"},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a new version of the plugin is available and prompts the user to update if one is available.
|
||||
/// </summary>
|
||||
public static void Update()
|
||||
{
|
||||
var now = (int) (DateTime.UtcNow - EpochTime).TotalSeconds;
|
||||
if (EditorPrefs.HasKey(KeyLastUpdateCheckTime))
|
||||
{
|
||||
var elapsedTime = now - EditorPrefs.GetInt(KeyLastUpdateCheckTime);
|
||||
|
||||
// Check if we have checked for a new version in the last 24 hrs and skip update if we have.
|
||||
if (elapsedTime < SecondsInADay) return;
|
||||
}
|
||||
|
||||
// Update last checked time.
|
||||
EditorPrefs.SetInt(KeyLastUpdateCheckTime, now);
|
||||
|
||||
// Load the plugin data
|
||||
AppLovinEditorCoroutine.StartCoroutine(AppLovinIntegrationManager.Instance.LoadPluginData(data =>
|
||||
{
|
||||
if (data == null) return;
|
||||
|
||||
ShowPluginUpdateDialogIfNeeded(data);
|
||||
ShowNetworkAdaptersUpdateDialogIfNeeded(data.MediatedNetworks);
|
||||
ShowGoogleNetworkAdaptersUpdateDialogIfNeeded(data.MediatedNetworks);
|
||||
}));
|
||||
}
|
||||
|
||||
private static void ShowPluginUpdateDialogIfNeeded(PluginData data)
|
||||
{
|
||||
// Check if publisher has disabled auto update.
|
||||
if (!EditorPrefs.GetBool(KeyAutoUpdateEnabled, true)) return;
|
||||
|
||||
// Check if the current and latest version are the same or if the publisher is on a newer version (on beta). If so, skip update.
|
||||
var comparison = data.AppLovinMax.CurrentToLatestVersionComparisonResult;
|
||||
if (comparison == MaxSdkUtils.VersionComparisonResult.Equal || comparison == MaxSdkUtils.VersionComparisonResult.Greater) return;
|
||||
|
||||
// A new version of the plugin is available. Show a dialog to the publisher.
|
||||
var option = EditorUtility.DisplayDialogComplex(
|
||||
"AppLovin MAX Plugin Update",
|
||||
"A new version of AppLovin MAX plugin is available for download. Update now?",
|
||||
"Download",
|
||||
"Not Now",
|
||||
"Don't Ask Again");
|
||||
|
||||
if (option == 0) // Download
|
||||
{
|
||||
MaxSdkLogger.UserDebug("Downloading plugin...");
|
||||
AppLovinEditorCoroutine.StartCoroutine(AppLovinIntegrationManager.Instance.DownloadPlugin(data.AppLovinMax));
|
||||
}
|
||||
else if (option == 1) // Not Now
|
||||
{
|
||||
// Do nothing
|
||||
MaxSdkLogger.UserDebug("Update postponed.");
|
||||
}
|
||||
else if (option == 2) // Don't Ask Again
|
||||
{
|
||||
MaxSdkLogger.UserDebug("Auto Update disabled. You can enable it again from the AppLovin Integration Manager");
|
||||
EditorPrefs.SetBool(KeyAutoUpdateEnabled, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ShowNetworkAdaptersUpdateDialogIfNeeded(Network[] networks)
|
||||
{
|
||||
var networksToUpdate = networks.Where(network => network.RequiresUpdate).ToList();
|
||||
|
||||
// If all networks are above the required version, do nothing.
|
||||
if (networksToUpdate.Count <= 0) return;
|
||||
|
||||
// We found a few adapters that are not compatible with the current SDK, show alert.
|
||||
var message = "The following network adapters are not compatible with the current version of AppLovin MAX Plugin:\n";
|
||||
foreach (var networkName in networksToUpdate)
|
||||
{
|
||||
message += "\n- ";
|
||||
message += networkName.DisplayName + " (Requires " + MinAdapterVersions[networkName.Name] + " or newer)";
|
||||
}
|
||||
|
||||
message += "\n\nPlease update them to the latest versions to avoid any issues.";
|
||||
|
||||
AppLovinIntegrationManager.ShowBuildFailureDialog(message);
|
||||
}
|
||||
|
||||
private static void ShowGoogleNetworkAdaptersUpdateDialogIfNeeded(Network[] networks)
|
||||
{
|
||||
// AdMob and GAM use the same SDKs so their adapters should use the same underlying SDK version.
|
||||
var googleNetwork = networks.FirstOrDefault(network => network.Name.Equals("ADMOB_NETWORK"));
|
||||
var googleAdManagerNetwork = networks.FirstOrDefault(network => network.Name.Equals("GOOGLE_AD_MANAGER_NETWORK"));
|
||||
|
||||
// If both AdMob and GAM are not integrated, do nothing.
|
||||
if (googleNetwork == null || string.IsNullOrEmpty(googleNetwork.CurrentVersions.Unity) ||
|
||||
googleAdManagerNetwork == null || string.IsNullOrEmpty(googleAdManagerNetwork.CurrentVersions.Unity)) return;
|
||||
|
||||
var isAndroidVersionCompatible = GoogleNetworkAdaptersCompatible(googleNetwork.CurrentVersions.Android, googleAdManagerNetwork.CurrentVersions.Android, "19.8.0.0");
|
||||
var isIosVersionCompatible = GoogleNetworkAdaptersCompatible(googleNetwork.CurrentVersions.Ios, googleAdManagerNetwork.CurrentVersions.Ios, "8.0.0.0");
|
||||
|
||||
if (isAndroidVersionCompatible && isIosVersionCompatible) return;
|
||||
|
||||
var message = "You may see unexpected errors if you use different versions of the AdMob and Google Ad Manager adapter SDKs. " +
|
||||
"AdMob and Google Ad Manager share the same SDKs.\n\n" +
|
||||
"You can be sure that you are using the same SDK for both if the first three numbers in each adapter version match.";
|
||||
|
||||
AppLovinIntegrationManager.ShowBuildFailureDialog(message);
|
||||
}
|
||||
|
||||
private static bool GoogleNetworkAdaptersCompatible(string googleVersion, string googleAdManagerVersion, string breakingVersion)
|
||||
{
|
||||
var googleResult = MaxSdkUtils.CompareVersions(googleVersion, breakingVersion);
|
||||
var googleAdManagerResult = MaxSdkUtils.CompareVersions(googleAdManagerVersion, breakingVersion);
|
||||
|
||||
// If one is less than the breaking version and the other is not, they are not compatible.
|
||||
if (googleResult == MaxSdkUtils.VersionComparisonResult.Lesser &&
|
||||
googleAdManagerResult != MaxSdkUtils.VersionComparisonResult.Lesser) return false;
|
||||
|
||||
if (googleAdManagerResult == MaxSdkUtils.VersionComparisonResult.Lesser &&
|
||||
googleResult != MaxSdkUtils.VersionComparisonResult.Lesser) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bcdd5226273242c5bd9ec79568202e6
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinAutoUpdater.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,94 @@
|
||||
//
|
||||
// AppLovinBuildPostProcessor.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 10/30/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_IOS || UNITY_IPHONE
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// A helper class to run command line tools.
|
||||
///
|
||||
/// TODO: Currently only supports shell (Linux). Add support for Windows machines.
|
||||
/// </summary>
|
||||
public static class AppLovinCommandLine
|
||||
{
|
||||
/// <summary>
|
||||
/// Result obtained by running a command line command.
|
||||
/// </summary>
|
||||
public class Result
|
||||
{
|
||||
/// <summary>
|
||||
/// Standard output stream from command line.
|
||||
/// </summary>
|
||||
public string StandardOutput;
|
||||
|
||||
/// <summary>
|
||||
/// Standard error stream from command line.
|
||||
/// </summary>
|
||||
public string StandardError;
|
||||
|
||||
/// <summary>
|
||||
/// Exit code returned from command line.
|
||||
/// </summary>
|
||||
public int ExitCode;
|
||||
|
||||
/// <summary>
|
||||
/// The description of the result that can be used for error logging.
|
||||
/// </summary>
|
||||
public string Message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a command line tool using the provided <see cref="toolPath"/> and <see cref="arguments"/>.
|
||||
/// </summary>
|
||||
/// <param name="toolPath">The tool path to run</param>
|
||||
/// <param name="arguments">The arguments to be passed to the command line tool</param>
|
||||
/// <param name="workingDirectory">The directory from which to run this command.</param>
|
||||
/// <returns></returns>
|
||||
public static Result Run(string toolPath, string arguments, string workingDirectory)
|
||||
{
|
||||
var stdoutFileName = Path.GetTempFileName();
|
||||
var stderrFileName = Path.GetTempFileName();
|
||||
|
||||
var process = new Process();
|
||||
process.StartInfo.UseShellExecute = true;
|
||||
process.StartInfo.CreateNoWindow = false;
|
||||
process.StartInfo.RedirectStandardInput = false;
|
||||
process.StartInfo.RedirectStandardOutput = false;
|
||||
process.StartInfo.RedirectStandardError = false;
|
||||
|
||||
process.StartInfo.WorkingDirectory = workingDirectory;
|
||||
process.StartInfo.FileName = "bash";
|
||||
process.StartInfo.Arguments = string.Format("-l -c '\"{0}\" {1} 1> {2} 2> {3}'", toolPath, arguments, stdoutFileName, stderrFileName);
|
||||
process.Start();
|
||||
|
||||
process.WaitForExit();
|
||||
|
||||
var stdout = File.ReadAllText(stdoutFileName);
|
||||
var stderr = File.ReadAllText(stderrFileName);
|
||||
|
||||
File.Delete(stdoutFileName);
|
||||
File.Delete(stderrFileName);
|
||||
|
||||
var result = new Result();
|
||||
result.StandardOutput = stdout;
|
||||
result.StandardError = stderr;
|
||||
result.ExitCode = process.ExitCode;
|
||||
|
||||
var messagePrefix = result.ExitCode == 0 ? "Command executed successfully" : "Failed to run command";
|
||||
result.Message = string.Format("{0}: '{1} {2}'\nstdout: {3}\nstderr: {4}\nExit code: {5}", messagePrefix, toolPath, arguments, stdout, stderr, process.ExitCode);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d0aa55f9a7d2440f871dfb256372a33
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinCommandLine.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,91 @@
|
||||
//
|
||||
// AppLovinEditorCoroutine.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 7/25/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// A coroutine that can update based on editor application update.
|
||||
/// </summary>
|
||||
public class AppLovinEditorCoroutine
|
||||
{
|
||||
/// <summary>
|
||||
/// Keeps track of the coroutine currently running.
|
||||
/// </summary>
|
||||
private IEnumerator enumerator;
|
||||
|
||||
/// <summary>
|
||||
/// Keeps track of coroutines that have yielded to the current enumerator.
|
||||
/// </summary>
|
||||
private readonly List<IEnumerator> history = new List<IEnumerator>();
|
||||
|
||||
private AppLovinEditorCoroutine(IEnumerator enumerator)
|
||||
{
|
||||
this.enumerator = enumerator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and starts a coroutine.
|
||||
/// </summary>
|
||||
/// <param name="enumerator">The coroutine to be started</param>
|
||||
/// <returns>The coroutine that has been started.</returns>
|
||||
public static AppLovinEditorCoroutine StartCoroutine(IEnumerator enumerator)
|
||||
{
|
||||
var coroutine = new AppLovinEditorCoroutine(enumerator);
|
||||
coroutine.Start();
|
||||
return coroutine;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
EditorApplication.update += OnEditorUpdate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the coroutine.
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (EditorApplication.update == null) return;
|
||||
|
||||
EditorApplication.update -= OnEditorUpdate;
|
||||
}
|
||||
|
||||
private void OnEditorUpdate()
|
||||
{
|
||||
if (enumerator.MoveNext())
|
||||
{
|
||||
// If there is a coroutine to yield for inside the coroutine, add the initial one to history and continue the second one
|
||||
if (enumerator.Current is IEnumerator)
|
||||
{
|
||||
history.Add(enumerator);
|
||||
enumerator = (IEnumerator) enumerator.Current;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Current coroutine has ended, check if we have more coroutines in history to be run.
|
||||
if (history.Count == 0)
|
||||
{
|
||||
// No more coroutines to run, stop updating.
|
||||
Stop();
|
||||
}
|
||||
// Step out and finish the code in the coroutine that yielded to it
|
||||
else
|
||||
{
|
||||
var index = history.Count - 1;
|
||||
enumerator = history[index];
|
||||
history.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95747c688378548eeb92aeb528ac96ff
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinEditorCoroutine.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,141 @@
|
||||
//
|
||||
// MaxInitialization.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Thomas So on 5/24/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public class AppLovinInitialize
|
||||
{
|
||||
private static readonly List<string> ObsoleteNetworks = new List<string>
|
||||
{
|
||||
"AdColony",
|
||||
"Criteo",
|
||||
"Nend",
|
||||
"Snap",
|
||||
"Tapjoy",
|
||||
"VerizonAds",
|
||||
"VoodooAds"
|
||||
};
|
||||
|
||||
private static readonly List<string> ObsoleteFileExportPathsToDelete = new List<string>
|
||||
{
|
||||
// The `MaxSdk/Scripts/Editor` folder contents have been moved into `MaxSdk/Scripts/IntegrationManager/Editor`.
|
||||
"MaxSdk/Scripts/Editor",
|
||||
"MaxSdk/Scripts/Editor.meta",
|
||||
|
||||
// The `EventSystemChecker` has been renamed to `MaxEventSystemChecker`.
|
||||
"MaxSdk/Scripts/EventSystemChecker.cs",
|
||||
"MaxSdk/Scripts/EventSystemChecker.cs.meta",
|
||||
|
||||
// Google AdMob adapter pre/post process scripts. The logic has been migrated to the main plugin.
|
||||
"MaxSdk/Mediation/Google/Editor/MaxGoogleInitialize.cs",
|
||||
"MaxSdk/Mediation/Google/Editor/MaxGoogleInitialize.cs.meta",
|
||||
"MaxSdk/Mediation/Google/Editor/MaxMediationGoogleUtils.cs",
|
||||
"MaxSdk/Mediation/Google/Editor/MaxMediationGoogleUtils.cs.meta",
|
||||
"MaxSdk/Mediation/Google/Editor/PostProcessor.cs",
|
||||
"MaxSdk/Mediation/Google/Editor/PostProcessor.cs.meta",
|
||||
"MaxSdk/Mediation/Google/Editor/PreProcessor.cs",
|
||||
"MaxSdk/Mediation/Google/Editor/PreProcessor.cs.meta",
|
||||
"MaxSdk/Mediation/Google/Editor/MaxSdk.Mediation.Google.Editor.asmdef",
|
||||
"MaxSdk/Mediation/Google/MaxSdk.Mediation.Google.Editor.asmdef.meta",
|
||||
"Plugins/Android/MaxMediationGoogle.androidlib",
|
||||
"Plugins/Android/MaxMediationGoogle.androidlib.meta",
|
||||
|
||||
// Google Ad Manager adapter pre/post process scripts. The logic has been migrated to the main plugin.
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/MaxGoogleAdManagerInitialize.cs",
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/MaxGoogleAdManagerInitialize.cs.meta",
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/PostProcessor.cs",
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/PostProcessor.cs.meta",
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/MaxSdk.Mediation.GoogleAdManager.Editor.asmdef",
|
||||
"MaxSdk/Mediation/GoogleAdManager/Editor/MaxSdk.Mediation.GoogleAdManager.Editor.asmdef.meta",
|
||||
"Plugins/Android/MaxMediationGoogleAdManager.androidlib",
|
||||
"Plugins/Android/MaxMediationGoogleAdManager.androidlib.meta",
|
||||
|
||||
// The `VariableService` has been removed.
|
||||
"MaxSdk/Scripts/MaxVariableServiceAndroid.cs",
|
||||
"MaxSdk/Scripts/MaxVariableServiceAndroid.cs.meta",
|
||||
"MaxSdk/Scripts/MaxVariableServiceiOS.cs",
|
||||
"MaxSdk/Scripts/MaxVariableServiceiOS.cs.meta",
|
||||
"MaxSdk/Scripts/MaxVariableServiceUnityEditor.cs",
|
||||
"MaxSdk/Scripts/MaxVariableServiceUnityEditor.cs.meta",
|
||||
|
||||
// The `MaxSdk/Scripts/Editor` folder contents have been moved into `MaxSdk/Scripts/IntegrationManager/Editor`.
|
||||
"MaxSdk/Version.md",
|
||||
"MaxSdk/Version.md.meta",
|
||||
|
||||
// The alert_icon.png has been renamed to error_icon.png.
|
||||
"MaxSdk/Resources/Images/alert_icon.png"
|
||||
|
||||
// TODO: Add MaxTargetingData and MaxUserSegment when the plugin has enough traction.
|
||||
};
|
||||
|
||||
static AppLovinInitialize()
|
||||
{
|
||||
// Don't run obsolete file cleanup logic when entering play mode.
|
||||
if (EditorApplication.isPlayingOrWillChangePlaymode) return;
|
||||
|
||||
#if UNITY_IOS
|
||||
// Check that the publisher is targeting iOS 9.0+
|
||||
if (!PlayerSettings.iOS.targetOSVersionString.StartsWith("9.") && !PlayerSettings.iOS.targetOSVersionString.StartsWith("1"))
|
||||
{
|
||||
MaxSdkLogger.UserError("Detected iOS project version less than iOS 9 - The AppLovin MAX SDK WILL NOT WORK ON < iOS9!!!");
|
||||
}
|
||||
#endif
|
||||
|
||||
var isPluginInPackageManager = AppLovinIntegrationManager.IsPluginInPackageManager;
|
||||
if (!isPluginInPackageManager)
|
||||
{
|
||||
var changesMade = false;
|
||||
foreach (var obsoleteFileExportPathToDelete in ObsoleteFileExportPathsToDelete)
|
||||
{
|
||||
var pathToDelete = MaxSdkUtils.GetAssetPathForExportPath(obsoleteFileExportPathToDelete);
|
||||
if (CheckExistence(pathToDelete))
|
||||
{
|
||||
MaxSdkLogger.UserDebug("Deleting obsolete file '" + pathToDelete + "' that is no longer needed.");
|
||||
FileUtil.DeleteFileOrDirectory(pathToDelete);
|
||||
changesMade = true;
|
||||
}
|
||||
}
|
||||
|
||||
var pluginParentDir = AppLovinIntegrationManager.PluginParentDirectory;
|
||||
// Check if any obsolete networks are installed
|
||||
foreach (var obsoleteNetwork in ObsoleteNetworks)
|
||||
{
|
||||
var networkDir = Path.Combine(pluginParentDir, "MaxSdk/Mediation/" + obsoleteNetwork);
|
||||
if (CheckExistence(networkDir))
|
||||
{
|
||||
MaxSdkLogger.UserDebug("Deleting obsolete network " + obsoleteNetwork + " from path " + networkDir + "...");
|
||||
FileUtil.DeleteFileOrDirectory(networkDir);
|
||||
FileUtil.DeleteFileOrDirectory(networkDir + ".meta");
|
||||
changesMade = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh UI
|
||||
if (changesMade)
|
||||
{
|
||||
AssetDatabase.Refresh();
|
||||
MaxSdkLogger.UserDebug("Obsolete networks and files removed.");
|
||||
}
|
||||
}
|
||||
|
||||
AppLovinAutoUpdater.Update();
|
||||
}
|
||||
|
||||
private static bool CheckExistence(string location)
|
||||
{
|
||||
return File.Exists(location) ||
|
||||
Directory.Exists(location) ||
|
||||
(location.EndsWith("/*") && Directory.Exists(Path.GetDirectoryName(location)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6b7dce7fe193a4058bc51d9f4d3a2aed
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinInitialize.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,514 @@
|
||||
//
|
||||
// MaxIntegrationManager.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 6/1/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using AppLovinMax.Internal;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class PluginData
|
||||
{
|
||||
// ReSharper disable InconsistentNaming - Consistent with JSON data.
|
||||
public Network AppLovinMax;
|
||||
public Network[] MediatedNetworks;
|
||||
public Network[] PartnerMicroSdks;
|
||||
public DynamicLibraryToEmbed[] ThirdPartyDynamicLibrariesToEmbed;
|
||||
public Alert[] Alerts;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Network
|
||||
{
|
||||
//
|
||||
// Sample network data:
|
||||
//
|
||||
// {
|
||||
// "Name": "adcolony",
|
||||
// "DisplayName": "AdColony",
|
||||
// "DownloadUrl": "https://bintray.com/applovin/Unity-Mediation-Packages/download_file?file_path=AppLovin-AdColony-Adapters-Android-3.3.10.1-iOS-3.3.7.2.unitypackage",
|
||||
// "PluginFileName": "AppLovin-AdColony-Adapters-Android-3.3.10.1-iOS-3.3.7.2.unitypackage",
|
||||
// "DependenciesFilePath": "MaxSdk/Mediation/AdColony/Editor/Dependencies.xml",
|
||||
// "LatestVersions" : {
|
||||
// "Unity": "android_3.3.10.1_ios_3.3.7.2",
|
||||
// "Android": "3.3.10.1",
|
||||
// "Ios": "3.3.7.2"
|
||||
// }
|
||||
// }
|
||||
//
|
||||
|
||||
// ReSharper disable InconsistentNaming - Consistent with JSON data.
|
||||
public string Name;
|
||||
public string DisplayName;
|
||||
public string DownloadUrl;
|
||||
public string DependenciesFilePath;
|
||||
public PackageInfo[] Packages;
|
||||
public string[] PluginFilePaths;
|
||||
public Versions LatestVersions;
|
||||
public DynamicLibraryToEmbed[] DynamicLibrariesToEmbed;
|
||||
|
||||
[NonSerialized] public Versions CurrentVersions;
|
||||
[NonSerialized] public MaxSdkUtils.VersionComparisonResult CurrentToLatestVersionComparisonResult = MaxSdkUtils.VersionComparisonResult.Lesser;
|
||||
[NonSerialized] public bool RequiresUpdate;
|
||||
[NonSerialized] public bool IsCurrentlyInstalling;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class DynamicLibraryToEmbed
|
||||
{
|
||||
// ReSharper disable InconsistentNaming - Consistent with JSON data.
|
||||
public string PodName;
|
||||
public string[] FrameworkNames;
|
||||
|
||||
// Min and max versions are inclusive, so if the adapter is the min or max version, the xcframework will get embedded.
|
||||
public string MinVersion;
|
||||
public string MaxVersion;
|
||||
|
||||
public DynamicLibraryToEmbed(string podName, string[] frameworkNames, string minVersion, string maxVersion)
|
||||
{
|
||||
PodName = podName;
|
||||
FrameworkNames = frameworkNames;
|
||||
MinVersion = minVersion;
|
||||
MaxVersion = maxVersion;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Severity
|
||||
{
|
||||
Info,
|
||||
Warning,
|
||||
Error
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Alert
|
||||
{
|
||||
public string SeverityType;
|
||||
public string Title;
|
||||
public string Message;
|
||||
public string Url;
|
||||
|
||||
public Severity Severity;
|
||||
|
||||
public void InitializeSeverityEnum()
|
||||
{
|
||||
switch (SeverityType)
|
||||
{
|
||||
case "INFO":
|
||||
Severity = Severity.Info;
|
||||
break;
|
||||
case "WARNING":
|
||||
Severity = Severity.Warning;
|
||||
break;
|
||||
case "ERROR":
|
||||
Severity = Severity.Error;
|
||||
break;
|
||||
default:
|
||||
MaxSdkLogger.E(string.Format("Alert <{0}> has unsupported severity type <{1}>.", Title, SeverityType));
|
||||
Severity = Severity.Info;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A helper data class used to get current versions from Dependency.xml files.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Versions
|
||||
{
|
||||
// ReSharper disable InconsistentNaming - Consistent with JSON data.
|
||||
public string Unity;
|
||||
public string Android;
|
||||
public string Ios;
|
||||
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
var versions = value as Versions;
|
||||
|
||||
return versions != null
|
||||
&& Unity.Equals(versions.Unity)
|
||||
&& (Android == null || Android.Equals(versions.Android))
|
||||
&& (Ios == null || Ios.Equals(versions.Ios));
|
||||
}
|
||||
|
||||
public bool HasEqualSdkVersions(Versions versions)
|
||||
{
|
||||
return versions != null
|
||||
&& AdapterSdkVersion(Android).Equals(AdapterSdkVersion(versions.Android))
|
||||
&& AdapterSdkVersion(Ios).Equals(AdapterSdkVersion(versions.Ios));
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return new {unity = Unity, android = Android, ios = Ios}.GetHashCode();
|
||||
}
|
||||
|
||||
private static string AdapterSdkVersion(string adapterVersion)
|
||||
{
|
||||
if (string.IsNullOrEmpty(adapterVersion)) return "";
|
||||
|
||||
var index = adapterVersion.LastIndexOf(".", StringComparison.Ordinal);
|
||||
return index > 0 ? adapterVersion.Substring(0, index) : adapterVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A manager class for MAX integration manager window.
|
||||
/// </summary>
|
||||
public class AppLovinIntegrationManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Delegate to be called when a plugin package's import is started.
|
||||
/// </summary>
|
||||
internal delegate void ImportPackageStartedCallback(Network network);
|
||||
|
||||
/// <summary>
|
||||
/// Delegate to be called when a plugin package is finished importing.
|
||||
/// </summary>
|
||||
/// <param name="network">The network data for which the package is imported.</param>
|
||||
internal delegate void ImportPackageCompletedCallback(Network network);
|
||||
|
||||
private static readonly AppLovinIntegrationManager instance = new AppLovinIntegrationManager();
|
||||
|
||||
internal static readonly string GradleTemplatePath = Path.Combine("Assets/Plugins/Android", "mainTemplate.gradle");
|
||||
private const string MaxSdkAssetExportPath = "MaxSdk/Scripts/MaxSdk.cs";
|
||||
private const string MaxSdkMediationExportPath = "MaxSdk/Mediation";
|
||||
|
||||
private const string PluginDataEndpoint = "https://unity.applovin.com/max/1.0/integration_manager_info?plugin_version={0}";
|
||||
|
||||
private static string externalDependencyManagerVersion;
|
||||
|
||||
internal static ImportPackageStartedCallback OnImportPackageStartedCallback;
|
||||
internal static ImportPackageCompletedCallback OnImportPackageCompletedCallback;
|
||||
|
||||
private MaxWebRequest maxWebRequest;
|
||||
private Network importingNetwork;
|
||||
|
||||
/// <summary>
|
||||
/// An Instance of the Integration manager.
|
||||
/// </summary>
|
||||
public static AppLovinIntegrationManager Instance
|
||||
{
|
||||
get { return instance; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The parent directory path where the MaxSdk plugin directory is placed.
|
||||
/// </summary>
|
||||
public static string PluginParentDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
// Search for the asset with the export path label.
|
||||
// Paths are normalized using AltDirectorySeparatorChar (/) to ensure compatibility across platforms (in case of migrating a project from Windows to Mac or vice versa).
|
||||
var maxSdkScriptAssetPath = MaxSdkUtils.GetAssetPathForExportPath(MaxSdkAssetExportPath);
|
||||
|
||||
// maxSdkScriptAssetPath will always have AltDirectorySeparatorChar (/) as the path separator. Convert to platform specific path.
|
||||
return maxSdkScriptAssetPath.Replace(MaxSdkAssetExportPath, "")
|
||||
.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
}
|
||||
}
|
||||
|
||||
public static string MediationDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
var mediationAssetPath = MaxSdkUtils.GetAssetPathForExportPath(MaxSdkMediationExportPath);
|
||||
return mediationAssetPath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the plugin is in the Unity Package Manager.
|
||||
/// </summary>
|
||||
public static bool IsPluginInPackageManager
|
||||
{
|
||||
get { return PluginParentDirectory.StartsWith("Packages"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not gradle build system is enabled.
|
||||
/// </summary>
|
||||
public static bool GradleBuildEnabled
|
||||
{
|
||||
get { return GetEditorUserBuildSetting("androidBuildSystem", "").ToString().Equals("Gradle"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not Gradle template is enabled.
|
||||
/// </summary>
|
||||
public static bool GradleTemplateEnabled
|
||||
{
|
||||
get { return GradleBuildEnabled && File.Exists(GradleTemplatePath); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the Quality Service settings can be processed which requires Gradle template enabled or Unity IDE newer than version 2018_2.
|
||||
/// </summary>
|
||||
public static bool CanProcessAndroidQualityServiceSettings
|
||||
{
|
||||
get { return GradleTemplateEnabled || GradleBuildEnabled; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The External Dependency Manager version obtained dynamically.
|
||||
/// </summary>
|
||||
public static string ExternalDependencyManagerVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (MaxSdkUtils.IsValidString(externalDependencyManagerVersion)) return externalDependencyManagerVersion;
|
||||
|
||||
try
|
||||
{
|
||||
var versionHandlerVersionNumberType = Type.GetType("Google.VersionHandlerVersionNumber, Google.VersionHandlerImpl");
|
||||
externalDependencyManagerVersion = versionHandlerVersionNumberType.GetProperty("Value").GetValue(null, null).ToString();
|
||||
}
|
||||
#pragma warning disable 0168
|
||||
catch (Exception ignored)
|
||||
#pragma warning restore 0168
|
||||
{
|
||||
externalDependencyManagerVersion = "Failed to get version.";
|
||||
}
|
||||
|
||||
return externalDependencyManagerVersion;
|
||||
}
|
||||
}
|
||||
|
||||
private AppLovinIntegrationManager()
|
||||
{
|
||||
AssetDatabase.importPackageStarted += packageName =>
|
||||
{
|
||||
if (!IsImportingNetwork(packageName)) return;
|
||||
|
||||
CallImportPackageStartedCallback(importingNetwork);
|
||||
};
|
||||
|
||||
// Add asset import callbacks.
|
||||
AssetDatabase.importPackageCompleted += packageName =>
|
||||
{
|
||||
if (!IsImportingNetwork(packageName)) return;
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
CallImportPackageCompletedCallback(importingNetwork);
|
||||
importingNetwork = null;
|
||||
};
|
||||
|
||||
AssetDatabase.importPackageCancelled += packageName =>
|
||||
{
|
||||
if (!IsImportingNetwork(packageName)) return;
|
||||
|
||||
importingNetwork = null;
|
||||
};
|
||||
|
||||
AssetDatabase.importPackageFailed += (packageName, errorMessage) =>
|
||||
{
|
||||
if (!IsImportingNetwork(packageName)) return;
|
||||
|
||||
MaxSdkLogger.UserError(errorMessage);
|
||||
importingNetwork = null;
|
||||
};
|
||||
}
|
||||
|
||||
static AppLovinIntegrationManager() { }
|
||||
|
||||
public static PluginData LoadPluginDataSync()
|
||||
{
|
||||
var url = string.Format(PluginDataEndpoint, MaxSdk.Version);
|
||||
var webRequestConfig = new WebRequestConfig()
|
||||
{
|
||||
EndPoint = url,
|
||||
};
|
||||
|
||||
var maxWebRequest = new MaxWebRequest(webRequestConfig);
|
||||
var webResponse = maxWebRequest.SendSync();
|
||||
|
||||
return CreatePluginDataFromWebResponse(webResponse);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the plugin data to be display by integration manager window.
|
||||
/// </summary>
|
||||
/// <param name="callback">Callback to be called once the plugin data download completes.</param>
|
||||
public IEnumerator LoadPluginData(Action<PluginData> callback)
|
||||
{
|
||||
var url = string.Format(PluginDataEndpoint, MaxSdk.Version);
|
||||
var webRequestConfig = new WebRequestConfig()
|
||||
{
|
||||
EndPoint = url,
|
||||
};
|
||||
|
||||
maxWebRequest = new MaxWebRequest(webRequestConfig);
|
||||
yield return maxWebRequest.Send(webResponse =>
|
||||
{
|
||||
var pluginData = CreatePluginDataFromWebResponse(webResponse);
|
||||
callback(pluginData);
|
||||
});
|
||||
}
|
||||
|
||||
private static PluginData CreatePluginDataFromWebResponse(WebResponse webResponse)
|
||||
{
|
||||
if (!webResponse.IsSuccess)
|
||||
{
|
||||
MaxSdkLogger.E("Failed to load plugin data. Please check your internet connection.");
|
||||
return null;
|
||||
}
|
||||
|
||||
PluginData pluginData;
|
||||
try
|
||||
{
|
||||
pluginData = JsonUtility.FromJson<PluginData>(webResponse.ResponseMessage);
|
||||
AppLovinPackageManager.PluginData = pluginData;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Console.WriteLine(exception);
|
||||
pluginData = null;
|
||||
}
|
||||
|
||||
if (pluginData == null) return null;
|
||||
|
||||
// Get current version of the plugin
|
||||
var appLovinMax = pluginData.AppLovinMax;
|
||||
AppLovinPackageManager.UpdateCurrentVersions(appLovinMax);
|
||||
|
||||
// Get current versions for all the mediation networks.
|
||||
foreach (var network in pluginData.MediatedNetworks)
|
||||
{
|
||||
AppLovinPackageManager.UpdateCurrentVersions(network);
|
||||
}
|
||||
|
||||
if (pluginData.PartnerMicroSdks != null)
|
||||
{
|
||||
foreach (var partnerMicroSdk in pluginData.PartnerMicroSdks)
|
||||
{
|
||||
AppLovinPackageManager.UpdateCurrentVersions(partnerMicroSdk);
|
||||
}
|
||||
}
|
||||
|
||||
if (pluginData.Alerts == null) return pluginData;
|
||||
|
||||
// Initiate Severity enums from the raw strings in the response
|
||||
foreach (var alert in pluginData.Alerts)
|
||||
{
|
||||
alert.InitializeSeverityEnum();
|
||||
}
|
||||
|
||||
return pluginData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Downloads the plugin file for a given network.
|
||||
/// </summary>
|
||||
/// <param name="network">Network for which to download the current version.</param>
|
||||
/// <param name="showImport">Whether or not to show the import window when downloading. Defaults to <c>true</c>.</param>
|
||||
/// <returns></returns>
|
||||
public IEnumerator DownloadPlugin(Network network, bool showImport = true)
|
||||
{
|
||||
var path = Path.Combine(Application.temporaryCachePath, GetPluginFileName(network)); // TODO: Maybe delete plugin file after finishing import.
|
||||
var webRequestConfig = new WebRequestConfig()
|
||||
{
|
||||
DownloadHandler = new DownloadHandlerFile(path),
|
||||
EndPoint = network.DownloadUrl
|
||||
};
|
||||
|
||||
maxWebRequest = new MaxWebRequest(webRequestConfig);
|
||||
yield return maxWebRequest.Send(webResponse =>
|
||||
{
|
||||
if (webResponse.IsSuccess)
|
||||
{
|
||||
importingNetwork = network;
|
||||
AssetDatabase.ImportPackage(path, showImport);
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to download plugin package: " + webResponse.ErrorMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancels the plugin download if one is in progress.
|
||||
/// </summary>
|
||||
public void CancelDownload()
|
||||
{
|
||||
if (maxWebRequest == null) return;
|
||||
|
||||
maxWebRequest.Abort();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows a dialog to the user with the given message and logs the error message to console.
|
||||
/// </summary>
|
||||
/// <param name="message">The failure message to be shown to the user.</param>
|
||||
public static void ShowBuildFailureDialog(string message)
|
||||
{
|
||||
var openIntegrationManager = EditorUtility.DisplayDialog("AppLovin MAX", message, "Open Integration Manager", "Dismiss");
|
||||
if (openIntegrationManager)
|
||||
{
|
||||
AppLovinIntegrationManagerWindow.ShowManager();
|
||||
}
|
||||
|
||||
MaxSdkLogger.UserError(message);
|
||||
}
|
||||
|
||||
#region Utility Methods
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether or not the given package name is the currently importing package.
|
||||
/// </summary>
|
||||
/// <param name="packageName">The name of the package that needs to be checked.</param>
|
||||
/// <returns>true if the importing package matches the given package name.</returns>
|
||||
private bool IsImportingNetwork(string packageName)
|
||||
{
|
||||
// Note: The pluginName doesn't have the '.unitypackage' extension included in its name but the pluginFileName does. So using Contains instead of Equals.
|
||||
return importingNetwork != null && GetPluginFileName(importingNetwork).Contains(packageName);
|
||||
}
|
||||
|
||||
private static void CallImportPackageStartedCallback(Network network)
|
||||
{
|
||||
if (OnImportPackageStartedCallback == null) return;
|
||||
|
||||
OnImportPackageStartedCallback(network);
|
||||
}
|
||||
|
||||
private static void CallImportPackageCompletedCallback(Network network)
|
||||
{
|
||||
if (OnImportPackageCompletedCallback == null) return;
|
||||
|
||||
OnImportPackageCompletedCallback(network);
|
||||
}
|
||||
|
||||
private static object GetEditorUserBuildSetting(string name, object defaultValue)
|
||||
{
|
||||
var editorUserBuildSettingsType = typeof(EditorUserBuildSettings);
|
||||
var property = editorUserBuildSettingsType.GetProperty(name);
|
||||
if (property != null)
|
||||
{
|
||||
var value = property.GetValue(null, null);
|
||||
if (value != null) return value;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static string GetPluginFileName(Network network)
|
||||
{
|
||||
return network.Name.ToLowerInvariant() + "_" + network.LatestVersions.Unity + ".unitypackage";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5b874c1e65274159bcc0dc15d9458cc
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManager.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
public static class AppLovinIntegrationManagerUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Compares AppLovin MAX Unity mediation adapter plugin versions. Returns <see cref="MaxSdkUtils.VersionComparisonResult.Lesser"/>, <see cref="MaxSdkUtils.VersionComparisonResult.Equal"/>,
|
||||
/// or <see cref="MaxSdkUtils.VersionComparisonResult.Greater"/> as the first version is less than, equal to, or greater than the second.
|
||||
///
|
||||
/// If a version for a specific platform is only present in one of the provided versions, the one that contains it is considered newer.
|
||||
/// </summary>
|
||||
/// <param name="versionA">The first version to be compared.</param>
|
||||
/// <param name="versionB">The second version to be compared.</param>
|
||||
/// <returns>
|
||||
/// <see cref="MaxSdkUtils.VersionComparisonResult.Lesser"/> if versionA is less than versionB.
|
||||
/// <see cref="MaxSdkUtils.VersionComparisonResult.Equal"/> if versionA and versionB are equal.
|
||||
/// <see cref="MaxSdkUtils.VersionComparisonResult.Greater"/> if versionA is greater than versionB.
|
||||
/// </returns>
|
||||
internal static MaxSdkUtils.VersionComparisonResult CompareUnityMediationVersions(string versionA, string versionB)
|
||||
{
|
||||
if (versionA.Equals(versionB)) return MaxSdkUtils.VersionComparisonResult.Equal;
|
||||
|
||||
// Unity version would be of format: android_w.x.y.z_ios_a.b.c.d
|
||||
// For Android only versions it would be: android_w.x.y.z
|
||||
// For iOS only version it would be: ios_a.b.c.d
|
||||
|
||||
// After splitting into their respective components, the versions would be at the odd indices.
|
||||
var versionAComponents = versionA.Split('_').ToList();
|
||||
var versionBComponents = versionB.Split('_').ToList();
|
||||
|
||||
var androidComparison = MaxSdkUtils.VersionComparisonResult.Equal;
|
||||
if (versionA.Contains("android") && versionB.Contains("android"))
|
||||
{
|
||||
var androidVersionA = versionAComponents[1];
|
||||
var androidVersionB = versionBComponents[1];
|
||||
androidComparison = MaxSdkUtils.CompareVersions(androidVersionA, androidVersionB);
|
||||
|
||||
// Remove the Android version component so that iOS versions can be processed.
|
||||
versionAComponents.RemoveRange(0, 2);
|
||||
versionBComponents.RemoveRange(0, 2);
|
||||
}
|
||||
else if (versionA.Contains("android"))
|
||||
{
|
||||
androidComparison = MaxSdkUtils.VersionComparisonResult.Greater;
|
||||
|
||||
// Remove the Android version component so that iOS versions can be processed.
|
||||
versionAComponents.RemoveRange(0, 2);
|
||||
}
|
||||
else if (versionB.Contains("android"))
|
||||
{
|
||||
androidComparison = MaxSdkUtils.VersionComparisonResult.Lesser;
|
||||
|
||||
// Remove the Android version component so that iOS version can be processed.
|
||||
versionBComponents.RemoveRange(0, 2);
|
||||
}
|
||||
|
||||
var iosComparison = MaxSdkUtils.VersionComparisonResult.Equal;
|
||||
if (versionA.Contains("ios") && versionB.Contains("ios"))
|
||||
{
|
||||
var iosVersionA = versionAComponents[1];
|
||||
var iosVersionB = versionBComponents[1];
|
||||
iosComparison = MaxSdkUtils.CompareVersions(iosVersionA, iosVersionB);
|
||||
}
|
||||
else if (versionA.Contains("ios"))
|
||||
{
|
||||
iosComparison = MaxSdkUtils.VersionComparisonResult.Greater;
|
||||
}
|
||||
else if (versionB.Contains("ios"))
|
||||
{
|
||||
iosComparison = MaxSdkUtils.VersionComparisonResult.Lesser;
|
||||
}
|
||||
|
||||
// If either one of the Android or iOS version is greater, the entire version should be greater.
|
||||
return (androidComparison == MaxSdkUtils.VersionComparisonResult.Greater || iosComparison == MaxSdkUtils.VersionComparisonResult.Greater) ? MaxSdkUtils.VersionComparisonResult.Greater : MaxSdkUtils.VersionComparisonResult.Lesser;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96efb4dba39eb48d2a60afab69786e6a
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManagerUtils.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84c61b4c05e114cec91df447d1b585f8
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinIntegrationManagerWindow.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,307 @@
|
||||
////
|
||||
//// AppLovinInternalSettings.cs
|
||||
//// AppLovin User Engagement Unity Plugin
|
||||
////
|
||||
//// Created by Santosh Bagadi on 9/15/22.
|
||||
//// Copyright © 2022 AppLovin. All rights reserved.
|
||||
////
|
||||
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.IO;
|
||||
//using UnityEngine;
|
||||
|
||||
//namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// A <see cref="ScriptableObject"/> representing the AppLovin internal settings that can be set in the Integration Manager Window.
|
||||
// ///
|
||||
// /// The scriptable object asset is saved under ProjectSettings as <c>AppLovinInternalSettings.json</c>.
|
||||
// /// </summary>
|
||||
// public class AppLovinInternalSettings : ScriptableObject
|
||||
// {
|
||||
// private static AppLovinInternalSettings instance;
|
||||
|
||||
// private const string DefaultUserTrackingDescriptionEn = "This uses device info for more personalized ads and content";
|
||||
// private const string DefaultUserTrackingDescriptionDe = "Dies benutzt Gerätinformationen für relevantere Werbeinhalte";
|
||||
// private const string DefaultUserTrackingDescriptionEs = "Esto utiliza la información del dispositivo para anuncios y contenido más personalizados";
|
||||
// private const string DefaultUserTrackingDescriptionFr = "Cela permet d'utiliser les informations du téléphone pour afficher des contenus publicitaires plus pertinents.";
|
||||
// private const string DefaultUserTrackingDescriptionJa = "これはユーザーデータをもとに、より関連性の高い広告コンテンツをお客様に提供します";
|
||||
// private const string DefaultUserTrackingDescriptionKo = "보다 개인화된 광고 및 콘텐츠를 위해 기기 정보를 사용합니다.";
|
||||
// private const string DefaultUserTrackingDescriptionZhHans = "我们使用设备信息来提供个性化的广告和内容。";
|
||||
// private const string DefaultUserTrackingDescriptionZhHant = "我們使用設備信息來提供個性化的廣告和內容。";
|
||||
|
||||
// [SerializeField] private bool consentFlowEnabled;
|
||||
// [SerializeField] private string consentFlowPrivacyPolicyUrl = string.Empty;
|
||||
// [SerializeField] private string consentFlowTermsOfServiceUrl = string.Empty;
|
||||
// [SerializeField] private bool shouldShowTermsAndPrivacyPolicyAlertInGDPR;
|
||||
// [SerializeField] private bool overrideDefaultUserTrackingUsageDescriptions;
|
||||
// [SerializeField] private MaxSdkBase.ConsentFlowUserGeography debugUserGeography;
|
||||
// [SerializeField] private string userTrackingUsageDescriptionEn = string.Empty;
|
||||
// [SerializeField] private bool userTrackingUsageLocalizationEnabled;
|
||||
// [SerializeField] private string userTrackingUsageDescriptionDe = string.Empty;
|
||||
// [SerializeField] private string userTrackingUsageDescriptionEs = string.Empty;
|
||||
// [SerializeField] private string userTrackingUsageDescriptionFr = string.Empty;
|
||||
// [SerializeField] private string userTrackingUsageDescriptionJa = string.Empty;
|
||||
// [SerializeField] private string userTrackingUsageDescriptionKo = string.Empty;
|
||||
// [SerializeField] private string userTrackingUsageDescriptionZhHans = string.Empty;
|
||||
// [SerializeField] private string userTrackingUsageDescriptionZhHant = string.Empty;
|
||||
|
||||
// private const string SettingsFilePath = "ProjectSettings/AppLovinInternalSettings.json";
|
||||
|
||||
// public static AppLovinInternalSettings Instance
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// if (instance != null) return instance;
|
||||
|
||||
// instance = CreateInstance<AppLovinInternalSettings>();
|
||||
|
||||
// var projectRootPath = Path.GetDirectoryName(Application.dataPath);
|
||||
// var settingsFilePath = Path.Combine(projectRootPath, SettingsFilePath);
|
||||
// if (!File.Exists(settingsFilePath))
|
||||
// {
|
||||
// instance.Save();
|
||||
// return instance;
|
||||
// }
|
||||
|
||||
// var settingsJson = File.ReadAllText(settingsFilePath);
|
||||
// if (string.IsNullOrEmpty(settingsJson))
|
||||
// {
|
||||
// instance.Save();
|
||||
// return instance;
|
||||
// }
|
||||
|
||||
// JsonUtility.FromJsonOverwrite(settingsJson, instance);
|
||||
// return instance;
|
||||
// }
|
||||
// }
|
||||
|
||||
// public void Save()
|
||||
// {
|
||||
// var settingsJson = JsonUtility.ToJson(instance);
|
||||
// try
|
||||
// {
|
||||
// var projectRootPath = Path.GetDirectoryName(Application.dataPath);
|
||||
// var settingsFilePath = Path.Combine(projectRootPath, SettingsFilePath);
|
||||
// File.WriteAllText(settingsFilePath, settingsJson);
|
||||
// }
|
||||
// catch (Exception exception)
|
||||
// {
|
||||
// MaxSdkLogger.UserError("Failed to save internal settings.");
|
||||
// Console.WriteLine(exception);
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Whether or not AppLovin Consent Flow is enabled.
|
||||
// /// </summary>
|
||||
// public bool ConsentFlowEnabled
|
||||
// {
|
||||
// get { return consentFlowEnabled; }
|
||||
// set
|
||||
// {
|
||||
// var previousValue = consentFlowEnabled;
|
||||
// consentFlowEnabled = value;
|
||||
|
||||
// if (value)
|
||||
// {
|
||||
// // If the value didn't change, we don't need to update anything.
|
||||
// if (previousValue) return;
|
||||
|
||||
// UserTrackingUsageDescriptionEn = DefaultUserTrackingDescriptionEn;
|
||||
// UserTrackingUsageLocalizationEnabled = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ConsentFlowPrivacyPolicyUrl = string.Empty;
|
||||
// ConsentFlowTermsOfServiceUrl = string.Empty;
|
||||
// UserTrackingUsageDescriptionEn = string.Empty;
|
||||
// UserTrackingUsageLocalizationEnabled = false;
|
||||
// OverrideDefaultUserTrackingUsageDescriptions = false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// A URL pointing to the Privacy Policy for the app to be shown when prompting the user for consent.
|
||||
// /// </summary>
|
||||
// public string ConsentFlowPrivacyPolicyUrl
|
||||
// {
|
||||
// get { return consentFlowPrivacyPolicyUrl; }
|
||||
// set { consentFlowPrivacyPolicyUrl = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// An optional URL pointing to the Terms of Service for the app to be shown when prompting the user for consent.
|
||||
// /// </summary>
|
||||
// public string ConsentFlowTermsOfServiceUrl
|
||||
// {
|
||||
// get { return consentFlowTermsOfServiceUrl; }
|
||||
// set { consentFlowTermsOfServiceUrl = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Whether or not to show the Terms and Privacy Policy alert in GDPR regions prior to presenting the CMP prompt.
|
||||
// /// </summary>
|
||||
// public bool ShouldShowTermsAndPrivacyPolicyAlertInGDPR
|
||||
// {
|
||||
// get { return shouldShowTermsAndPrivacyPolicyAlertInGDPR; }
|
||||
// set { shouldShowTermsAndPrivacyPolicyAlertInGDPR = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// A User Tracking Usage Description in English to be shown to users when requesting permission to use data for tracking.
|
||||
// /// For more information see <see href="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
// /// </summary>
|
||||
// public string UserTrackingUsageDescriptionEn
|
||||
// {
|
||||
// get { return userTrackingUsageDescriptionEn; }
|
||||
// set { userTrackingUsageDescriptionEn = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// An optional string to set debug user geography
|
||||
// /// </summary>
|
||||
// public MaxSdkBase.ConsentFlowUserGeography DebugUserGeography
|
||||
// {
|
||||
// get { return debugUserGeography; }
|
||||
// set { debugUserGeography = value; }
|
||||
// }
|
||||
|
||||
// public bool OverrideDefaultUserTrackingUsageDescriptions
|
||||
// {
|
||||
// get { return overrideDefaultUserTrackingUsageDescriptions; }
|
||||
// set
|
||||
// {
|
||||
// var previousValue = overrideDefaultUserTrackingUsageDescriptions;
|
||||
// overrideDefaultUserTrackingUsageDescriptions = value;
|
||||
|
||||
// if (!value)
|
||||
// {
|
||||
// if (!previousValue) return;
|
||||
|
||||
// UserTrackingUsageDescriptionEn = DefaultUserTrackingDescriptionEn;
|
||||
// UserTrackingUsageDescriptionDe = DefaultUserTrackingDescriptionDe;
|
||||
// UserTrackingUsageDescriptionEs = DefaultUserTrackingDescriptionEs;
|
||||
// UserTrackingUsageDescriptionFr = DefaultUserTrackingDescriptionFr;
|
||||
// UserTrackingUsageDescriptionJa = DefaultUserTrackingDescriptionJa;
|
||||
// UserTrackingUsageDescriptionKo = DefaultUserTrackingDescriptionKo;
|
||||
// UserTrackingUsageDescriptionZhHans = DefaultUserTrackingDescriptionZhHans;
|
||||
// UserTrackingUsageDescriptionZhHant = DefaultUserTrackingDescriptionZhHant;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Whether or not to localize User Tracking Usage Description.
|
||||
// /// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
// /// </summary>
|
||||
// public bool UserTrackingUsageLocalizationEnabled
|
||||
// {
|
||||
// get { return userTrackingUsageLocalizationEnabled; }
|
||||
// set
|
||||
// {
|
||||
// var previousValue = userTrackingUsageLocalizationEnabled;
|
||||
// userTrackingUsageLocalizationEnabled = value;
|
||||
|
||||
// if (value)
|
||||
// {
|
||||
// // If the value didn't change, don't do anything
|
||||
// if (previousValue) return;
|
||||
|
||||
// // Don't set the default values if they are being overriden.
|
||||
// if (OverrideDefaultUserTrackingUsageDescriptions) return;
|
||||
|
||||
// UserTrackingUsageDescriptionDe = DefaultUserTrackingDescriptionDe;
|
||||
// UserTrackingUsageDescriptionEs = DefaultUserTrackingDescriptionEs;
|
||||
// UserTrackingUsageDescriptionFr = DefaultUserTrackingDescriptionFr;
|
||||
// UserTrackingUsageDescriptionJa = DefaultUserTrackingDescriptionJa;
|
||||
// UserTrackingUsageDescriptionKo = DefaultUserTrackingDescriptionKo;
|
||||
// UserTrackingUsageDescriptionZhHans = DefaultUserTrackingDescriptionZhHans;
|
||||
// UserTrackingUsageDescriptionZhHant = DefaultUserTrackingDescriptionZhHant;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// UserTrackingUsageDescriptionDe = string.Empty;
|
||||
// UserTrackingUsageDescriptionEs = string.Empty;
|
||||
// UserTrackingUsageDescriptionFr = string.Empty;
|
||||
// UserTrackingUsageDescriptionJa = string.Empty;
|
||||
// UserTrackingUsageDescriptionKo = string.Empty;
|
||||
// UserTrackingUsageDescriptionZhHans = string.Empty;
|
||||
// UserTrackingUsageDescriptionZhHant = string.Empty;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// A User Tracking Usage Description in German to be shown to users when requesting permission to use data for tracking.
|
||||
// /// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
// /// </summary>
|
||||
// public string UserTrackingUsageDescriptionDe
|
||||
// {
|
||||
// get { return userTrackingUsageDescriptionDe; }
|
||||
// set { userTrackingUsageDescriptionDe = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// A User Tracking Usage Description in Spanish to be shown to users when requesting permission to use data for tracking.
|
||||
// /// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
// /// </summary>
|
||||
// public string UserTrackingUsageDescriptionEs
|
||||
// {
|
||||
// get { return userTrackingUsageDescriptionEs; }
|
||||
// set { userTrackingUsageDescriptionEs = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// A User Tracking Usage Description in French to be shown to users when requesting permission to use data for tracking.
|
||||
// /// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
// /// </summary>
|
||||
// public string UserTrackingUsageDescriptionFr
|
||||
// {
|
||||
// get { return userTrackingUsageDescriptionFr; }
|
||||
// set { userTrackingUsageDescriptionFr = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// A User Tracking Usage Description in Japanese to be shown to users when requesting permission to use data for tracking.
|
||||
// /// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
// /// </summary>
|
||||
// public string UserTrackingUsageDescriptionJa
|
||||
// {
|
||||
// get { return userTrackingUsageDescriptionJa; }
|
||||
// set { userTrackingUsageDescriptionJa = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// A User Tracking Usage Description in Korean to be shown to users when requesting permission to use data for tracking.
|
||||
// /// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
// /// </summary>
|
||||
// public string UserTrackingUsageDescriptionKo
|
||||
// {
|
||||
// get { return userTrackingUsageDescriptionKo; }
|
||||
// set { userTrackingUsageDescriptionKo = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// A User Tracking Usage Description in Chinese (Simplified) to be shown to users when requesting permission to use data for tracking.
|
||||
// /// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
// /// </summary>
|
||||
// public string UserTrackingUsageDescriptionZhHans
|
||||
// {
|
||||
// get { return userTrackingUsageDescriptionZhHans; }
|
||||
// set { userTrackingUsageDescriptionZhHans = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// A User Tracking Usage Description in Chinese (Traditional) to be shown to users when requesting permission to use data for tracking.
|
||||
// /// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
// /// </summary>
|
||||
// public string UserTrackingUsageDescriptionZhHant
|
||||
// {
|
||||
// get { return userTrackingUsageDescriptionZhHant; }
|
||||
// set { userTrackingUsageDescriptionZhHant = value; }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65c51e21887ae42c2839962fb9585e9f
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinInternalSettings.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,307 @@
|
||||
//
|
||||
// AppLovinInternalSettings.cs
|
||||
// AppLovin User Engagement Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 9/15/22.
|
||||
// Copyright © 2022 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="ScriptableObject"/> representing the AppLovin internal settings that can be set in the Integration Manager Window.
|
||||
///
|
||||
/// The scriptable object asset is saved under ProjectSettings as <c>AppLovinInternalSettings.json</c>.
|
||||
/// </summary>
|
||||
public class AppLovinInternalSettings : ScriptableObject
|
||||
{
|
||||
private static AppLovinInternalSettings instance;
|
||||
|
||||
private const string DefaultUserTrackingDescriptionEn = "This uses device info for more personalized ads and content";
|
||||
private const string DefaultUserTrackingDescriptionDe = "Dies benutzt Gerätinformationen für relevantere Werbeinhalte";
|
||||
private const string DefaultUserTrackingDescriptionEs = "Esto utiliza la información del dispositivo para anuncios y contenido más personalizados";
|
||||
private const string DefaultUserTrackingDescriptionFr = "Cela permet d'utiliser les informations du téléphone pour afficher des contenus publicitaires plus pertinents.";
|
||||
private const string DefaultUserTrackingDescriptionJa = "これはユーザーデータをもとに、より関連性の高い広告コンテンツをお客様に提供します";
|
||||
private const string DefaultUserTrackingDescriptionKo = "보다 개인화된 광고 및 콘텐츠를 위해 기기 정보를 사용합니다.";
|
||||
private const string DefaultUserTrackingDescriptionZhHans = "我们使用设备信息来提供个性化的广告和内容。";
|
||||
private const string DefaultUserTrackingDescriptionZhHant = "我們使用設備信息來提供個性化的廣告和內容。";
|
||||
|
||||
[SerializeField] private bool consentFlowEnabled;
|
||||
[SerializeField] private string consentFlowPrivacyPolicyUrl = string.Empty;
|
||||
[SerializeField] private string consentFlowTermsOfServiceUrl = string.Empty;
|
||||
[SerializeField] private bool shouldShowTermsAndPrivacyPolicyAlertInGDPR;
|
||||
[SerializeField] private bool overrideDefaultUserTrackingUsageDescriptions;
|
||||
[SerializeField] private MaxSdkBase.ConsentFlowUserGeography debugUserGeography;
|
||||
[SerializeField] private string userTrackingUsageDescriptionEn = string.Empty;
|
||||
[SerializeField] private bool userTrackingUsageLocalizationEnabled;
|
||||
[SerializeField] private string userTrackingUsageDescriptionDe = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionEs = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionFr = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionJa = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionKo = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionZhHans = string.Empty;
|
||||
[SerializeField] private string userTrackingUsageDescriptionZhHant = string.Empty;
|
||||
|
||||
private const string SettingsFilePath = "ProjectSettings/Packages/com.bywaystudios.applovin/AppLovinInternalSettings.json";
|
||||
|
||||
public static AppLovinInternalSettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance != null) return instance;
|
||||
|
||||
instance = CreateInstance<AppLovinInternalSettings>();
|
||||
|
||||
var projectRootPath = Path.GetDirectoryName(Application.dataPath);
|
||||
var settingsFilePath = Path.Combine(projectRootPath, SettingsFilePath);
|
||||
if (!File.Exists(settingsFilePath))
|
||||
{
|
||||
instance.Save();
|
||||
return instance;
|
||||
}
|
||||
|
||||
var settingsJson = File.ReadAllText(settingsFilePath);
|
||||
if (string.IsNullOrEmpty(settingsJson))
|
||||
{
|
||||
instance.Save();
|
||||
return instance;
|
||||
}
|
||||
|
||||
JsonUtility.FromJsonOverwrite(settingsJson, instance);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
var settingsJson = JsonUtility.ToJson(instance);
|
||||
try
|
||||
{
|
||||
var projectRootPath = Path.GetDirectoryName(Application.dataPath);
|
||||
var settingsFilePath = Path.Combine(projectRootPath, SettingsFilePath);
|
||||
File.WriteAllText(settingsFilePath, settingsJson);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to save internal settings.");
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not AppLovin Consent Flow is enabled.
|
||||
/// </summary>
|
||||
public bool ConsentFlowEnabled
|
||||
{
|
||||
get { return consentFlowEnabled; }
|
||||
set
|
||||
{
|
||||
var previousValue = consentFlowEnabled;
|
||||
consentFlowEnabled = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
// If the value didn't change, we don't need to update anything.
|
||||
if (previousValue) return;
|
||||
|
||||
UserTrackingUsageDescriptionEn = DefaultUserTrackingDescriptionEn;
|
||||
UserTrackingUsageLocalizationEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsentFlowPrivacyPolicyUrl = string.Empty;
|
||||
ConsentFlowTermsOfServiceUrl = string.Empty;
|
||||
UserTrackingUsageDescriptionEn = string.Empty;
|
||||
UserTrackingUsageLocalizationEnabled = false;
|
||||
OverrideDefaultUserTrackingUsageDescriptions = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A URL pointing to the Privacy Policy for the app to be shown when prompting the user for consent.
|
||||
/// </summary>
|
||||
public string ConsentFlowPrivacyPolicyUrl
|
||||
{
|
||||
get { return consentFlowPrivacyPolicyUrl; }
|
||||
set { consentFlowPrivacyPolicyUrl = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional URL pointing to the Terms of Service for the app to be shown when prompting the user for consent.
|
||||
/// </summary>
|
||||
public string ConsentFlowTermsOfServiceUrl
|
||||
{
|
||||
get { return consentFlowTermsOfServiceUrl; }
|
||||
set { consentFlowTermsOfServiceUrl = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to show the Terms and Privacy Policy alert in GDPR regions prior to presenting the CMP prompt.
|
||||
/// </summary>
|
||||
public bool ShouldShowTermsAndPrivacyPolicyAlertInGDPR
|
||||
{
|
||||
get { return shouldShowTermsAndPrivacyPolicyAlertInGDPR; }
|
||||
set { shouldShowTermsAndPrivacyPolicyAlertInGDPR = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in English to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see <see href="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionEn
|
||||
{
|
||||
get { return userTrackingUsageDescriptionEn; }
|
||||
set { userTrackingUsageDescriptionEn = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional string to set debug user geography
|
||||
/// </summary>
|
||||
public MaxSdkBase.ConsentFlowUserGeography DebugUserGeography
|
||||
{
|
||||
get { return debugUserGeography; }
|
||||
set { debugUserGeography = value; }
|
||||
}
|
||||
|
||||
public bool OverrideDefaultUserTrackingUsageDescriptions
|
||||
{
|
||||
get { return overrideDefaultUserTrackingUsageDescriptions; }
|
||||
set
|
||||
{
|
||||
var previousValue = overrideDefaultUserTrackingUsageDescriptions;
|
||||
overrideDefaultUserTrackingUsageDescriptions = value;
|
||||
|
||||
if (!value)
|
||||
{
|
||||
if (!previousValue) return;
|
||||
|
||||
UserTrackingUsageDescriptionEn = DefaultUserTrackingDescriptionEn;
|
||||
UserTrackingUsageDescriptionDe = DefaultUserTrackingDescriptionDe;
|
||||
UserTrackingUsageDescriptionEs = DefaultUserTrackingDescriptionEs;
|
||||
UserTrackingUsageDescriptionFr = DefaultUserTrackingDescriptionFr;
|
||||
UserTrackingUsageDescriptionJa = DefaultUserTrackingDescriptionJa;
|
||||
UserTrackingUsageDescriptionKo = DefaultUserTrackingDescriptionKo;
|
||||
UserTrackingUsageDescriptionZhHans = DefaultUserTrackingDescriptionZhHans;
|
||||
UserTrackingUsageDescriptionZhHant = DefaultUserTrackingDescriptionZhHant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to localize User Tracking Usage Description.
|
||||
/// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
/// </summary>
|
||||
public bool UserTrackingUsageLocalizationEnabled
|
||||
{
|
||||
get { return userTrackingUsageLocalizationEnabled; }
|
||||
set
|
||||
{
|
||||
var previousValue = userTrackingUsageLocalizationEnabled;
|
||||
userTrackingUsageLocalizationEnabled = value;
|
||||
|
||||
if (value)
|
||||
{
|
||||
// If the value didn't change, don't do anything
|
||||
if (previousValue) return;
|
||||
|
||||
// Don't set the default values if they are being overriden.
|
||||
if (OverrideDefaultUserTrackingUsageDescriptions) return;
|
||||
|
||||
UserTrackingUsageDescriptionDe = DefaultUserTrackingDescriptionDe;
|
||||
UserTrackingUsageDescriptionEs = DefaultUserTrackingDescriptionEs;
|
||||
UserTrackingUsageDescriptionFr = DefaultUserTrackingDescriptionFr;
|
||||
UserTrackingUsageDescriptionJa = DefaultUserTrackingDescriptionJa;
|
||||
UserTrackingUsageDescriptionKo = DefaultUserTrackingDescriptionKo;
|
||||
UserTrackingUsageDescriptionZhHans = DefaultUserTrackingDescriptionZhHans;
|
||||
UserTrackingUsageDescriptionZhHant = DefaultUserTrackingDescriptionZhHant;
|
||||
}
|
||||
else
|
||||
{
|
||||
UserTrackingUsageDescriptionDe = string.Empty;
|
||||
UserTrackingUsageDescriptionEs = string.Empty;
|
||||
UserTrackingUsageDescriptionFr = string.Empty;
|
||||
UserTrackingUsageDescriptionJa = string.Empty;
|
||||
UserTrackingUsageDescriptionKo = string.Empty;
|
||||
UserTrackingUsageDescriptionZhHans = string.Empty;
|
||||
UserTrackingUsageDescriptionZhHant = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in German to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionDe
|
||||
{
|
||||
get { return userTrackingUsageDescriptionDe; }
|
||||
set { userTrackingUsageDescriptionDe = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Spanish to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionEs
|
||||
{
|
||||
get { return userTrackingUsageDescriptionEs; }
|
||||
set { userTrackingUsageDescriptionEs = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in French to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionFr
|
||||
{
|
||||
get { return userTrackingUsageDescriptionFr; }
|
||||
set { userTrackingUsageDescriptionFr = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Japanese to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionJa
|
||||
{
|
||||
get { return userTrackingUsageDescriptionJa; }
|
||||
set { userTrackingUsageDescriptionJa = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Korean to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionKo
|
||||
{
|
||||
get { return userTrackingUsageDescriptionKo; }
|
||||
set { userTrackingUsageDescriptionKo = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Chinese (Simplified) to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionZhHans
|
||||
{
|
||||
get { return userTrackingUsageDescriptionZhHans; }
|
||||
set { userTrackingUsageDescriptionZhHans = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A User Tracking Usage Description in Chinese (Traditional) to be shown to users when requesting permission to use data for tracking.
|
||||
/// For more information see Apple's documentation: https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription
|
||||
/// </summary>
|
||||
public string UserTrackingUsageDescriptionZhHant
|
||||
{
|
||||
get { return userTrackingUsageDescriptionZhHant; }
|
||||
set { userTrackingUsageDescriptionZhHant = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4cd80248f891d8d43a9edcc0bbb95c2d
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinInternalSettings.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,60 @@
|
||||
//
|
||||
// MaxMenuItems.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 5/27/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
public static class AppLovinMenuItems
|
||||
{
|
||||
/**
|
||||
* The special characters at the end represent a shortcut for this action.
|
||||
*
|
||||
* % - ctrl on Windows, cmd on macOS
|
||||
* # - shift
|
||||
* & - alt
|
||||
*
|
||||
* So, (shift + cmd/ctrl + i) will launch the integration manager
|
||||
*/
|
||||
[MenuItem("AppLovin/Integration Manager %#i")]
|
||||
private static void IntegrationManager()
|
||||
{
|
||||
ShowIntegrationManager();
|
||||
}
|
||||
|
||||
[MenuItem("AppLovin/Documentation")]
|
||||
private static void Documentation()
|
||||
{
|
||||
Application.OpenURL("https://support.axon.ai/en/max/unity/overview/integration");
|
||||
}
|
||||
|
||||
[MenuItem("AppLovin/Contact Us")]
|
||||
private static void ContactUs()
|
||||
{
|
||||
Application.OpenURL("https://www.applovin.com/contact/");
|
||||
}
|
||||
|
||||
[MenuItem("AppLovin/About")]
|
||||
private static void About()
|
||||
{
|
||||
Application.OpenURL("https://www.applovin.com/about/");
|
||||
}
|
||||
|
||||
[MenuItem("Assets/AppLovin Integration Manager")]
|
||||
private static void AssetsIntegrationManager()
|
||||
{
|
||||
ShowIntegrationManager();
|
||||
}
|
||||
|
||||
private static void ShowIntegrationManager()
|
||||
{
|
||||
AppLovinIntegrationManagerWindow.ShowManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02c2d277874f649d18a59d382420bf65
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinMenuItems.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,611 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
#if !UNITY_2020_1_OR_NEWER
|
||||
using System.Reflection;
|
||||
#endif
|
||||
using System.Xml.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditor.PackageManager;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class PackageInfo
|
||||
{
|
||||
// ReSharper disable InconsistentNaming - For JSON Deserialization
|
||||
public string Name;
|
||||
public string Version;
|
||||
}
|
||||
|
||||
public interface IPackageManagerClient
|
||||
{
|
||||
IEnumerator AddNetwork(Network network, bool showImport);
|
||||
void RemoveNetwork(Network network);
|
||||
}
|
||||
|
||||
public static class AppLovinPackageManager
|
||||
{
|
||||
private const string AppLovinMediationAmazonAdapterDependenciesPath = "Amazon/Scripts/Mediations/AppLovinMediation/Editor/Dependencies.xml";
|
||||
|
||||
private static readonly IPackageManagerClient _upmPackageManager = new AppLovinUpmPackageManager();
|
||||
private static readonly IPackageManagerClient _assetsPackageManager = new AppLovinAssetsPackageManager();
|
||||
|
||||
private static IPackageManagerClient PackageManagerClient
|
||||
{
|
||||
get
|
||||
{
|
||||
return AppLovinIntegrationManager.IsPluginInPackageManager ? _upmPackageManager : _assetsPackageManager;
|
||||
}
|
||||
}
|
||||
|
||||
internal static PluginData PluginData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether or not an adapter with the given version or newer exists.
|
||||
/// </summary>
|
||||
/// <param name="adapterName">The name of the network (the root adapter folder name in "MaxSdk/Mediation/" folder.</param>
|
||||
/// <param name="iosVersion">The min iOS adapter version to check for. Can be <c>null</c> if we want to check for any version.</param>
|
||||
/// <param name="androidVersion">The min android adapter version to check for. Can be <c>null</c> if we want to check for any version.</param>
|
||||
/// <returns><c>true</c> if an adapter with the min version is installed.</returns>
|
||||
internal static bool IsAdapterInstalled(string adapterName, string iosVersion = null, string androidVersion = null)
|
||||
{
|
||||
var dependencyFilePathList = GetAssetPathListForExportPath("MaxSdk/Mediation/" + adapterName + "/Editor/Dependencies.xml");
|
||||
if (dependencyFilePathList.Count <= 0) return false;
|
||||
|
||||
var currentVersion = GetCurrentVersions(dependencyFilePathList);
|
||||
if (iosVersion != null)
|
||||
{
|
||||
var iosVersionComparison = MaxSdkUtils.CompareVersions(currentVersion.Ios, iosVersion);
|
||||
if (iosVersionComparison == MaxSdkUtils.VersionComparisonResult.Lesser)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (androidVersion != null)
|
||||
{
|
||||
var androidVersionComparison = MaxSdkUtils.CompareVersions(currentVersion.Android, androidVersion);
|
||||
if (androidVersionComparison == MaxSdkUtils.VersionComparisonResult.Lesser)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether an adapter is installed using the plugin data.
|
||||
/// </summary>
|
||||
/// <param name="pluginData">The plugin data to check for the adapter</param>
|
||||
/// <param name="adapterName">The name of the network.</param>
|
||||
/// <returns>Whether an adapter is installed in the plugin data</returns>
|
||||
internal static bool IsAdapterInstalled(PluginData pluginData, string adapterName)
|
||||
{
|
||||
var network = pluginData.MediatedNetworks.Where(mediatedNetwork => mediatedNetwork.Name.Equals(adapterName)).ToList().FirstOrDefault();
|
||||
var networkVersion = network != null ? network.CurrentVersions : null;
|
||||
var currentVersion = networkVersion != null ? networkVersion.Unity : "";
|
||||
|
||||
return MaxSdkUtils.IsValidString(currentVersion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mediation networks that are currently installed in the project. If using UPM, checks
|
||||
/// for networks in Packages folder and Mediation folder in case a custom adapter was added to the project.
|
||||
/// </summary>
|
||||
/// <returns>A list of the installed mediation network names.</returns>
|
||||
internal static List<string> GetInstalledMediationNetworks()
|
||||
{
|
||||
var installedNetworks = new List<string>();
|
||||
var installedNetworksInAssets = AppLovinAssetsPackageManager.GetInstalledMediationNetworks();
|
||||
installedNetworks.AddRange(installedNetworksInAssets);
|
||||
|
||||
var installedNetworksInPackages = AppLovinUpmPackageManager.GetInstalledMediationNetworks();
|
||||
installedNetworks.AddRange(installedNetworksInPackages);
|
||||
|
||||
if (IsAmazonAppLovinAdapterInstalled())
|
||||
{
|
||||
installedNetworks.Add("AmazonAdMarketplace");
|
||||
}
|
||||
|
||||
return installedNetworks;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a network to the project.
|
||||
/// </summary>
|
||||
/// <param name="network">The network to add.</param>
|
||||
/// <param name="showImport">Whether to show the import window (only for non UPM)</param>
|
||||
internal static IEnumerator AddNetwork(Network network, bool showImport)
|
||||
{
|
||||
yield return PackageManagerClient.AddNetwork(network, showImport);
|
||||
|
||||
AppLovinEditorCoroutine.StartCoroutine(RefreshAssetsAtEndOfFrame(network));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a network from the project.
|
||||
/// </summary>
|
||||
/// <param name="network">The network to remove.</param>
|
||||
internal static void RemoveNetwork(Network network)
|
||||
{
|
||||
PackageManagerClient.RemoveNetwork(network);
|
||||
|
||||
AppLovinEditorCoroutine.StartCoroutine(RefreshAssetsAtEndOfFrame(network));
|
||||
}
|
||||
|
||||
#region Utility
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of all asset paths for a given MAX plugin export path.
|
||||
/// </summary>
|
||||
/// <param name="exportPath">The actual exported path of the asset.</param>
|
||||
/// <returns>The exported path of the MAX plugin asset or an empty list if the asset is not found.</returns>
|
||||
private static List<string> GetAssetPathListForExportPath(string exportPath)
|
||||
{
|
||||
var assetLabelToFind = "l:al_max_export_path-" + MaxSdkUtils.NormalizeToUnityPath(exportPath);
|
||||
var assetGuids = AssetDatabase.FindAssets(assetLabelToFind);
|
||||
|
||||
var assetPaths = new List<string>();
|
||||
foreach (var assetGuid in assetGuids)
|
||||
{
|
||||
assetPaths.Add(AssetDatabase.GUIDToAssetPath(assetGuid));
|
||||
}
|
||||
|
||||
return assetPaths.Count <= 0 ? new List<string>() : assetPaths;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the CurrentVersion fields for a given network data object.
|
||||
/// </summary>
|
||||
/// <param name="network">Network for which to update the current versions.</param>
|
||||
internal static void UpdateCurrentVersions(Network network)
|
||||
{
|
||||
var assetPaths = GetAssetPathListForExportPath(network.DependenciesFilePath);
|
||||
if (HasDuplicateAdapters(assetPaths))
|
||||
{
|
||||
ShowDeleteDuplicateAdapterPrompt(network);
|
||||
}
|
||||
|
||||
var currentVersions = GetCurrentVersions(assetPaths);
|
||||
network.CurrentVersions = currentVersions;
|
||||
|
||||
// If AppLovin mediation plugin, get the version from MaxSdk and the latest and current version comparison.
|
||||
if (network.Name.Equals("APPLOVIN_NETWORK"))
|
||||
{
|
||||
network.CurrentVersions.Unity = MaxSdk.Version;
|
||||
|
||||
var unityVersionComparison = MaxSdkUtils.CompareVersions(network.CurrentVersions.Unity, network.LatestVersions.Unity);
|
||||
var androidVersionComparison = MaxSdkUtils.CompareVersions(network.CurrentVersions.Android, network.LatestVersions.Android);
|
||||
var iosVersionComparison = MaxSdkUtils.CompareVersions(network.CurrentVersions.Ios, network.LatestVersions.Ios);
|
||||
|
||||
// Overall version is same if all the current and latest (from db) versions are same.
|
||||
if (unityVersionComparison == MaxSdkUtils.VersionComparisonResult.Equal &&
|
||||
androidVersionComparison == MaxSdkUtils.VersionComparisonResult.Equal &&
|
||||
iosVersionComparison == MaxSdkUtils.VersionComparisonResult.Equal)
|
||||
{
|
||||
network.CurrentToLatestVersionComparisonResult = MaxSdkUtils.VersionComparisonResult.Equal;
|
||||
}
|
||||
// One of the installed versions is newer than the latest versions which means that the publisher is on a beta version.
|
||||
else if (unityVersionComparison == MaxSdkUtils.VersionComparisonResult.Greater ||
|
||||
androidVersionComparison == MaxSdkUtils.VersionComparisonResult.Greater ||
|
||||
iosVersionComparison == MaxSdkUtils.VersionComparisonResult.Greater)
|
||||
{
|
||||
network.CurrentToLatestVersionComparisonResult = MaxSdkUtils.VersionComparisonResult.Greater;
|
||||
}
|
||||
// We have a new version available if all Android, iOS and Unity has a newer version available in db.
|
||||
else
|
||||
{
|
||||
network.CurrentToLatestVersionComparisonResult = MaxSdkUtils.VersionComparisonResult.Lesser;
|
||||
}
|
||||
}
|
||||
// For all other mediation adapters, get the version comparison using their Unity versions.
|
||||
else
|
||||
{
|
||||
// If adapter is indeed installed, compare the current (installed) and the latest (from db) versions, so that we can determine if the publisher is on an older, current or a newer version of the adapter.
|
||||
// If the publisher is on a newer version of the adapter than the db version, that means they are on a beta version.
|
||||
if (MaxSdkUtils.IsValidString(currentVersions.Unity))
|
||||
{
|
||||
network.CurrentToLatestVersionComparisonResult = AppLovinIntegrationManagerUtils.CompareUnityMediationVersions(currentVersions.Unity, network.LatestVersions.Unity);
|
||||
}
|
||||
|
||||
if (MaxSdkUtils.IsValidString(network.CurrentVersions.Unity) && AppLovinAutoUpdater.MinAdapterVersions.ContainsKey(network.Name))
|
||||
{
|
||||
var comparisonResult = AppLovinIntegrationManagerUtils.CompareUnityMediationVersions(network.CurrentVersions.Unity, AppLovinAutoUpdater.MinAdapterVersions[network.Name]);
|
||||
// Requires update if current version is lower than the min required version.
|
||||
network.RequiresUpdate = comparisonResult < 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset value so that the Integration manager can hide the alert icon once adapter is updated.
|
||||
network.RequiresUpdate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a network has duplicate adapters installed in both the Assets folder and via UPM.
|
||||
/// </summary>
|
||||
/// <param name="dependencyPaths">The list of paths to the dependencies.xml files</param>
|
||||
/// <returns><c>True</c> if there are adapters in both the Assets folder and installed via UPM</returns>
|
||||
private static bool HasDuplicateAdapters(List<string> dependencyPaths)
|
||||
{
|
||||
var inPackagesFolder = dependencyPaths.Any(path => path.Contains("Packages"));
|
||||
var inAssetsFolder = dependencyPaths.Any(path => path.Contains("Assets"));
|
||||
|
||||
return inPackagesFolder && inAssetsFolder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays a prompt informing the user that duplicate adapters were detected
|
||||
/// and allows them to choose which version to keep.
|
||||
/// </summary>
|
||||
/// <param name="network">The network that has duplicate adapters installed.</param>
|
||||
private static void ShowDeleteDuplicateAdapterPrompt(Network network)
|
||||
{
|
||||
var keepAssetsAdapter = EditorUtility.DisplayDialog("Duplicate Adapters Detected",
|
||||
"The " + network.DisplayName + " adapter is installed in both the Assets folder and via UPM. Please choose which version to keep.",
|
||||
"Keep Assets Folder Version",
|
||||
"Keep UPM Version");
|
||||
DeleteDuplicateAdapter(network, keepAssetsAdapter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a duplicate adapter by either deleting it from the Assets folder
|
||||
/// or uninstalling it from the Unity Package Manager (UPM).
|
||||
/// </summary>
|
||||
/// <param name="network">The network for which the duplicate adapter is being removed.</param>
|
||||
/// <param name="keepAssetsAdapter">If <c>true</c>, retains the adapter in the Assets folder and removes the UPM version;
|
||||
/// otherwise, deletes the adapter from the Assets folder.</param>
|
||||
internal static void DeleteDuplicateAdapter(Network network, bool keepAssetsAdapter)
|
||||
{
|
||||
if (keepAssetsAdapter)
|
||||
{
|
||||
var appLovinManifest = AppLovinUpmManifest.Load();
|
||||
AppLovinUpmPackageManager.RemovePackages(network, appLovinManifest);
|
||||
appLovinManifest.Save();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var pluginFilePath in network.PluginFilePaths)
|
||||
{
|
||||
var filePath = Path.Combine(AppLovinIntegrationManager.MediationDirectory, pluginFilePath.Replace("MaxSdk/Mediation/", ""));
|
||||
FileUtil.DeleteFileOrDirectory(filePath);
|
||||
FileUtil.DeleteFileOrDirectory(filePath + ".meta");
|
||||
}
|
||||
}
|
||||
|
||||
AppLovinUpmPackageManager.ResolvePackageManager();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current versions for a given network's dependency file paths. UPM will have multiple paths
|
||||
/// for each network - one each for iOS and Android.
|
||||
/// </summary>
|
||||
/// <param name="dependencyPaths">A list of dependency file paths to extract current versions from.</param>
|
||||
/// <returns>Current versions of a given network's dependency files.</returns>
|
||||
private static Versions GetCurrentVersions(List<string> dependencyPaths)
|
||||
{
|
||||
var currentVersions = new Versions();
|
||||
foreach (var dependencyPath in dependencyPaths)
|
||||
{
|
||||
GetCurrentVersion(currentVersions, dependencyPath);
|
||||
}
|
||||
|
||||
if (currentVersions.Android != null && currentVersions.Ios != null)
|
||||
{
|
||||
currentVersions.Unity = "android_" + currentVersions.Android + "_ios_" + currentVersions.Ios;
|
||||
}
|
||||
else if (currentVersions.Android != null)
|
||||
{
|
||||
currentVersions.Unity = "android_" + currentVersions.Android;
|
||||
}
|
||||
else if (currentVersions.Ios != null)
|
||||
{
|
||||
currentVersions.Unity = "ios_" + currentVersions.Ios;
|
||||
}
|
||||
|
||||
return currentVersions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts the current version of a network from its dependency.xml file.
|
||||
/// </summary>
|
||||
/// <param name="currentVersions">The Versions object we are using.</param>
|
||||
/// <param name="dependencyPath">The path to the dependency.xml file.</param>
|
||||
private static void GetCurrentVersion(Versions currentVersions, string dependencyPath)
|
||||
{
|
||||
XDocument dependency;
|
||||
try
|
||||
{
|
||||
dependency = XDocument.Load(dependencyPath);
|
||||
}
|
||||
#pragma warning disable 0168
|
||||
catch (IOException exception)
|
||||
#pragma warning restore 0168
|
||||
{
|
||||
// Couldn't find the dependencies file. The plugin is not installed.
|
||||
return;
|
||||
}
|
||||
|
||||
// <dependencies>
|
||||
// <androidPackages>
|
||||
// <androidPackage spec="com.applovin.mediation:network_name-adapter:1.2.3.4" />
|
||||
// </androidPackages>
|
||||
// <iosPods>
|
||||
// <iosPod name="AppLovinMediationNetworkNameAdapter" version="2.3.4.5" />
|
||||
// </iosPods>
|
||||
// </dependencies>
|
||||
string androidVersion = null;
|
||||
string iosVersion = null;
|
||||
var dependenciesElement = dependency.Element("dependencies");
|
||||
if (dependenciesElement != null)
|
||||
{
|
||||
var androidPackages = dependenciesElement.Element("androidPackages");
|
||||
if (androidPackages != null)
|
||||
{
|
||||
var adapterPackage = androidPackages.Descendants().FirstOrDefault(element => element.Name.LocalName.Equals("androidPackage")
|
||||
&& element.FirstAttribute.Name.LocalName.Equals("spec")
|
||||
&& element.FirstAttribute.Value.StartsWith("com.applovin"));
|
||||
if (adapterPackage != null)
|
||||
{
|
||||
androidVersion = adapterPackage.FirstAttribute.Value.Split(':').Last();
|
||||
// Hack alert: Some Android versions might have square brackets to force a specific version. Remove them if they are detected.
|
||||
if (androidVersion.StartsWith("["))
|
||||
{
|
||||
androidVersion = androidVersion.Trim('[', ']');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var iosPods = dependenciesElement.Element("iosPods");
|
||||
if (iosPods != null)
|
||||
{
|
||||
var adapterPod = iosPods.Descendants().FirstOrDefault(element => element.Name.LocalName.Equals("iosPod")
|
||||
&& element.FirstAttribute.Name.LocalName.Equals("name")
|
||||
&& element.FirstAttribute.Value.StartsWith("AppLovin"));
|
||||
if (adapterPod != null)
|
||||
{
|
||||
iosVersion = adapterPod.Attributes().First(attribute => attribute.Name.LocalName.Equals("version")).Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (androidVersion != null)
|
||||
{
|
||||
currentVersions.Android = androidVersion;
|
||||
}
|
||||
|
||||
if (iosVersion != null)
|
||||
{
|
||||
currentVersions.Ios = iosVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check for the Amazon AppLovin adapter in the project.
|
||||
/// </summary>
|
||||
/// <returns>Whether the AppLovin Adapter is installed through the Amazon SDK.</returns>
|
||||
private static bool IsAmazonAppLovinAdapterInstalled()
|
||||
{
|
||||
string[] dependenciesFiles = AssetDatabase.FindAssets("t:TextAsset Dependencies", new[] {"Assets"})
|
||||
.Select(AssetDatabase.GUIDToAssetPath)
|
||||
.ToArray();
|
||||
|
||||
// Use regex to search for Amazon and then AppLovin in the file paths of the dependencies.xml files.
|
||||
return dependenciesFiles.Any(filePath => filePath.Contains(AppLovinMediationAmazonAdapterDependenciesPath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh assets and update current versions after a slight delay to allow for Client.Resolve to finish.
|
||||
/// </summary>
|
||||
/// <param name="network">The network that was just installed/removed.</param>
|
||||
private static IEnumerator RefreshAssetsAtEndOfFrame(Network network)
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
UpdateCurrentVersions(network);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class AppLovinUpmPackageManager : IPackageManagerClient
|
||||
{
|
||||
public const string PackageNamePrefixAppLovin = "com.applovin.mediation.ads";
|
||||
private const string PackageNamePrefixNetwork = "com.applovin.mediation.adapters";
|
||||
private const string PackageNamePrefixDsp = "com.applovin.mediation.dsp";
|
||||
|
||||
private const float TimeoutFetchPackageCollectionSeconds = 10f;
|
||||
|
||||
#if !UNITY_2020_1_OR_NEWER
|
||||
private static Type packageManagerClientType;
|
||||
private static MethodInfo packageManagerResolveMethod;
|
||||
#endif
|
||||
|
||||
public static List<string> GetInstalledMediationNetworks()
|
||||
{
|
||||
// Return empty list if we failed to get the package list
|
||||
var packageCollection = GetPackageCollectionSync(TimeoutFetchPackageCollectionSeconds);
|
||||
if (packageCollection == null)
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
return packageCollection.Where(package => package.name.StartsWith(PackageNamePrefixNetwork) || package.name.StartsWith(PackageNamePrefixDsp))
|
||||
.SelectMany(package => package.keywords)
|
||||
.Where(keyword => keyword.StartsWith("dir:"))
|
||||
.Select(keyword => keyword.Replace("dir:", ""))
|
||||
.Distinct()
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public IEnumerator AddNetwork(Network network, bool showImport)
|
||||
{
|
||||
var appLovinManifest = AppLovinUpmManifest.Load();
|
||||
AddPackages(network, appLovinManifest);
|
||||
appLovinManifest.Save();
|
||||
|
||||
// Remove any versions of the adapter in the Assets folder
|
||||
AppLovinPackageManager.DeleteDuplicateAdapter(network, false);
|
||||
ResolvePackageManager();
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
public void RemoveNetwork(Network network)
|
||||
{
|
||||
var appLovinManifest = AppLovinUpmManifest.Load();
|
||||
RemovePackages(network, appLovinManifest);
|
||||
appLovinManifest.Save();
|
||||
ResolvePackageManager();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a network's packages to the package manager removes any beta version that exists
|
||||
/// </summary>
|
||||
/// <param name="network">The network to add.</param>
|
||||
/// <param name="appLovinManifest">The AppLovinUpmManifest instance to edit</param>
|
||||
internal static void AddPackages(Network network, AppLovinUpmManifest appLovinManifest)
|
||||
{
|
||||
foreach (var packageInfo in network.Packages)
|
||||
{
|
||||
appLovinManifest.AddPackageDependency(packageInfo.Name, packageInfo.Version);
|
||||
RemoveBetaPackage(packageInfo.Name, appLovinManifest);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a network's packages from the package manager
|
||||
/// </summary>
|
||||
/// <param name="network">The network to add.</param>
|
||||
/// <param name="appLovinManifest">The AppLovinUpmManifest instance to edit</param>
|
||||
internal static void RemovePackages(Network network, AppLovinUpmManifest appLovinManifest)
|
||||
{
|
||||
foreach (var packageInfo in network.Packages)
|
||||
{
|
||||
appLovinManifest.RemovePackageDependency(packageInfo.Name);
|
||||
RemoveBetaPackage(packageInfo.Name, appLovinManifest);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the beta version of a package name
|
||||
/// </summary>
|
||||
/// <param name="packageName">The name of the package to remove a beta for</param>
|
||||
/// <param name="appLovinManifest">The AppLovinUpmManifest instance to edit</param>
|
||||
private static void RemoveBetaPackage(string packageName, AppLovinUpmManifest appLovinManifest)
|
||||
{
|
||||
var prefix = "";
|
||||
if (packageName.Contains(PackageNamePrefixNetwork))
|
||||
{
|
||||
prefix = PackageNamePrefixNetwork;
|
||||
}
|
||||
else if (packageName.Contains(PackageNamePrefixDsp))
|
||||
{
|
||||
prefix = PackageNamePrefixDsp;
|
||||
}
|
||||
else if (packageName.Contains(PackageNamePrefixAppLovin))
|
||||
{
|
||||
prefix = PackageNamePrefixAppLovin;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var betaPackageName = packageName.Replace(prefix, prefix + ".beta");
|
||||
appLovinManifest.RemovePackageDependency(betaPackageName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the Unity Package Manager so any changes made to the manifest.json file are reflected in the Unity Editor.
|
||||
/// </summary>
|
||||
internal static void ResolvePackageManager()
|
||||
{
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
Client.Resolve();
|
||||
#else
|
||||
packageManagerClientType = packageManagerClientType ?? typeof(Client);
|
||||
if (packageManagerClientType != null)
|
||||
{
|
||||
packageManagerResolveMethod = packageManagerResolveMethod ?? packageManagerClientType.GetMethod("Resolve", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
}
|
||||
|
||||
if (packageManagerResolveMethod != null)
|
||||
{
|
||||
packageManagerResolveMethod.Invoke(null, null);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the PackageCollection from the Unity Package Manager synchronously.
|
||||
/// </summary>
|
||||
/// <param name="timeoutSeconds">How long to wait before exiting with a timeout error</param>
|
||||
/// <returns></returns>
|
||||
private static PackageCollection GetPackageCollectionSync(float timeoutSeconds = -1)
|
||||
{
|
||||
var request = Client.List();
|
||||
|
||||
// Just wait till the request is complete
|
||||
var now = DateTime.Now;
|
||||
while (!request.IsCompleted)
|
||||
{
|
||||
// Wait indefinitely if there is no timeout set.
|
||||
if (timeoutSeconds < 0) continue;
|
||||
|
||||
var delta = DateTime.Now - now;
|
||||
if (delta.TotalSeconds > timeoutSeconds)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to list UPM packages: Timeout");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!request.IsCompleted)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (request.Status >= StatusCode.Failure)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to list packages: " + request.Error.message);
|
||||
return null;
|
||||
}
|
||||
|
||||
return (request.Status == StatusCode.Success) ? request.Result : null;
|
||||
}
|
||||
}
|
||||
|
||||
public class AppLovinAssetsPackageManager : IPackageManagerClient
|
||||
{
|
||||
public static List<string> GetInstalledMediationNetworks()
|
||||
{
|
||||
var maxMediationDirectory = AppLovinIntegrationManager.MediationDirectory;
|
||||
if (!Directory.Exists(maxMediationDirectory)) return new List<string>();
|
||||
|
||||
var mediationNetworkDirectories = Directory.GetDirectories(maxMediationDirectory);
|
||||
return mediationNetworkDirectories.Select(Path.GetFileName).ToList();
|
||||
}
|
||||
|
||||
public IEnumerator AddNetwork(Network network, bool showImport)
|
||||
{
|
||||
yield return AppLovinIntegrationManager.Instance.DownloadPlugin(network, showImport);
|
||||
}
|
||||
|
||||
public void RemoveNetwork(Network network)
|
||||
{
|
||||
foreach (var pluginFilePath in network.PluginFilePaths)
|
||||
{
|
||||
var filePath = Path.Combine(AppLovinIntegrationManager.PluginParentDirectory, pluginFilePath);
|
||||
FileUtil.DeleteFileOrDirectory(filePath);
|
||||
FileUtil.DeleteFileOrDirectory(filePath + ".meta");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69faa9dfd9aac483daa24261a3e11206
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPackageManager.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,166 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Moves our SDK Unity Plugin from under the Assets folder to the Unity Package Manager.
|
||||
/// </summary>
|
||||
public static class AppLovinPluginMigrationHelper
|
||||
{
|
||||
private const string ApplovinRegistryName = "AppLovin MAX Unity";
|
||||
private const string ApplovinRegistryUrl = "https://unity.packages.applovin.com/";
|
||||
private static readonly List<string> AppLovinRegistryScopes = new List<string>() {"com.applovin.mediation.ads", "com.applovin.mediation.adapters", "com.applovin.mediation.dsp"};
|
||||
|
||||
private const string OpenUpmRegistryName = "package.openupm.com";
|
||||
private const string OpenUpmRegistryUrl = "https://package.openupm.com";
|
||||
private static readonly List<string> OpenUpmRegistryScopes = new List<string>() {"com.google.external-dependency-manager"};
|
||||
|
||||
private static List<string> betaNetworkPluginFilePaths = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to move the Unity plugin to UPM by adding the AppLovin scoped registry and dependencies to the manifest.
|
||||
/// </summary>
|
||||
/// <param name="pluginData">The Unity Plugin data for our sdk and mediation adapters.</param>
|
||||
/// <param name="deleteExternalDependencyManager">Whether to delete the EDM folder under "Assets"</param>
|
||||
internal static void MigrateToUnityPackageManager(PluginData pluginData, bool deleteExternalDependencyManager)
|
||||
{
|
||||
MaxSdkLogger.UserDebug("Moving AppLovin Unity Plugin to package manager");
|
||||
|
||||
if (deleteExternalDependencyManager)
|
||||
{
|
||||
DeleteExternalDependencyManager();
|
||||
}
|
||||
|
||||
var appLovinManifest = AppLovinUpmManifest.Load();
|
||||
|
||||
MigrateAdapters(pluginData, appLovinManifest);
|
||||
MigratePlugin(pluginData, appLovinManifest);
|
||||
|
||||
appLovinManifest.Save();
|
||||
AppLovinUpmPackageManager.ResolvePackageManager();
|
||||
DeletePluginFiles();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add all currently installed networks to the manifest.
|
||||
/// </summary>
|
||||
internal static void MigrateAdapters(PluginData pluginData, AppLovinUpmManifest appLovinManifest)
|
||||
{
|
||||
var allNetworks = pluginData.MediatedNetworks.Concat(pluginData.PartnerMicroSdks).ToArray();
|
||||
betaNetworkPluginFilePaths.Clear();
|
||||
|
||||
// Add every currently installed network and separate it by android and iOS.
|
||||
foreach (var network in allNetworks)
|
||||
{
|
||||
var currentVersion = network.CurrentVersions != null ? network.CurrentVersions.Unity : "";
|
||||
if (string.IsNullOrEmpty(currentVersion)) continue;
|
||||
|
||||
if (currentVersion.Contains("beta"))
|
||||
{
|
||||
betaNetworkPluginFilePaths.AddRange(network.PluginFilePaths);
|
||||
continue;
|
||||
}
|
||||
|
||||
AppLovinUpmPackageManager.AddPackages(network, appLovinManifest);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add the AppLovin scoped registry to the manifest if it doesn't exist. Otherwise update it.
|
||||
/// </summary>
|
||||
private static void MigratePlugin(PluginData pluginData, AppLovinUpmManifest appLovinManifest)
|
||||
{
|
||||
appLovinManifest.AddOrUpdateRegistry(ApplovinRegistryName, ApplovinRegistryUrl, AppLovinRegistryScopes);
|
||||
appLovinManifest.AddOrUpdateRegistry(OpenUpmRegistryName, OpenUpmRegistryUrl, OpenUpmRegistryScopes);
|
||||
|
||||
var appLovinVersion = pluginData.AppLovinMax.LatestVersions.Unity;
|
||||
appLovinManifest.AddPackageDependency(AppLovinUpmPackageManager.PackageNamePrefixAppLovin, appLovinVersion);
|
||||
}
|
||||
|
||||
#region Utility
|
||||
|
||||
/// <summary>
|
||||
/// Delete the external dependency manager folder from the project.
|
||||
/// </summary>
|
||||
private static void DeleteExternalDependencyManager()
|
||||
{
|
||||
var externalDependencyManagerPath = Path.Combine(Application.dataPath, "ExternalDependencyManager");
|
||||
FileUtil.DeleteFileOrDirectory(externalDependencyManagerPath);
|
||||
FileUtil.DeleteFileOrDirectory(externalDependencyManagerPath + ".meta");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes all the files in the plugin directory except the AppLovinSettings.asset file.
|
||||
/// </summary>
|
||||
private static void DeletePluginFiles()
|
||||
{
|
||||
if (AppLovinIntegrationManager.IsPluginInPackageManager) return;
|
||||
|
||||
var pluginPath = Path.Combine(AppLovinIntegrationManager.PluginParentDirectory, "MaxSdk");
|
||||
var appLovinSettingsPath = Path.Combine(pluginPath, "Resources/AppLovinSettings.asset");
|
||||
|
||||
var appLovinResourcesDirectory = Path.Combine(pluginPath, "Resources");
|
||||
var appLovinSettingsTempPath = Path.Combine(Path.GetTempPath(), "AppLovinSettings.asset");
|
||||
var appLovinMediationTempPath = Path.Combine(Path.GetTempPath(), "Mediation");
|
||||
|
||||
// Ensure there aren't any errors when moving the files due to the directories/files already existing.
|
||||
FileUtil.DeleteFileOrDirectory(appLovinSettingsTempPath);
|
||||
FileUtil.DeleteFileOrDirectory(appLovinMediationTempPath);
|
||||
|
||||
var mediationAssetsDir = Path.Combine(AppLovinIntegrationManager.PluginParentDirectory, "MaxSdk/Mediation");
|
||||
|
||||
// Move the AppLovinSettings.asset file and any beta adapters to a temporary directory.
|
||||
File.Move(appLovinSettingsPath, appLovinSettingsTempPath);
|
||||
var adapterSaved = MoveBetaAdaptersIfNeeded(mediationAssetsDir, appLovinMediationTempPath);
|
||||
|
||||
// Move the meta file if the adapter was saved to save the asset labels
|
||||
if (adapterSaved)
|
||||
{
|
||||
File.Move(mediationAssetsDir, appLovinMediationTempPath + ".meta");
|
||||
}
|
||||
|
||||
// Delete the plugin directory and then move the AppLovinSettings.asset and beta adapters back.
|
||||
FileUtil.DeleteFileOrDirectory(pluginPath);
|
||||
Directory.CreateDirectory(appLovinResourcesDirectory);
|
||||
File.Move(appLovinSettingsTempPath, appLovinSettingsPath);
|
||||
MoveBetaAdaptersIfNeeded(appLovinMediationTempPath, mediationAssetsDir);
|
||||
if (adapterSaved)
|
||||
{
|
||||
File.Move(appLovinMediationTempPath + ".meta", mediationAssetsDir);
|
||||
}
|
||||
|
||||
FileUtil.DeleteFileOrDirectory(appLovinMediationTempPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves the beta adapters from a source mediation directory to a destination mediation directory.
|
||||
/// </summary>
|
||||
/// <param name="sourceMediationDirectory">The directory containing the beta adapters to be moved.</param>
|
||||
/// <param name="destinationMediationDirectory">The target directory where the beta adapters should be moved.</param>
|
||||
private static bool MoveBetaAdaptersIfNeeded(string sourceMediationDirectory, string destinationMediationDirectory)
|
||||
{
|
||||
if (betaNetworkPluginFilePaths.Count == 0 || !Directory.Exists(sourceMediationDirectory)) return false;
|
||||
|
||||
var movedAdapter = false;
|
||||
Directory.CreateDirectory(destinationMediationDirectory);
|
||||
foreach (var pluginFilePath in betaNetworkPluginFilePaths)
|
||||
{
|
||||
var sourceDirectory = Path.Combine(sourceMediationDirectory, Path.GetFileName(pluginFilePath));
|
||||
var destinationDirectory = Path.Combine(destinationMediationDirectory, Path.GetFileName(pluginFilePath));
|
||||
if (Directory.Exists(sourceDirectory))
|
||||
{
|
||||
Directory.Move(sourceDirectory, destinationDirectory);
|
||||
movedAdapter = true;
|
||||
}
|
||||
}
|
||||
|
||||
return movedAdapter;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11288612632de49b99708cdee436692c
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPluginMigrationHelper.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,482 @@
|
||||
//
|
||||
// MaxPostProcessBuildAndroid.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 4/10/20.
|
||||
// Copyright © 2020 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_ANDROID
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml.Linq;
|
||||
using AppLovinMax.ThirdParty.MiniJson;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Android;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// A post processor used to update the Android project once it is generated.
|
||||
/// </summary>
|
||||
public class AppLovinPostProcessAndroid : IPostGenerateGradleAndroidProject
|
||||
{
|
||||
private const string PropertyAndroidX = "android.useAndroidX";
|
||||
private const string PropertyJetifier = "android.enableJetifier";
|
||||
private const string EnableProperty = "=true";
|
||||
private const string PropertyDexingArtifactTransform = "android.enableDexingArtifactTransform";
|
||||
private const string DisableProperty = "=false";
|
||||
|
||||
private const string KeyMetaDataAppLovinVerboseLoggingOn = "applovin.sdk.verbose_logging";
|
||||
private const string KeyMetaDataGoogleApplicationId = "com.google.android.gms.ads.APPLICATION_ID";
|
||||
private const string KeyMetaDataGoogleOptimizeInitialization = "com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION";
|
||||
private const string KeyMetaDataGoogleOptimizeAdLoading = "com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING";
|
||||
|
||||
private const string KeyMetaDataMobileFuseAutoInit = "com.mobilefuse.sdk.disable_auto_init";
|
||||
private const string KeyMetaDataMyTargetAutoInit = "com.my.target.autoInitMode";
|
||||
|
||||
private const string KeyMetaDataAppLovinSdkKey = "applovin.sdk.key";
|
||||
|
||||
private const string AppLovinSettingsFileName = "applovin_settings.json";
|
||||
|
||||
private const string KeySdkKey = "sdk_key";
|
||||
private const string KeyConsentFlowSettings = "consent_flow_settings";
|
||||
private const string KeyConsentFlowEnabled = "consent_flow_enabled";
|
||||
private const string KeyConsentFlowTermsOfService = "consent_flow_terms_of_service";
|
||||
private const string KeyConsentFlowPrivacyPolicy = "consent_flow_privacy_policy";
|
||||
private const string KeyConsentFlowShowTermsAndPrivacyPolicyAlertInGDPR = "consent_flow_show_terms_and_privacy_policy_alert_in_gdpr";
|
||||
private const string KeyConsentFlowDebugUserGeography = "consent_flow_debug_user_geography";
|
||||
|
||||
private const string KeyRenderOutsideSafeArea = "render_outside_safe_area";
|
||||
|
||||
#if UNITY_2022_3_OR_NEWER
|
||||
// To match "'com.android.library' version '7.3.1'" line in build.gradle
|
||||
private static readonly Regex TokenGradleVersionLibrary = new Regex(".*id ['\"]com\\.android\\.library['\"] version");
|
||||
private static readonly Regex TokenGradleVersion = new Regex(".*id ['\"]com\\.android\\.application['\"] version");
|
||||
#else
|
||||
// To match "classpath 'com.android.tools.build:gradle:4.0.1'" line in build.gradle
|
||||
private static readonly Regex TokenGradleVersion = new Regex(".*classpath ['\"]com\\.android\\.tools\\.build:gradle:.*");
|
||||
#endif
|
||||
|
||||
// To match "distributionUrl=..." in gradle-wrapper.properties file
|
||||
private static readonly Regex TokenDistributionUrl = new Regex(".*distributionUrl.*");
|
||||
|
||||
private static readonly XNamespace AndroidNamespace = "http://schemas.android.com/apk/res/android";
|
||||
|
||||
public void OnPostGenerateGradleAndroidProject(string path)
|
||||
{
|
||||
var rootGradleBuildFilePath = Path.Combine(path, "../build.gradle");
|
||||
var gradlePropertiesPath = Path.Combine(path, "../gradle.properties");
|
||||
var gradleWrapperPropertiesPath = Path.Combine(path, "../gradle/wrapper/gradle-wrapper.properties");
|
||||
|
||||
UpdateGradleVersionsIfNeeded(gradleWrapperPropertiesPath, rootGradleBuildFilePath);
|
||||
|
||||
var gradlePropertiesUpdated = new List<string>();
|
||||
|
||||
// If the gradle properties file already exists, make sure to add any previous properties.
|
||||
if (File.Exists(gradlePropertiesPath))
|
||||
{
|
||||
var lines = File.ReadAllLines(gradlePropertiesPath);
|
||||
|
||||
// Add all properties except AndroidX, Jetifier, and DexingArtifactTransform since they may already exist. We will re-add them below.
|
||||
gradlePropertiesUpdated.AddRange(lines.Where(line => !line.Contains(PropertyAndroidX) && !line.Contains(PropertyJetifier) && !line.Contains(PropertyDexingArtifactTransform)));
|
||||
}
|
||||
|
||||
// Enable AndroidX and Jetifier properties
|
||||
gradlePropertiesUpdated.Add(PropertyAndroidX + EnableProperty);
|
||||
gradlePropertiesUpdated.Add(PropertyJetifier + EnableProperty);
|
||||
|
||||
// `DexingArtifactTransform` has been removed in Gradle 8+ which is the default Gradle version for Unity 6.
|
||||
#if !UNITY_6000_0_OR_NEWER
|
||||
// Disable dexing using artifact transform (it causes issues for ExoPlayer with Gradle plugin 3.5.0+)
|
||||
gradlePropertiesUpdated.Add(PropertyDexingArtifactTransform + DisableProperty);
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(gradlePropertiesPath, string.Join("\n", gradlePropertiesUpdated.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to enable AndroidX and Jetifier. gradle.properties file write failed.");
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
|
||||
ProcessAndroidManifest(path);
|
||||
AddSdkSettings(path);
|
||||
}
|
||||
|
||||
public int callbackOrder
|
||||
{
|
||||
get { return AppLovinPreProcess.CallbackOrder; }
|
||||
}
|
||||
|
||||
private static void ProcessAndroidManifest(string path)
|
||||
{
|
||||
var manifestPath = Path.Combine(path, "src/main/AndroidManifest.xml");
|
||||
XDocument manifest;
|
||||
try
|
||||
{
|
||||
manifest = XDocument.Load(manifestPath);
|
||||
}
|
||||
#pragma warning disable 0168
|
||||
catch (IOException exception)
|
||||
#pragma warning restore 0168
|
||||
{
|
||||
MaxSdkLogger.UserWarning("[AppLovin MAX] AndroidManifest.xml is missing.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the `manifest` element.
|
||||
var elementManifest = manifest.Element("manifest");
|
||||
if (elementManifest == null)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("[AppLovin MAX] AndroidManifest.xml is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
var elementApplication = elementManifest.Element("application");
|
||||
if (elementApplication == null)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("[AppLovin MAX] AndroidManifest.xml is invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
var metaDataElements = elementApplication.Descendants().Where(element => element.Name.LocalName.Equals("meta-data"));
|
||||
|
||||
EnableVerboseLoggingIfNeeded(elementApplication);
|
||||
AddGoogleApplicationIdIfNeeded(elementApplication, metaDataElements);
|
||||
AddGoogleOptimizationFlagsIfNeeded(elementApplication, metaDataElements);
|
||||
DisableAutoInitIfNeeded(elementApplication, metaDataElements);
|
||||
RemoveSdkKeyIfNeeded(metaDataElements);
|
||||
|
||||
// Save the updated manifest file.
|
||||
manifest.Save(manifestPath);
|
||||
}
|
||||
|
||||
private static void EnableVerboseLoggingIfNeeded(XElement elementApplication)
|
||||
{
|
||||
var enabled = EditorPrefs.GetBool(MaxSdkLogger.KeyVerboseLoggingEnabled, false);
|
||||
|
||||
var descendants = elementApplication.Descendants();
|
||||
var verboseLoggingMetaData = descendants.FirstOrDefault(descendant => descendant.FirstAttribute != null &&
|
||||
descendant.FirstAttribute.Name.LocalName.Equals("name") &&
|
||||
descendant.FirstAttribute.Value.Equals(KeyMetaDataAppLovinVerboseLoggingOn) &&
|
||||
descendant.LastAttribute != null &&
|
||||
descendant.LastAttribute.Name.LocalName.Equals("value"));
|
||||
|
||||
// check if applovin.sdk.verbose_logging meta data exists.
|
||||
if (verboseLoggingMetaData != null)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
// update applovin.sdk.verbose_logging meta data value.
|
||||
verboseLoggingMetaData.LastAttribute.Value = enabled.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove applovin.sdk.verbose_logging meta data.
|
||||
verboseLoggingMetaData.Remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
// add applovin.sdk.verbose_logging meta data if it does not exist.
|
||||
var metaData = CreateMetaDataElement(KeyMetaDataAppLovinVerboseLoggingOn, enabled.ToString());
|
||||
elementApplication.Add(metaData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddGoogleApplicationIdIfNeeded(XElement elementApplication, IEnumerable<XElement> metaDataElements)
|
||||
{
|
||||
if (!AppLovinPackageManager.IsAdapterInstalled("Google") && !AppLovinPackageManager.IsAdapterInstalled("GoogleAdManager")) return;
|
||||
|
||||
var googleApplicationIdMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataGoogleApplicationId);
|
||||
var appId = AppLovinSettings.Instance.AdMobAndroidAppId;
|
||||
// Log error if the App ID is not set.
|
||||
if (string.IsNullOrEmpty(appId) || !appId.StartsWith("ca-app-pub-"))
|
||||
{
|
||||
MaxSdkLogger.UserError("Google App ID is not set. Please enter a valid app ID within the AppLovin Integration Manager window.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the Google App ID meta data already exists. Update if it already exists.
|
||||
if (googleApplicationIdMetaData != null)
|
||||
{
|
||||
googleApplicationIdMetaData.SetAttributeValue(AndroidNamespace + "value", appId);
|
||||
}
|
||||
// Meta data doesn't exist, add it.
|
||||
else
|
||||
{
|
||||
elementApplication.Add(CreateMetaDataElement(KeyMetaDataGoogleApplicationId, appId));
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddGoogleOptimizationFlagsIfNeeded(XElement elementApplication, IEnumerable<XElement> metaDataElements)
|
||||
{
|
||||
if (!AppLovinPackageManager.IsAdapterInstalled("Google") && !AppLovinPackageManager.IsAdapterInstalled("GoogleAdManager")) return;
|
||||
|
||||
var googleOptimizeInitializationMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataGoogleOptimizeInitialization);
|
||||
// If meta data doesn't exist, add it
|
||||
if (googleOptimizeInitializationMetaData == null)
|
||||
{
|
||||
elementApplication.Add(CreateMetaDataElement(KeyMetaDataGoogleOptimizeInitialization, true));
|
||||
}
|
||||
|
||||
var googleOptimizeAdLoadingMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataGoogleOptimizeAdLoading);
|
||||
// If meta data doesn't exist, add it
|
||||
if (googleOptimizeAdLoadingMetaData == null)
|
||||
{
|
||||
elementApplication.Add(CreateMetaDataElement(KeyMetaDataGoogleOptimizeAdLoading, true));
|
||||
}
|
||||
}
|
||||
|
||||
private static void DisableAutoInitIfNeeded(XElement elementApplication, IEnumerable<XElement> metaDataElements)
|
||||
{
|
||||
if (AppLovinPackageManager.IsAdapterInstalled("MobileFuse"))
|
||||
{
|
||||
var mobileFuseMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataMobileFuseAutoInit);
|
||||
// If MobileFuse meta data doesn't exist, add it
|
||||
if (mobileFuseMetaData == null)
|
||||
{
|
||||
elementApplication.Add(CreateMetaDataElement(KeyMetaDataMobileFuseAutoInit, true));
|
||||
}
|
||||
}
|
||||
|
||||
if (AppLovinPackageManager.IsAdapterInstalled("MyTarget"))
|
||||
{
|
||||
var myTargetMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataMyTargetAutoInit);
|
||||
// If MyTarget meta data doesn't exist, add it
|
||||
if (myTargetMetaData == null)
|
||||
{
|
||||
elementApplication.Add(CreateMetaDataElement(KeyMetaDataMyTargetAutoInit, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RemoveSdkKeyIfNeeded(IEnumerable<XElement> metaDataElements)
|
||||
{
|
||||
var sdkKeyMetaData = GetMetaDataElement(metaDataElements, KeyMetaDataAppLovinSdkKey);
|
||||
if (sdkKeyMetaData == null) return;
|
||||
|
||||
sdkKeyMetaData.Remove();
|
||||
}
|
||||
|
||||
private static void UpdateGradleVersionsIfNeeded(string gradleWrapperPropertiesPath, string rootGradleBuildFilePath)
|
||||
{
|
||||
var customGradleVersionUrl = AppLovinSettings.Instance.CustomGradleVersionUrl;
|
||||
var customGradleToolsVersion = AppLovinSettings.Instance.CustomGradleToolsVersion;
|
||||
|
||||
if (MaxSdkUtils.IsValidString(customGradleVersionUrl))
|
||||
{
|
||||
var newDistributionUrl = string.Format("distributionUrl={0}", customGradleVersionUrl);
|
||||
if (ReplaceStringInFile(gradleWrapperPropertiesPath, TokenDistributionUrl, newDistributionUrl))
|
||||
{
|
||||
MaxSdkLogger.D("Distribution url set to " + newDistributionUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set distribution URL");
|
||||
}
|
||||
}
|
||||
|
||||
if (MaxSdkUtils.IsValidString(customGradleToolsVersion))
|
||||
{
|
||||
#if UNITY_2022_3_OR_NEWER
|
||||
// Unity 2022.3+ requires Gradle Plugin version 7.1.2+.
|
||||
if (MaxSdkUtils.CompareVersions(customGradleToolsVersion, "7.1.2") == MaxSdkUtils.VersionComparisonResult.Lesser)
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set gradle plugin version. Unity 2022.3+ requires gradle plugin version 7.1.2+");
|
||||
return;
|
||||
}
|
||||
|
||||
var newGradleVersionLibraryLine = AppLovinProcessGradleBuildFile.GetFormattedBuildScriptLine(string.Format("id 'com.android.library' version '{0}' apply false", customGradleToolsVersion));
|
||||
if (ReplaceStringInFile(rootGradleBuildFilePath, TokenGradleVersionLibrary, newGradleVersionLibraryLine))
|
||||
{
|
||||
MaxSdkLogger.D("Gradle library version set to " + newGradleVersionLibraryLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set gradle library version");
|
||||
}
|
||||
|
||||
var newGradleVersionLine = AppLovinProcessGradleBuildFile.GetFormattedBuildScriptLine(string.Format("id 'com.android.application' version '{0}' apply false", customGradleToolsVersion));
|
||||
#else
|
||||
var newGradleVersionLine = AppLovinProcessGradleBuildFile.GetFormattedBuildScriptLine(string.Format("classpath 'com.android.tools.build:gradle:{0}'", customGradleToolsVersion));
|
||||
#endif
|
||||
if (ReplaceStringInFile(rootGradleBuildFilePath, TokenGradleVersion, newGradleVersionLine))
|
||||
{
|
||||
MaxSdkLogger.D("Gradle version set to " + newGradleVersionLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxSdkLogger.E("Failed to set gradle plugin version");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddSdkSettings(string path)
|
||||
{
|
||||
var appLovinSdkSettings = new Dictionary<string, object>();
|
||||
var rawResourceDirectory = Path.Combine(path, "src/main/res/raw");
|
||||
|
||||
// Add the SDK key to the SDK settings.
|
||||
appLovinSdkSettings[KeySdkKey] = AppLovinSettings.Instance.SdkKey;
|
||||
appLovinSdkSettings[KeyRenderOutsideSafeArea] = PlayerSettings.Android.renderOutsideSafeArea;
|
||||
|
||||
// Add the Terms and Privacy Policy flow settings if needed.
|
||||
EnableConsentFlowIfNeeded(rawResourceDirectory, appLovinSdkSettings);
|
||||
|
||||
WriteAppLovinSettings(rawResourceDirectory, appLovinSdkSettings);
|
||||
}
|
||||
|
||||
private static void EnableConsentFlowIfNeeded(string rawResourceDirectory, Dictionary<string, object> applovinSdkSettings)
|
||||
{
|
||||
// Check if consent flow is enabled. No need to create the applovin_consent_flow_settings.json if consent flow is disabled.
|
||||
var consentFlowEnabled = AppLovinInternalSettings.Instance.ConsentFlowEnabled;
|
||||
if (!consentFlowEnabled)
|
||||
{
|
||||
RemoveAppLovinSettingsRawResourceFileIfNeeded(rawResourceDirectory);
|
||||
return;
|
||||
}
|
||||
|
||||
var privacyPolicyUrl = AppLovinInternalSettings.Instance.ConsentFlowPrivacyPolicyUrl;
|
||||
if (string.IsNullOrEmpty(privacyPolicyUrl))
|
||||
{
|
||||
AppLovinIntegrationManager.ShowBuildFailureDialog("You cannot use the AppLovin SDK's consent flow without defining a Privacy Policy URL in the AppLovin Integration Manager.");
|
||||
|
||||
// No need to update the applovin_consent_flow_settings.json here. Default consent flow state will be determined on the SDK side.
|
||||
return;
|
||||
}
|
||||
|
||||
var consentFlowSettings = new Dictionary<string, object>();
|
||||
consentFlowSettings[KeyConsentFlowEnabled] = consentFlowEnabled;
|
||||
consentFlowSettings[KeyConsentFlowPrivacyPolicy] = privacyPolicyUrl;
|
||||
|
||||
var termsOfServiceUrl = AppLovinInternalSettings.Instance.ConsentFlowTermsOfServiceUrl;
|
||||
if (MaxSdkUtils.IsValidString(termsOfServiceUrl))
|
||||
{
|
||||
consentFlowSettings[KeyConsentFlowTermsOfService] = termsOfServiceUrl;
|
||||
}
|
||||
|
||||
consentFlowSettings[KeyConsentFlowShowTermsAndPrivacyPolicyAlertInGDPR] = AppLovinInternalSettings.Instance.ShouldShowTermsAndPrivacyPolicyAlertInGDPR;
|
||||
|
||||
var debugUserGeography = AppLovinInternalSettings.Instance.DebugUserGeography;
|
||||
if (debugUserGeography == MaxSdkBase.ConsentFlowUserGeography.Gdpr)
|
||||
{
|
||||
consentFlowSettings[KeyConsentFlowDebugUserGeography] = "gdpr";
|
||||
}
|
||||
|
||||
applovinSdkSettings[KeyConsentFlowSettings] = consentFlowSettings;
|
||||
}
|
||||
|
||||
private static void WriteAppLovinSettingsRawResourceFile(string applovinSdkSettingsJson, string rawResourceDirectory)
|
||||
{
|
||||
if (!Directory.Exists(rawResourceDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(rawResourceDirectory);
|
||||
}
|
||||
|
||||
var consentFlowSettingsFilePath = Path.Combine(rawResourceDirectory, AppLovinSettingsFileName);
|
||||
try
|
||||
{
|
||||
File.WriteAllText(consentFlowSettingsFilePath, applovinSdkSettingsJson + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("applovin_settings.json file write failed due to: " + exception.Message);
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the applovin_settings json file from the build if it exists.
|
||||
/// </summary>
|
||||
/// <param name="rawResourceDirectory">The raw resource directory that holds the json file</param>
|
||||
private static void RemoveAppLovinSettingsRawResourceFileIfNeeded(string rawResourceDirectory)
|
||||
{
|
||||
var consentFlowSettingsFilePath = Path.Combine(rawResourceDirectory, AppLovinSettingsFileName);
|
||||
if (!File.Exists(consentFlowSettingsFilePath)) return;
|
||||
|
||||
try
|
||||
{
|
||||
File.Delete(consentFlowSettingsFilePath);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Deleting applovin_settings.json failed due to: " + exception.Message);
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteAppLovinSettings(string rawResourceDirectory, Dictionary<string, object> applovinSdkSettings)
|
||||
{
|
||||
var applovinSdkSettingsJson = Json.Serialize(applovinSdkSettings);
|
||||
WriteAppLovinSettingsRawResourceFile(applovinSdkSettingsJson, rawResourceDirectory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and returns a <c>meta-data</c> element with the given name and value.
|
||||
/// </summary>
|
||||
private static XElement CreateMetaDataElement(string name, object value)
|
||||
{
|
||||
var metaData = new XElement("meta-data");
|
||||
metaData.Add(new XAttribute(AndroidNamespace + "name", name));
|
||||
metaData.Add(new XAttribute(AndroidNamespace + "value", value));
|
||||
|
||||
return metaData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks through all the given meta-data elements to check if the required one exists. Returns <c>null</c> if it doesn't exist.
|
||||
/// </summary>
|
||||
private static XElement GetMetaDataElement(IEnumerable<XElement> metaDataElements, string metaDataName)
|
||||
{
|
||||
foreach (var metaDataElement in metaDataElements)
|
||||
{
|
||||
var attributes = metaDataElement.Attributes();
|
||||
if (attributes.Any(attribute => attribute.Name.Namespace.Equals(AndroidNamespace)
|
||||
&& attribute.Name.LocalName.Equals("name")
|
||||
&& attribute.Value.Equals(metaDataName)))
|
||||
{
|
||||
return metaDataElement;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the first line that contains regexToMatch and replaces the whole line with replacement
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the file you want to replace a line in</param>
|
||||
/// <param name="regexToMatch">Regex to search for in the line you want to replace</param>
|
||||
/// <param name="replacement">String that you want as the new line</param>
|
||||
/// <returns>Returns whether the string was successfully replaced or not</returns>
|
||||
private static bool ReplaceStringInFile(string path, Regex regexToMatch, string replacement)
|
||||
{
|
||||
if (!File.Exists(path)) return false;
|
||||
|
||||
var lines = File.ReadAllLines(path);
|
||||
for (var i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (regexToMatch.IsMatch(lines[i]))
|
||||
{
|
||||
lines[i] = replacement;
|
||||
File.WriteAllLines(path, lines);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c01ea79d0cb2a43c093e2fd07201df9e
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessAndroid.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,51 @@
|
||||
//
|
||||
// AppLovinBuildPostProcessor.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 8/29/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_ANDROID
|
||||
|
||||
using System.IO;
|
||||
using UnityEditor.Android;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds Quality Service plugin to the Gradle project once the project has been exported. See <see cref="AppLovinProcessGradleBuildFile"/> for more details.
|
||||
/// </summary>
|
||||
public class AppLovinPostProcessGradleProject : AppLovinProcessGradleBuildFile, IPostGenerateGradleAndroidProject
|
||||
{
|
||||
public void OnPostGenerateGradleAndroidProject(string path)
|
||||
{
|
||||
if (!AppLovinSettings.Instance.QualityServiceEnabled) return;
|
||||
|
||||
var failedToAddPlugin = !AddQualityServiceToRootGradleFile(path);
|
||||
if (failedToAddPlugin)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("Failed to add AppLovin Quality Service plugin to the gradle project.");
|
||||
return;
|
||||
}
|
||||
|
||||
// The plugin needs to be added to the application module (named launcher)
|
||||
var applicationGradleBuildFilePath = Path.Combine(path, "../launcher/build.gradle");
|
||||
|
||||
if (!File.Exists(applicationGradleBuildFilePath))
|
||||
{
|
||||
MaxSdkLogger.UserWarning("Couldn't find build.gradle file. Failed to add AppLovin Quality Service plugin to the gradle project.");
|
||||
return;
|
||||
}
|
||||
|
||||
AddAppLovinQualityServicePlugin(applicationGradleBuildFilePath);
|
||||
}
|
||||
|
||||
public int callbackOrder
|
||||
{
|
||||
get { return CallbackOrder; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f75e54e2eb78f427ca8643c97684387b
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessAndroidGradle.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,692 @@
|
||||
//
|
||||
// MaxIntegrationManager.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 8/29/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_IOS || UNITY_IPHONE
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using AppLovinMax.Internal;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEditor.iOS.Xcode.Extensions;
|
||||
using UnityEditor.iOS.Xcode;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class SkAdNetworkData
|
||||
{
|
||||
[SerializeField] public string[] SkAdNetworkIds;
|
||||
}
|
||||
|
||||
public class AppLovinPostProcessiOS
|
||||
{
|
||||
private const string OutputFileName = "AppLovinQualityServiceSetup.rb";
|
||||
|
||||
// Use a priority of 90 to have AppLovin embed frameworks after Pods are installed (EDM finishes installing Pods at priority 60) and before Firebase Crashlytics runs their scripts (at priority 100).
|
||||
private const int AppLovinEmbedFrameworksPriority = 90;
|
||||
|
||||
private const string TargetUnityIphonePodfileLine = "target 'Unity-iPhone' do";
|
||||
private const string UseFrameworksPodfileLine = "use_frameworks!";
|
||||
private const string UseFrameworksDynamicPodfileLine = "use_frameworks! :linkage => :dynamic";
|
||||
private const string UseFrameworksStaticPodfileLine = "use_frameworks! :linkage => :static";
|
||||
|
||||
private const string ResourcesDirectoryName = "Resources";
|
||||
private const string AppLovinMaxResourcesDirectoryName = "AppLovinMAXResources";
|
||||
private const string AppLovinAdvertisingAttributionEndpoint = "https://postbacks-app.com";
|
||||
|
||||
private const string AppLovinSettingsPlistFileName = "AppLovin-Settings.plist";
|
||||
|
||||
private const string KeySdkKey = "SdkKey";
|
||||
|
||||
private const string AppLovinVerboseLoggingOnKey = "AppLovinVerboseLoggingOn";
|
||||
|
||||
private const string KeyConsentFlowInfo = "ConsentFlowInfo";
|
||||
private const string KeyConsentFlowEnabled = "ConsentFlowEnabled";
|
||||
private const string KeyConsentFlowTermsOfService = "ConsentFlowTermsOfService";
|
||||
private const string KeyConsentFlowPrivacyPolicy = "ConsentFlowPrivacyPolicy";
|
||||
private const string KeyConsentFlowShowTermsAndPrivacyPolicyAlertInGDPR = "ConsentFlowShowTermsAndPrivacyPolicyAlertInGDPR";
|
||||
private const string KeyConsentFlowDebugUserGeography = "ConsentFlowDebugUserGeography";
|
||||
|
||||
private const string KeyAppLovinSdkKeyToRemove = "AppLovinSdkKey";
|
||||
|
||||
private static readonly Regex PodfilePodLineRegex = new Regex("pod \'([^\']*)\'");
|
||||
|
||||
/// <summary>
|
||||
/// Adds AppLovin Quality Service to the iOS project once the project has been exported.
|
||||
///
|
||||
/// 1. Downloads the Quality Service ruby script.
|
||||
/// 2. Runs the script using Ruby which integrates AppLovin Quality Service to the project.
|
||||
/// </summary>
|
||||
[PostProcessBuild(AppLovinPreProcess.CallbackOrder)] // We want to run Quality Service script last.
|
||||
public static void OnPostProcessBuild(BuildTarget buildTarget, string buildPath)
|
||||
{
|
||||
if (!AppLovinSettings.Instance.QualityServiceEnabled) return;
|
||||
|
||||
var sdkKey = AppLovinSettings.Instance.SdkKey;
|
||||
if (string.IsNullOrEmpty(sdkKey))
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. SDK Key is empty. Please enter the AppLovin SDK Key in the Integration Manager.");
|
||||
return;
|
||||
}
|
||||
|
||||
var outputFilePath = Path.Combine(buildPath, OutputFileName);
|
||||
|
||||
// Check if Quality Service is already installed.
|
||||
if (File.Exists(outputFilePath) && Directory.Exists(Path.Combine(buildPath, "AppLovinQualityService")))
|
||||
{
|
||||
// TODO: Check if there is a way to validate if the SDK key matches the script. Else the pub can't use append when/if they change the SDK Key.
|
||||
return;
|
||||
}
|
||||
|
||||
var webRequestConfig = new WebRequestConfig()
|
||||
{
|
||||
DownloadHandler = new DownloadHandlerFile(outputFilePath),
|
||||
JsonString = string.Format("{{\"sdk_key\" : \"{0}\"}}", sdkKey),
|
||||
EndPoint = "https://api2.safedk.com/v1/build/ios_setup2",
|
||||
RequestType = WebRequestType.Post,
|
||||
};
|
||||
|
||||
webRequestConfig.Headers.Add("Content-Type", "application/json");
|
||||
|
||||
var maxWebRequest = new MaxWebRequest(webRequestConfig);
|
||||
|
||||
var webResponse = maxWebRequest.SendSync();
|
||||
if (!webResponse.IsSuccess)
|
||||
{
|
||||
MaxSdkLogger.UserError("AppLovin Quality Service installation failed. Failed to download script with error: " + webResponse.ErrorMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if Ruby is installed
|
||||
var rubyVersion = AppLovinCommandLine.Run("ruby", "--version", buildPath);
|
||||
if (rubyVersion.ExitCode != 0)
|
||||
{
|
||||
MaxSdkLogger.UserError("AppLovin Quality Service installation requires Ruby. Please install Ruby, export it to your system PATH and re-export the project.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Ruby is installed, run `ruby AppLovinQualityServiceSetup.rb`
|
||||
var result = AppLovinCommandLine.Run("ruby", OutputFileName, buildPath);
|
||||
|
||||
// Check if we have an error.
|
||||
if (result.ExitCode != 0) MaxSdkLogger.UserError("Failed to set up AppLovin Quality Service");
|
||||
|
||||
MaxSdkLogger.UserDebug(result.Message);
|
||||
}
|
||||
|
||||
[PostProcessBuild(AppLovinEmbedFrameworksPriority)]
|
||||
public static void MaxPostProcessPbxProject(BuildTarget buildTarget, string buildPath)
|
||||
{
|
||||
var projectPath = PBXProject.GetPBXProjectPath(buildPath);
|
||||
var project = new PBXProject();
|
||||
project.ReadFromFile(projectPath);
|
||||
|
||||
var unityMainTargetGuid = project.GetUnityMainTargetGuid();
|
||||
var unityFrameworkTargetGuid = project.GetUnityFrameworkTargetGuid();
|
||||
|
||||
EmbedDynamicLibrariesIfNeeded(buildPath, project, unityMainTargetGuid);
|
||||
|
||||
LocalizeUserTrackingDescriptionIfNeeded(AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionDe, "de", buildPath, project, unityMainTargetGuid);
|
||||
LocalizeUserTrackingDescriptionIfNeeded(AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEn, "en", buildPath, project, unityMainTargetGuid);
|
||||
LocalizeUserTrackingDescriptionIfNeeded(AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEs, "es", buildPath, project, unityMainTargetGuid);
|
||||
LocalizeUserTrackingDescriptionIfNeeded(AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionFr, "fr", buildPath, project, unityMainTargetGuid);
|
||||
LocalizeUserTrackingDescriptionIfNeeded(AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionJa, "ja", buildPath, project, unityMainTargetGuid);
|
||||
LocalizeUserTrackingDescriptionIfNeeded(AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionKo, "ko", buildPath, project, unityMainTargetGuid);
|
||||
LocalizeUserTrackingDescriptionIfNeeded(AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionZhHans, "zh-Hans", buildPath, project, unityMainTargetGuid);
|
||||
LocalizeUserTrackingDescriptionIfNeeded(AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionZhHant, "zh-Hant", buildPath, project, unityMainTargetGuid);
|
||||
|
||||
AddSwiftSupport(buildPath, project, unityFrameworkTargetGuid, unityMainTargetGuid);
|
||||
AddYandexSettingsIfNeeded(project, unityMainTargetGuid);
|
||||
|
||||
project.WriteToFile(projectPath);
|
||||
}
|
||||
|
||||
private static void EmbedDynamicLibrariesIfNeeded(string buildPath, PBXProject project, string targetGuid)
|
||||
{
|
||||
// Check that the Pods directory exists (it might not if a publisher is building with Generate Podfile setting disabled in EDM).
|
||||
var podsDirectory = Path.Combine(buildPath, "Pods");
|
||||
if (!Directory.Exists(podsDirectory) || !ShouldEmbedDynamicLibraries(buildPath)) return;
|
||||
|
||||
var dynamicLibraryPathsToEmbed = GetDynamicLibraryPathsToEmbed(podsDirectory, buildPath);
|
||||
if (dynamicLibraryPathsToEmbed == null || dynamicLibraryPathsToEmbed.Count == 0) return;
|
||||
|
||||
foreach (var dynamicLibraryPath in dynamicLibraryPathsToEmbed)
|
||||
{
|
||||
var fileGuid = project.AddFile(dynamicLibraryPath, dynamicLibraryPath);
|
||||
project.AddFileToEmbedFrameworks(targetGuid, fileGuid);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// |-----------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
/// | embed | use_frameworks! (:linkage => :dynamic) | use_frameworks! :linkage => :static | `use_frameworks!` line not present |
|
||||
/// |---------------------------|------------------------------------------|---------------------------------------|--------------------------------------|
|
||||
/// | Unity-iPhone present | Do not embed dynamic libraries | Embed dynamic libraries | Do not embed dynamic libraries |
|
||||
/// | Unity-iPhone not present | Embed dynamic libraries | Embed dynamic libraries | Embed dynamic libraries |
|
||||
/// |-----------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
/// </summary>
|
||||
/// <param name="buildPath">An iOS build path</param>
|
||||
/// <returns>Whether or not the dynamic libraries should be embedded.</returns>
|
||||
private static bool ShouldEmbedDynamicLibraries(string buildPath)
|
||||
{
|
||||
var podfilePath = Path.Combine(buildPath, "Podfile");
|
||||
if (!File.Exists(podfilePath)) return false;
|
||||
|
||||
// If the Podfile doesn't have a `Unity-iPhone` target, we should embed the dynamic libraries.
|
||||
var lines = File.ReadAllLines(podfilePath);
|
||||
var containsUnityIphoneTarget = lines.Any(line => line.Contains(TargetUnityIphonePodfileLine));
|
||||
if (!containsUnityIphoneTarget) return true;
|
||||
|
||||
// If the Podfile does not have a `use_frameworks! :linkage => static` line, we should not embed the dynamic libraries.
|
||||
var useFrameworksStaticLineIndex = Array.FindIndex(lines, line => line.Contains(UseFrameworksStaticPodfileLine));
|
||||
if (useFrameworksStaticLineIndex == -1) return false;
|
||||
|
||||
// If more than one of the `use_frameworks!` lines are present, CocoaPods will use the last one.
|
||||
var useFrameworksLineIndex = Array.FindIndex(lines, line => line.Trim() == UseFrameworksPodfileLine); // Check for exact line to avoid matching `use_frameworks! :linkage => static/dynamic`
|
||||
var useFrameworksDynamicLineIndex = Array.FindIndex(lines, line => line.Contains(UseFrameworksDynamicPodfileLine));
|
||||
|
||||
// Check if `use_frameworks! :linkage => :static` is the last line of the three. If it is, we should embed the dynamic libraries.
|
||||
return useFrameworksLineIndex < useFrameworksStaticLineIndex && useFrameworksDynamicLineIndex < useFrameworksStaticLineIndex;
|
||||
}
|
||||
|
||||
private static List<string> GetDynamicLibraryPathsToEmbed(string podsDirectory, string buildPath)
|
||||
{
|
||||
var podfilePath = Path.Combine(buildPath, "Podfile");
|
||||
var dynamicLibraryFrameworksToEmbed = GetDynamicLibraryFrameworksToEmbed(podfilePath);
|
||||
|
||||
return GetDynamicLibraryPathsInProjectToEmbed(podsDirectory, dynamicLibraryFrameworksToEmbed);
|
||||
}
|
||||
|
||||
private static List<string> GetDynamicLibraryFrameworksToEmbed(string podfilePath)
|
||||
{
|
||||
var dynamicLibrariesToEmbed = GetDynamicLibrariesToEmbed();
|
||||
|
||||
var podsInUnityIphoneTarget = GetPodNamesInUnityIphoneTarget(podfilePath);
|
||||
var dynamicLibrariesToIgnore = dynamicLibrariesToEmbed.Where(dynamicLibraryToEmbed => podsInUnityIphoneTarget.Contains(dynamicLibraryToEmbed.PodName)).ToList();
|
||||
|
||||
// Determine frameworks to embed based on the dynamic libraries to embed and ignore
|
||||
var dynamicLibraryFrameworksToIgnore = dynamicLibrariesToIgnore.SelectMany(library => library.FrameworkNames).Distinct().ToList();
|
||||
return dynamicLibrariesToEmbed.SelectMany(library => library.FrameworkNames).Except(dynamicLibraryFrameworksToIgnore).Distinct().ToList();
|
||||
}
|
||||
|
||||
private static List<DynamicLibraryToEmbed> GetDynamicLibrariesToEmbed()
|
||||
{
|
||||
var pluginData = AppLovinIntegrationManager.LoadPluginDataSync();
|
||||
if (pluginData == null)
|
||||
{
|
||||
MaxSdkLogger.E("Failed to load plugin data. Dynamic libraries will not be embedded.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get the dynamic libraries to embed for each network
|
||||
var librariesToAdd = pluginData.MediatedNetworks
|
||||
.Where(network => network.DynamicLibrariesToEmbed != null)
|
||||
.SelectMany(network => network.DynamicLibrariesToEmbed
|
||||
.Where(libraryToEmbed => IsRequiredNetworkVersionInstalled(libraryToEmbed, network)))
|
||||
.ToList();
|
||||
|
||||
// Get the dynamic libraries to embed for AppLovin MAX
|
||||
if (pluginData.AppLovinMax.DynamicLibrariesToEmbed != null)
|
||||
{
|
||||
librariesToAdd.AddRange(pluginData.AppLovinMax.DynamicLibrariesToEmbed);
|
||||
}
|
||||
|
||||
// Get the dynamic libraries to embed for third parties
|
||||
if (pluginData.ThirdPartyDynamicLibrariesToEmbed != null)
|
||||
{
|
||||
// TODO: Add version check for third party dynamic libraries.
|
||||
librariesToAdd.AddRange(pluginData.ThirdPartyDynamicLibrariesToEmbed);
|
||||
}
|
||||
|
||||
return librariesToAdd;
|
||||
}
|
||||
|
||||
private static List<string> GetPodNamesInUnityIphoneTarget(string podfilePath)
|
||||
{
|
||||
var lines = File.ReadAllLines(podfilePath);
|
||||
var podNamesInUnityIphone = new List<string>();
|
||||
|
||||
var insideUnityIphoneTarget = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
// Loop until we find the `target 'Unity-iPhone'` line
|
||||
if (insideUnityIphoneTarget)
|
||||
{
|
||||
if (line.Trim() == "end") break;
|
||||
|
||||
if (PodfilePodLineRegex.IsMatch(line))
|
||||
{
|
||||
var podName = PodfilePodLineRegex.Match(line).Groups[1].Value;
|
||||
podNamesInUnityIphone.Add(podName);
|
||||
}
|
||||
}
|
||||
else if (line.Contains(TargetUnityIphonePodfileLine))
|
||||
{
|
||||
insideUnityIphoneTarget = true;
|
||||
}
|
||||
}
|
||||
|
||||
return podNamesInUnityIphone;
|
||||
}
|
||||
|
||||
private static bool IsRequiredNetworkVersionInstalled(DynamicLibraryToEmbed libraryToEmbed, Network network)
|
||||
{
|
||||
var currentIosVersion = network.CurrentVersions.Ios;
|
||||
if (string.IsNullOrEmpty(currentIosVersion)) return false;
|
||||
|
||||
var minIosVersion = libraryToEmbed.MinVersion;
|
||||
var maxIosVersion = libraryToEmbed.MaxVersion;
|
||||
|
||||
var greaterThanOrEqualToMinVersion = string.IsNullOrEmpty(minIosVersion) || MaxSdkUtils.CompareVersions(currentIosVersion, minIosVersion) != MaxSdkUtils.VersionComparisonResult.Lesser;
|
||||
var lessThanOrEqualToMaxVersion = string.IsNullOrEmpty(maxIosVersion) || MaxSdkUtils.CompareVersions(currentIosVersion, maxIosVersion) != MaxSdkUtils.VersionComparisonResult.Greater;
|
||||
|
||||
return greaterThanOrEqualToMinVersion && lessThanOrEqualToMaxVersion;
|
||||
}
|
||||
|
||||
private static List<string> GetDynamicLibraryPathsInProjectToEmbed(string podsDirectory, List<string> dynamicLibrariesToEmbed)
|
||||
{
|
||||
var dynamicLibraryPathsPresentInProject = new List<string>();
|
||||
foreach (var dynamicLibraryToSearch in dynamicLibrariesToEmbed)
|
||||
{
|
||||
// both .framework and .xcframework are directories, not files
|
||||
var directories = Directory.GetDirectories(podsDirectory, dynamicLibraryToSearch, SearchOption.AllDirectories);
|
||||
if (directories.Length <= 0) continue;
|
||||
|
||||
var dynamicLibraryAbsolutePath = directories[0];
|
||||
var relativePath = GetDynamicLibraryRelativePath(dynamicLibraryAbsolutePath);
|
||||
dynamicLibraryPathsPresentInProject.Add(relativePath);
|
||||
}
|
||||
|
||||
return dynamicLibraryPathsPresentInProject;
|
||||
}
|
||||
|
||||
private static string GetDynamicLibraryRelativePath(string dynamicLibraryAbsolutePath)
|
||||
{
|
||||
var index = dynamicLibraryAbsolutePath.LastIndexOf("Pods", StringComparison.Ordinal);
|
||||
return dynamicLibraryAbsolutePath.Substring(index);
|
||||
}
|
||||
|
||||
private static void LocalizeUserTrackingDescriptionIfNeeded(string localizedUserTrackingDescription, string localeCode, string buildPath, PBXProject project, string targetGuid)
|
||||
{
|
||||
var resourcesDirectoryPath = Path.Combine(buildPath, AppLovinMaxResourcesDirectoryName);
|
||||
var localeSpecificDirectoryName = localeCode + ".lproj";
|
||||
var localeSpecificDirectoryPath = Path.Combine(resourcesDirectoryPath, localeSpecificDirectoryName);
|
||||
var infoPlistStringsFilePath = Path.Combine(localeSpecificDirectoryPath, "InfoPlist.strings");
|
||||
|
||||
// Check if localization has been disabled between builds, and remove them as needed.
|
||||
if (ShouldRemoveLocalization(localizedUserTrackingDescription))
|
||||
{
|
||||
if (!File.Exists(infoPlistStringsFilePath)) return;
|
||||
|
||||
File.Delete(infoPlistStringsFilePath);
|
||||
return;
|
||||
}
|
||||
|
||||
// Log an error if we detect a localization file for this language in the `Resources` directory
|
||||
var legacyResourcedDirectoryPath = Path.Combine(buildPath, ResourcesDirectoryName);
|
||||
var localeSpecificLegacyDirectoryPath = Path.Combine(legacyResourcedDirectoryPath, localeSpecificDirectoryName);
|
||||
if (Directory.Exists(localeSpecificLegacyDirectoryPath))
|
||||
{
|
||||
MaxSdkLogger.UserError("Detected existing localization resource for \"" + localeCode + "\" locale. Skipping localization for User Tracking Usage Description. Please disable localization in AppLovin Integration manager and add the localizations to your existing resource.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create intermediate directories as needed.
|
||||
if (!Directory.Exists(resourcesDirectoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(resourcesDirectoryPath);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(localeSpecificDirectoryPath))
|
||||
{
|
||||
Directory.CreateDirectory(localeSpecificDirectoryPath);
|
||||
}
|
||||
|
||||
var localizedDescriptionLine = "\"NSUserTrackingUsageDescription\" = \"" + localizedUserTrackingDescription + "\";\n";
|
||||
// File already exists, update it in case the value changed between builds.
|
||||
if (File.Exists(infoPlistStringsFilePath))
|
||||
{
|
||||
var output = new List<string>();
|
||||
var lines = File.ReadAllLines(infoPlistStringsFilePath);
|
||||
var keyUpdated = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (line.Contains("NSUserTrackingUsageDescription"))
|
||||
{
|
||||
output.Add(localizedDescriptionLine);
|
||||
keyUpdated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
output.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (!keyUpdated)
|
||||
{
|
||||
output.Add(localizedDescriptionLine);
|
||||
}
|
||||
|
||||
File.WriteAllText(infoPlistStringsFilePath, string.Join("\n", output.ToArray()) + "\n");
|
||||
}
|
||||
// File doesn't exist, create one.
|
||||
else
|
||||
{
|
||||
File.WriteAllText(infoPlistStringsFilePath, "/* Localized versions of Info.plist keys - Generated by AL MAX plugin */\n" + localizedDescriptionLine);
|
||||
}
|
||||
|
||||
var localeSpecificDirectoryRelativePath = Path.Combine(AppLovinMaxResourcesDirectoryName, localeSpecificDirectoryName);
|
||||
var guid = project.AddFolderReference(localeSpecificDirectoryRelativePath, localeSpecificDirectoryRelativePath);
|
||||
project.AddFileToBuild(targetGuid, guid);
|
||||
}
|
||||
|
||||
private static bool ShouldRemoveLocalization(string localizedUserTrackingDescription)
|
||||
{
|
||||
if (string.IsNullOrEmpty(localizedUserTrackingDescription)) return true;
|
||||
|
||||
var internalSettings = AppLovinInternalSettings.Instance;
|
||||
return !internalSettings.ConsentFlowEnabled || !internalSettings.UserTrackingUsageLocalizationEnabled;
|
||||
}
|
||||
|
||||
private static void AddSwiftSupport(string buildPath, PBXProject project, string unityFrameworkTargetGuid, string unityMainTargetGuid)
|
||||
{
|
||||
var swiftFileRelativePath = "Classes/MAXSwiftSupport.swift";
|
||||
var swiftFilePath = Path.Combine(buildPath, swiftFileRelativePath);
|
||||
|
||||
// Add Swift file
|
||||
CreateSwiftFile(swiftFilePath);
|
||||
var swiftFileGuid = project.AddFile(swiftFileRelativePath, swiftFileRelativePath);
|
||||
project.AddFileToBuild(unityFrameworkTargetGuid, swiftFileGuid);
|
||||
|
||||
// Add Swift version property if needed
|
||||
var swiftVersion = project.GetBuildPropertyForAnyConfig(unityFrameworkTargetGuid, "SWIFT_VERSION");
|
||||
if (string.IsNullOrEmpty(swiftVersion))
|
||||
{
|
||||
project.SetBuildProperty(unityFrameworkTargetGuid, "SWIFT_VERSION", "5.0");
|
||||
}
|
||||
|
||||
// Some publishers may configure these settings in their own post-processing scripts.
|
||||
// Only set them if they haven't already been defined to avoid overwriting publisher-defined values.
|
||||
var enableModules = project.GetBuildPropertyForAnyConfig(unityFrameworkTargetGuid, "CLANG_ENABLE_MODULES");
|
||||
if (string.IsNullOrEmpty(enableModules))
|
||||
{
|
||||
project.SetBuildProperty(unityFrameworkTargetGuid, "CLANG_ENABLE_MODULES", "YES");
|
||||
}
|
||||
|
||||
var alwaysEmbedSwiftLibraries = project.GetBuildPropertyForAnyConfig(unityMainTargetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES");
|
||||
if (string.IsNullOrEmpty(alwaysEmbedSwiftLibraries))
|
||||
{
|
||||
project.SetBuildProperty(unityMainTargetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "YES");
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateSwiftFile(string swiftFilePath)
|
||||
{
|
||||
if (File.Exists(swiftFilePath)) return;
|
||||
|
||||
// Create a file to write to.
|
||||
using (var writer = File.CreateText(swiftFilePath))
|
||||
{
|
||||
writer.WriteLine("//\n// MAXSwiftSupport.swift\n//");
|
||||
writer.WriteLine("\nimport Foundation\n");
|
||||
writer.WriteLine("// This file ensures the project includes Swift support.");
|
||||
writer.WriteLine("// It is automatically generated by the MAX Unity Plugin.");
|
||||
writer.Close();
|
||||
}
|
||||
}
|
||||
|
||||
[PostProcessBuild(AppLovinPreProcess.CallbackOrder)]
|
||||
public static void MaxPostProcessPlist(BuildTarget buildTarget, string path)
|
||||
{
|
||||
var plistPath = Path.Combine(path, "Info.plist");
|
||||
var plist = new PlistDocument();
|
||||
plist.ReadFromFile(plistPath);
|
||||
|
||||
RemoveAttributionReportEndpointIfNeeded(plist);
|
||||
|
||||
EnableVerboseLoggingIfNeeded(plist);
|
||||
AddGoogleApplicationIdIfNeeded(plist);
|
||||
|
||||
AddSdkSettings(plist, path);
|
||||
AddSkAdNetworksInfoIfNeeded(plist);
|
||||
RemoveSdkKeyIfNeeded(plist);
|
||||
|
||||
plist.WriteToFile(plistPath);
|
||||
}
|
||||
|
||||
private static void RemoveAttributionReportEndpointIfNeeded(PlistDocument plist)
|
||||
{
|
||||
PlistElement attributionReportEndPoint;
|
||||
plist.root.values.TryGetValue("NSAdvertisingAttributionReportEndpoint", out attributionReportEndPoint);
|
||||
|
||||
// We no longer support this feature. Check if we had previously set the attribution endpoint and un-set it.
|
||||
if (attributionReportEndPoint == null || !AppLovinAdvertisingAttributionEndpoint.Equals(attributionReportEndPoint.AsString())) return;
|
||||
|
||||
MaxSdkLogger.UserWarning("Global SKAdNetwork postback forwarding is no longer supported by AppLovin. Removing AppLovin Advertising Attribution Endpoint from Info.plist.");
|
||||
plist.root.values.Remove("NSAdvertisingAttributionReportEndpoint");
|
||||
}
|
||||
|
||||
private static void EnableVerboseLoggingIfNeeded(PlistDocument plist)
|
||||
{
|
||||
if (!EditorPrefs.HasKey(MaxSdkLogger.KeyVerboseLoggingEnabled)) return;
|
||||
|
||||
var enabled = EditorPrefs.GetBool(MaxSdkLogger.KeyVerboseLoggingEnabled);
|
||||
if (enabled)
|
||||
{
|
||||
plist.root.SetBoolean(AppLovinVerboseLoggingOnKey, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
plist.root.values.Remove(AppLovinVerboseLoggingOnKey);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddGoogleApplicationIdIfNeeded(PlistDocument plist)
|
||||
{
|
||||
if (!AppLovinPackageManager.IsAdapterInstalled("Google") && !AppLovinPackageManager.IsAdapterInstalled("GoogleAdManager")) return;
|
||||
|
||||
const string googleApplicationIdentifier = "GADApplicationIdentifier";
|
||||
var appId = AppLovinSettings.Instance.AdMobIosAppId;
|
||||
// Log error if the App ID is not set.
|
||||
if (string.IsNullOrEmpty(appId) || !appId.StartsWith("ca-app-pub-"))
|
||||
{
|
||||
MaxSdkLogger.UserError("[AppLovin MAX] Google App ID is not set. Please enter a valid app ID within the AppLovin Integration Manager window.");
|
||||
return;
|
||||
}
|
||||
|
||||
plist.root.SetString(googleApplicationIdentifier, appId);
|
||||
}
|
||||
|
||||
private static void AddYandexSettingsIfNeeded(PBXProject project, string unityMainTargetGuid)
|
||||
{
|
||||
if (!AppLovinPackageManager.IsAdapterInstalled("Yandex")) return;
|
||||
|
||||
if (MaxSdkUtils.CompareVersions(PlayerSettings.iOS.targetOSVersionString, "12.0") == MaxSdkUtils.VersionComparisonResult.Lesser)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("Your iOS target version is under the minimum required version by Yandex. Please update it to 12.0 or newer in your ProjectSettings and rebuild your project.");
|
||||
return;
|
||||
}
|
||||
|
||||
project.SetBuildProperty(unityMainTargetGuid, "GENERATE_INFOPLIST_FILE", "NO");
|
||||
}
|
||||
|
||||
private static void AddSdkSettings(PlistDocument infoPlist, string buildPath)
|
||||
{
|
||||
var sdkSettingsPlistPath = Path.Combine(buildPath, AppLovinSettingsPlistFileName);
|
||||
var sdkSettingsPlist = new PlistDocument();
|
||||
if (File.Exists(sdkSettingsPlistPath))
|
||||
{
|
||||
sdkSettingsPlist.ReadFromFile(sdkSettingsPlistPath);
|
||||
}
|
||||
|
||||
// Add the SDK key to the SDK settings plist.
|
||||
sdkSettingsPlist.root.SetString(KeySdkKey, AppLovinSettings.Instance.SdkKey);
|
||||
|
||||
// Add consent flow settings if needed.
|
||||
EnableConsentFlowIfNeeded(sdkSettingsPlist, infoPlist);
|
||||
|
||||
sdkSettingsPlist.WriteToFile(sdkSettingsPlistPath);
|
||||
|
||||
var projectPath = PBXProject.GetPBXProjectPath(buildPath);
|
||||
var project = new PBXProject();
|
||||
project.ReadFromFile(projectPath);
|
||||
|
||||
var unityMainTargetGuid = project.GetUnityMainTargetGuid();
|
||||
|
||||
var guid = project.AddFile(AppLovinSettingsPlistFileName, AppLovinSettingsPlistFileName);
|
||||
project.AddFileToBuild(unityMainTargetGuid, guid);
|
||||
project.WriteToFile(projectPath);
|
||||
}
|
||||
|
||||
private static void EnableConsentFlowIfNeeded(PlistDocument applovinSettingsPlist, PlistDocument infoPlist)
|
||||
{
|
||||
var consentFlowEnabled = AppLovinInternalSettings.Instance.ConsentFlowEnabled;
|
||||
if (!consentFlowEnabled) return;
|
||||
|
||||
var userTrackingUsageDescription = AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEn;
|
||||
var privacyPolicyUrl = AppLovinInternalSettings.Instance.ConsentFlowPrivacyPolicyUrl;
|
||||
if (string.IsNullOrEmpty(userTrackingUsageDescription) || string.IsNullOrEmpty(privacyPolicyUrl))
|
||||
{
|
||||
AppLovinIntegrationManager.ShowBuildFailureDialog("You cannot use the AppLovin SDK's consent flow without defining a Privacy Policy URL and the `User Tracking Usage Description` in the AppLovin Integration Manager. \n\n" +
|
||||
"Both values must be included to enable the SDK's consent flow.");
|
||||
|
||||
// No need to update the info.plist here. Default consent flow state will be determined on the SDK side.
|
||||
return;
|
||||
}
|
||||
|
||||
var consentFlowInfoRoot = applovinSettingsPlist.root.CreateDict(KeyConsentFlowInfo);
|
||||
consentFlowInfoRoot.SetBoolean(KeyConsentFlowEnabled, consentFlowEnabled);
|
||||
consentFlowInfoRoot.SetString(KeyConsentFlowPrivacyPolicy, privacyPolicyUrl);
|
||||
|
||||
var termsOfServiceUrl = AppLovinInternalSettings.Instance.ConsentFlowTermsOfServiceUrl;
|
||||
if (MaxSdkUtils.IsValidString(termsOfServiceUrl))
|
||||
{
|
||||
consentFlowInfoRoot.SetString(KeyConsentFlowTermsOfService, termsOfServiceUrl);
|
||||
}
|
||||
|
||||
var shouldShowTermsAndPrivacyPolicyAlertInGdpr = AppLovinInternalSettings.Instance.ShouldShowTermsAndPrivacyPolicyAlertInGDPR;
|
||||
consentFlowInfoRoot.SetBoolean(KeyConsentFlowShowTermsAndPrivacyPolicyAlertInGDPR, shouldShowTermsAndPrivacyPolicyAlertInGdpr);
|
||||
|
||||
var debugUserGeography = AppLovinInternalSettings.Instance.DebugUserGeography;
|
||||
if (debugUserGeography == MaxSdkBase.ConsentFlowUserGeography.Gdpr)
|
||||
{
|
||||
consentFlowInfoRoot.SetString(KeyConsentFlowDebugUserGeography, "gdpr");
|
||||
}
|
||||
|
||||
infoPlist.root.SetString("NSUserTrackingUsageDescription", userTrackingUsageDescription);
|
||||
}
|
||||
|
||||
private static void AddSkAdNetworksInfoIfNeeded(PlistDocument plist)
|
||||
{
|
||||
var skAdNetworkData = GetSkAdNetworkData();
|
||||
var skAdNetworkIds = skAdNetworkData.SkAdNetworkIds;
|
||||
// Check if we have a valid list of SKAdNetworkIds that need to be added.
|
||||
if (skAdNetworkIds == null || skAdNetworkIds.Length < 1) return;
|
||||
|
||||
//
|
||||
// Add the SKAdNetworkItems to the plist. It should look like following:
|
||||
//
|
||||
// <key>SKAdNetworkItems</key>
|
||||
// <array>
|
||||
// <dict>
|
||||
// <key>SKAdNetworkIdentifier</key>
|
||||
// <string>ABC123XYZ.skadnetwork</string>
|
||||
// </dict>
|
||||
// <dict>
|
||||
// <key>SKAdNetworkIdentifier</key>
|
||||
// <string>123QWE456.skadnetwork</string>
|
||||
// </dict>
|
||||
// <dict>
|
||||
// <key>SKAdNetworkIdentifier</key>
|
||||
// <string>987XYZ123.skadnetwork</string>
|
||||
// </dict>
|
||||
// </array>
|
||||
//
|
||||
PlistElement skAdNetworkItems;
|
||||
plist.root.values.TryGetValue("SKAdNetworkItems", out skAdNetworkItems);
|
||||
var existingSkAdNetworkIds = new HashSet<string>();
|
||||
// Check if SKAdNetworkItems array is already in the Plist document and collect all the IDs that are already present.
|
||||
if (skAdNetworkItems != null && skAdNetworkItems.GetType() == typeof(PlistElementArray))
|
||||
{
|
||||
var plistElementDictionaries = skAdNetworkItems.AsArray().values.Where(plistElement => plistElement.GetType() == typeof(PlistElementDict));
|
||||
foreach (var plistElement in plistElementDictionaries)
|
||||
{
|
||||
PlistElement existingId;
|
||||
plistElement.AsDict().values.TryGetValue("SKAdNetworkIdentifier", out existingId);
|
||||
if (existingId == null || existingId.GetType() != typeof(PlistElementString) || string.IsNullOrEmpty(existingId.AsString())) continue;
|
||||
|
||||
existingSkAdNetworkIds.Add(existingId.AsString());
|
||||
}
|
||||
}
|
||||
// Else, create an array of SKAdNetworkItems into which we will add our IDs.
|
||||
else
|
||||
{
|
||||
skAdNetworkItems = plist.root.CreateArray("SKAdNetworkItems");
|
||||
}
|
||||
|
||||
foreach (var skAdNetworkId in skAdNetworkIds)
|
||||
{
|
||||
// Skip adding IDs that are already in the array.
|
||||
if (existingSkAdNetworkIds.Contains(skAdNetworkId)) continue;
|
||||
|
||||
var skAdNetworkItemDict = skAdNetworkItems.AsArray().AddDict();
|
||||
skAdNetworkItemDict.SetString("SKAdNetworkIdentifier", skAdNetworkId);
|
||||
}
|
||||
}
|
||||
|
||||
private static SkAdNetworkData GetSkAdNetworkData()
|
||||
{
|
||||
// Get the list of installed ad networks to be passed up
|
||||
var installedNetworks = AppLovinPackageManager.GetInstalledMediationNetworks();
|
||||
var uriBuilder = new UriBuilder("https://unity.applovin.com/max/1.0/skadnetwork_ids");
|
||||
var adNetworks = string.Join(",", installedNetworks.ToArray());
|
||||
if (MaxSdkUtils.IsValidString(adNetworks))
|
||||
{
|
||||
uriBuilder.Query += string.Format("ad_networks={0}", adNetworks);
|
||||
}
|
||||
|
||||
var webRequestConfig = new WebRequestConfig()
|
||||
{
|
||||
EndPoint = uriBuilder.ToString()
|
||||
};
|
||||
|
||||
var maxWebRequest = new MaxWebRequest(webRequestConfig);
|
||||
var webResponse = maxWebRequest.SendSync();
|
||||
|
||||
if (!webResponse.IsSuccess)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to retrieve SKAdNetwork IDs with error: " + webResponse.ErrorMessage);
|
||||
return new SkAdNetworkData();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return JsonUtility.FromJson<SkAdNetworkData>(webResponse.ResponseMessage);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to parse data '" + webResponse.ResponseMessage + "' with exception: " + exception);
|
||||
return new SkAdNetworkData();
|
||||
}
|
||||
}
|
||||
|
||||
private static void RemoveSdkKeyIfNeeded(PlistDocument plist)
|
||||
{
|
||||
if (!plist.root.values.ContainsKey(KeyAppLovinSdkKeyToRemove)) return;
|
||||
|
||||
plist.root.values.Remove(KeyAppLovinSdkKeyToRemove);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5d209f90444f4a90830b48b5f3f3ff4
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPostProcessiOS.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,182 @@
|
||||
//
|
||||
// AppLovinPreProcess.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Jonathan Liu on 10/19/2023.
|
||||
// Copyright © 2023 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
public abstract class AppLovinPreProcess
|
||||
{
|
||||
// Use a slightly lower value than max value so pubs have the option to run a post process script after ours.
|
||||
internal const int CallbackOrder = int.MaxValue - 10;
|
||||
private const string AppLovinDependenciesFileExportPath = "MaxSdk/AppLovin/Editor/Dependencies.xml";
|
||||
private const string ElementNameDependencies = "dependencies";
|
||||
|
||||
private static readonly XmlWriterSettings DependenciesFileXmlWriterSettings = new XmlWriterSettings
|
||||
{
|
||||
Indent = true,
|
||||
IndentChars = " ",
|
||||
NewLineChars = "\n",
|
||||
NewLineHandling = NewLineHandling.Replace
|
||||
};
|
||||
|
||||
protected static string AppLovinDependenciesFilePath
|
||||
{
|
||||
get { return AppLovinIntegrationManager.IsPluginInPackageManager ? Path.Combine("Assets", AppLovinDependenciesFileExportPath) : MaxSdkUtils.GetAssetPathForExportPath(AppLovinDependenciesFileExportPath); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the AppLovin Dependencies.xml file. If `createIfNotExists` is true, a new file will be created if one does not exist.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the AppLovin Dependencies.xml file</param>
|
||||
/// <param name="createIfNotExists">Whether to create a new Dependencies.xml file if one does not exist</param>
|
||||
/// <returns></returns>
|
||||
protected static XDocument GetAppLovinDependenciesFile(string path, bool createIfNotExists = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
return XDocument.Load(path);
|
||||
}
|
||||
|
||||
if (createIfNotExists)
|
||||
{
|
||||
return new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
|
||||
new XElement(ElementNameDependencies));
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.E("Unable to load Dependencies file due to exception: " + exception.Message);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates a dependency if it exists, otherwise adds a new dependency.
|
||||
/// </summary>
|
||||
/// <param name="dependenciesDocument">The dependencies document we are writing to</param>
|
||||
/// <param name="parentTag">The parent tag that we want to search for the dependency. For example, to add a new dependency to Android, pass in "androidPackages"</param>
|
||||
/// <param name="elementTag">The element we are looking to update/add. For example, to add a new dependency to Android, pass in "androidPackage"</param>
|
||||
/// <param name="matchAttribute">The attribute name we want in the dependency. For example, to add something to the spec attribute, pass in "spec" </param>
|
||||
/// <param name="matchValuePrefix">The attribute value prefix we are looking to replace. For example, "com.google.android.ump:user-messaging-platform"</param>
|
||||
/// <param name="newDependency">The new dependency we want to add.</param>
|
||||
protected static void AddOrUpdateDependency(
|
||||
XDocument dependenciesDocument,
|
||||
string parentTag,
|
||||
string elementTag,
|
||||
string matchAttribute,
|
||||
string matchValuePrefix,
|
||||
XElement newDependency)
|
||||
{
|
||||
var parentElement = dependenciesDocument.Root.Element(parentTag);
|
||||
if (parentElement == null)
|
||||
{
|
||||
parentElement = new XElement(parentTag);
|
||||
dependenciesDocument.Root.Add(parentElement);
|
||||
}
|
||||
|
||||
// Check if a dependency exists that matches the attributes name and value
|
||||
var existingElement = parentElement.Elements(elementTag)
|
||||
.FirstOrDefault(element =>
|
||||
{
|
||||
var attr = element.Attribute(matchAttribute);
|
||||
return attr != null && attr.Value.StartsWith(matchValuePrefix, StringComparison.OrdinalIgnoreCase);
|
||||
});
|
||||
|
||||
if (existingElement != null)
|
||||
{
|
||||
foreach (var attr in newDependency.Attributes())
|
||||
{
|
||||
existingElement.SetAttributeValue(attr.Name, attr.Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parentElement.Add(newDependency);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a dependency from an xml file.
|
||||
/// </summary>
|
||||
/// <param name="doc">The xml file to remove a dependency from</param>
|
||||
/// <param name="parentTag">The parent tag that we want to search for the dependency to remove. For example: "androidPackages"</param>
|
||||
/// <param name="elementTag">The element we are looking to remove. For example: "androidPackage"</param>
|
||||
/// <param name="matchAttribute">The attribute name we want to remove. For example: "spec" </param>
|
||||
/// <param name="matchValuePrefix">The attribute value prefix we are looking to replace. For example: "com.google.android.ump:user-messaging-platform"</param>
|
||||
/// <returns>True if the dependency was removed successfully, otherwise return false.</returns>
|
||||
protected static bool RemoveDependency(
|
||||
XDocument doc,
|
||||
string parentTag,
|
||||
string elementTag,
|
||||
string matchAttribute,
|
||||
string matchValuePrefix)
|
||||
{
|
||||
var root = doc.Root;
|
||||
if (root == null) return false;
|
||||
|
||||
var parentElement = root.Element(parentTag);
|
||||
if (parentElement == null) return false;
|
||||
|
||||
XElement toRemove = null;
|
||||
foreach (var e in parentElement.Elements(elementTag))
|
||||
{
|
||||
var attr = e.Attribute(matchAttribute);
|
||||
if (attr != null && attr.Value.StartsWith(matchValuePrefix))
|
||||
{
|
||||
toRemove = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (toRemove == null) return false;
|
||||
|
||||
toRemove.Remove();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves an xml file.
|
||||
/// </summary>
|
||||
/// <param name="doc">The document to save</param>
|
||||
/// <param name="path">The path to the document to save</param>
|
||||
/// <returns>Returns true if the file was saved successfully</returns>
|
||||
protected static bool SaveDependenciesFile(XDocument doc, string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Ensure directory exists before saving the file
|
||||
var directory = Path.GetDirectoryName(path);
|
||||
if (MaxSdkUtils.IsValidString(directory))
|
||||
{
|
||||
// Does nothing if directory already exists
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
using (var xmlWriter = XmlWriter.Create(path, DependenciesFileXmlWriterSettings))
|
||||
{
|
||||
doc.Save(xmlWriter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.E("Unable to save Dependencies file due to exception: " + exception.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e6254f24e89548b3a7644fa7bf25f9d
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPreProcess.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,111 @@
|
||||
//
|
||||
// AppLovinBuildPreProcessor.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 8/27/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_ANDROID
|
||||
|
||||
using System.Xml.Linq;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the AppLovin Quality Service plugin to the gradle template file. See <see cref="AppLovinProcessGradleBuildFile"/> for more details.
|
||||
/// </summary>
|
||||
public class AppLovinPreProcessAndroid : AppLovinProcessGradleBuildFile, IPreprocessBuildWithReport
|
||||
{
|
||||
private const string ElementNameAndroidPackages = "androidPackages";
|
||||
private const string ElementNameAndroidPackage = "androidPackage";
|
||||
private const string AttributeNameSpec = "spec";
|
||||
private const string UmpDependencyPackage = "com.google.android.ump:user-messaging-platform:";
|
||||
private const string UmpDependencyVersion = "2.1.0";
|
||||
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
PreprocessAppLovinQualityServicePlugin();
|
||||
AddGoogleCmpDependencyIfNeeded();
|
||||
}
|
||||
|
||||
private static void PreprocessAppLovinQualityServicePlugin()
|
||||
{
|
||||
// We can only process gradle template file here. If it is not available, we will try again in post build on Unity IDEs newer than 2018_2 (see AppLovinPostProcessGradleProject).
|
||||
if (!AppLovinIntegrationManager.GradleTemplateEnabled) return;
|
||||
|
||||
// The publisher could be migrating from older Unity versions to 2019_3 or newer.
|
||||
// If so, we should delete the plugin from the template. The plugin will be added to the project's application module in the post processing script (AppLovinPostProcessGradleProject).
|
||||
RemoveAppLovinQualityServiceOrSafeDkPlugin(AppLovinIntegrationManager.GradleTemplatePath);
|
||||
}
|
||||
|
||||
private static void AddGoogleCmpDependencyIfNeeded()
|
||||
{
|
||||
if (AppLovinInternalSettings.Instance.ConsentFlowEnabled)
|
||||
{
|
||||
var umpPackage = new XElement(ElementNameAndroidPackage,
|
||||
new XAttribute(AttributeNameSpec, UmpDependencyPackage + UmpDependencyVersion));
|
||||
var success = AddOrUpdateAndroidDependency(UmpDependencyPackage, umpPackage );
|
||||
if (!success)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("Google CMP will not function. Unable to add user-messaging-platform dependency.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveAndroidDependency(UmpDependencyPackage);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds or updates an Android dependency in the AppLovin Dependencies.xml file.
|
||||
/// </summary>
|
||||
/// <param name="package">The package that we are trying to update</param>
|
||||
/// <param name="newDependency">The new dependency to add if it doesn't exist</param>
|
||||
/// <returns>Returns true if the file was successfully edited</returns>
|
||||
private static bool AddOrUpdateAndroidDependency(string package, XElement newDependency)
|
||||
{
|
||||
var dependenciesFilePath = AppLovinDependenciesFilePath;
|
||||
var dependenciesDocument = GetAppLovinDependenciesFile(dependenciesFilePath, AppLovinIntegrationManager.IsPluginInPackageManager);
|
||||
if (dependenciesDocument == null) return false;
|
||||
|
||||
AddOrUpdateDependency(dependenciesDocument,
|
||||
ElementNameAndroidPackages,
|
||||
ElementNameAndroidPackage,
|
||||
AttributeNameSpec,
|
||||
package,
|
||||
newDependency);
|
||||
return SaveDependenciesFile(dependenciesDocument, dependenciesFilePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removed an android dependency from the AppLovin Dependencies.xml file.
|
||||
/// </summary>
|
||||
/// <param name="package">The package to remove</param>
|
||||
private static void RemoveAndroidDependency(string package)
|
||||
{
|
||||
var dependenciesFilePath = AppLovinDependenciesFilePath;
|
||||
var dependenciesDocument = GetAppLovinDependenciesFile(dependenciesFilePath);
|
||||
if (dependenciesDocument == null) return;
|
||||
|
||||
var removed = RemoveDependency(dependenciesDocument,
|
||||
ElementNameAndroidPackages,
|
||||
ElementNameAndroidPackage,
|
||||
AttributeNameSpec,
|
||||
package);
|
||||
|
||||
if (!removed) return;
|
||||
|
||||
SaveDependenciesFile(dependenciesDocument, dependenciesFilePath);
|
||||
}
|
||||
|
||||
public int callbackOrder
|
||||
{
|
||||
get { return CallbackOrder; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ccaf444d0d4f4cadb5debe7c41b20c4
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPreProcessAndroid.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,99 @@
|
||||
//
|
||||
// AppLovinBuildPreProcessiOS.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Jonathan Liu on 10/17/2023.
|
||||
// Copyright © 2023 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_IOS
|
||||
|
||||
using System.Xml.Linq;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
public class AppLovinPreProcessiOS : AppLovinPreProcess, IPreprocessBuildWithReport
|
||||
{
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
{
|
||||
AddGoogleCmpDependencyIfNeeded();
|
||||
}
|
||||
|
||||
private const string ElementNameIosPods = "iosPods";
|
||||
private const string ElementNameIosPod = "iosPod";
|
||||
private const string AttributeNameName = "name";
|
||||
private const string AttributeNameVersion = "version";
|
||||
private const string UmpDependencyPod = "GoogleUserMessagingPlatform";
|
||||
private const string UmpDependencyVersion = "~> 2.1";
|
||||
|
||||
private static void AddGoogleCmpDependencyIfNeeded()
|
||||
{
|
||||
if (AppLovinInternalSettings.Instance.ConsentFlowEnabled)
|
||||
{
|
||||
var umpDependency = new XElement(ElementNameIosPod,
|
||||
new XAttribute(AttributeNameName, UmpDependencyPod),
|
||||
new XAttribute(AttributeNameVersion, UmpDependencyVersion));
|
||||
var success = AddOrUpdateIosDependency(UmpDependencyPod, umpDependency);
|
||||
if (!success)
|
||||
{
|
||||
MaxSdkLogger.UserWarning("Google CMP will not function. Unable to add GoogleUserMessagingPlatform dependency.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveIosDependency(UmpDependencyPod);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds or updates an iOS pod in the AppLovin Dependencies.xml file.
|
||||
/// </summary>
|
||||
/// <param name="pod">The pod that we are trying to update</param>
|
||||
/// <param name="newDependency">The new dependency to add if it doesn't exist</param>
|
||||
/// <returns>Returns true if the file was successfully edited</returns>
|
||||
private static bool AddOrUpdateIosDependency(string pod, XElement newDependency)
|
||||
{
|
||||
var dependenciesFilePath = AppLovinDependenciesFilePath;
|
||||
var dependenciesDocument = GetAppLovinDependenciesFile(dependenciesFilePath, AppLovinIntegrationManager.IsPluginInPackageManager);
|
||||
if (dependenciesDocument == null) return false;
|
||||
|
||||
AddOrUpdateDependency(dependenciesDocument,
|
||||
ElementNameIosPods,
|
||||
ElementNameIosPod,
|
||||
AttributeNameName,
|
||||
pod,
|
||||
newDependency);
|
||||
return SaveDependenciesFile(dependenciesDocument, dependenciesFilePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removed an iOS pod from the AppLovin Dependencies.xml file.
|
||||
/// </summary>
|
||||
/// <param name="pod">The pod to remove</param>
|
||||
private static void RemoveIosDependency(string pod)
|
||||
{
|
||||
var dependenciesFilePath = AppLovinDependenciesFilePath;
|
||||
var dependenciesDocument = GetAppLovinDependenciesFile(dependenciesFilePath);
|
||||
if (dependenciesDocument == null) return;
|
||||
|
||||
var removed = RemoveDependency(dependenciesDocument,
|
||||
ElementNameIosPods,
|
||||
ElementNameIosPod,
|
||||
AttributeNameName,
|
||||
pod);
|
||||
|
||||
if (!removed) return;
|
||||
|
||||
SaveDependenciesFile(dependenciesDocument, dependenciesFilePath);
|
||||
}
|
||||
|
||||
public int callbackOrder
|
||||
{
|
||||
get { return CallbackOrder; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee45537a5833240d7afcfac4a38df1b9
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinPreProcessiOS.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,658 @@
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 9/3/19.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_ANDROID
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using AppLovinMax.Internal;
|
||||
using UnityEngine;
|
||||
using UnityEngine.PlayerLoop;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
[Serializable]
|
||||
public class AppLovinQualityServiceData
|
||||
{
|
||||
// ReSharper disable once InconsistentNaming - Need to keep name for response data
|
||||
public string api_key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds or updates the AppLovin Quality Service plugin to the provided build.gradle file.
|
||||
/// If the gradle file already has the plugin, the API key is updated.
|
||||
/// </summary>
|
||||
public abstract class AppLovinProcessGradleBuildFile : AppLovinPreProcess
|
||||
{
|
||||
private static readonly Regex TokenBuildScriptRepositories = new Regex(".*repositories.*");
|
||||
private static readonly Regex TokenBuildScriptDependencies = new Regex(".*classpath \'com.android.tools.build:gradle.*");
|
||||
private static readonly Regex TokenApplicationPlugin = new Regex(".*apply plugin: \'com.android.application\'.*");
|
||||
private static readonly Regex TokenApiKey = new Regex(".*apiKey.*");
|
||||
private static readonly Regex TokenAppLovinPlugin = new Regex(".*apply plugin:.+?(?=applovin-quality-service).*");
|
||||
|
||||
private const string PluginsMatcher = "plugins";
|
||||
private const string PluginManagementMatcher = "pluginManagement";
|
||||
private const string QualityServicePluginRoot = " id 'com.applovin.quality' version '+' apply false // NOTE: Requires version 4.8.3+ for Gradle version 7.2+";
|
||||
|
||||
private const string BuildScriptMatcher = "buildscript";
|
||||
private const string QualityServiceMavenRepo = "maven { url 'https://artifacts.applovin.com/android'; content { includeGroupByRegex 'com.applovin.*' } }";
|
||||
private const string QualityServiceDependencyClassPath = "classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:+'";
|
||||
private const string QualityServiceApplyPlugin = "apply plugin: 'applovin-quality-service'";
|
||||
private const string QualityServicePlugin = "applovin {";
|
||||
private const string QualityServiceApiKey = " apiKey '{0}'";
|
||||
private const string QualityServiceBintrayMavenRepo = "https://applovin.bintray.com/Quality-Service";
|
||||
private const string QualityServiceNoRegexMavenRepo = "maven { url 'https://artifacts.applovin.com/android' }";
|
||||
|
||||
// Legacy plugin detection variables
|
||||
private const string QualityServiceDependencyClassPathV3 = "classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:3.+'";
|
||||
private static readonly Regex TokenSafeDkLegacyApplyPlugin = new Regex(".*apply plugin:.+?(?=safedk).*");
|
||||
private const string SafeDkLegacyPlugin = "safedk {";
|
||||
private const string SafeDkLegacyMavenRepo = "http://download.safedk.com";
|
||||
private const string SafeDkLegacyDependencyClassPath = "com.safedk:SafeDKGradlePlugin:";
|
||||
|
||||
/// <summary>
|
||||
/// Adds the Quality Service plugin to the root gradle file.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the unityLibrary's module.</param>
|
||||
/// <returns>True if the plugin was added successfully, otherwise return false</returns>
|
||||
protected static bool AddQualityServiceToRootGradleFile(string path)
|
||||
{
|
||||
var rootGradleBuildFilePath = Path.Combine(path, "../build.gradle");
|
||||
var shouldAddQualityServiceToDependencies = ShouldAddQualityServiceToDependencies(rootGradleBuildFilePath);
|
||||
|
||||
if (shouldAddQualityServiceToDependencies)
|
||||
{
|
||||
// Add the Quality Service Plugin to the dependencies block in the root build.gradle file
|
||||
return AddQualityServiceBuildScriptLines(rootGradleBuildFilePath);
|
||||
}
|
||||
|
||||
// Add the Quality Service Plugin to the plugin block in the root build.gradle file
|
||||
var rootSettingsGradleFilePath = Path.Combine(path, "../settings.gradle");
|
||||
var qualityServiceAdded = AddPluginToRootGradleBuildFile(rootGradleBuildFilePath);
|
||||
var appLovinRepositoryAdded = AddAppLovinRepository(rootSettingsGradleFilePath);
|
||||
return qualityServiceAdded && appLovinRepositoryAdded;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the AppLovin Quality Service plugin should be added to the
|
||||
/// dependencies block in the root build.gradle file or to the plugins block.
|
||||
///
|
||||
/// Gradle's required structure for including plugins varies by version:
|
||||
/// - Older versions of Gradle require the plugin to be added to the dependencies block.
|
||||
/// Example:
|
||||
/// dependencies {
|
||||
/// classpath 'com.android.tools.build:gradle:4.0.1'
|
||||
/// classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:+'
|
||||
/// }
|
||||
///
|
||||
/// - Newer versions of gradle require the plugin to be added to the plugins block.
|
||||
/// Example:
|
||||
/// plugins {
|
||||
/// id 'com.android.application' version '7.4.2' apply false
|
||||
/// id 'com.android.library' version '7.4.2' apply false
|
||||
/// id 'com.applovin.quality' version '+' apply false
|
||||
/// }
|
||||
///
|
||||
/// Since Unity projects may use custom Gradle versions depending on the Unity version or
|
||||
/// user modifications, this check ensures proper integration of the AppLovin plugin.
|
||||
/// </summary>
|
||||
/// <param name="rootGradleBuildFile">The path to project's root build.gradle file.</param>
|
||||
/// <returns><c>true</c> if the file contains a `dependencies` block, indicating an older Gradle version</returns>
|
||||
private static bool ShouldAddQualityServiceToDependencies(string rootGradleBuildFile)
|
||||
{
|
||||
var lines = File.ReadAllLines(rootGradleBuildFile).ToList();
|
||||
return lines.Any(line => TokenBuildScriptDependencies.IsMatch(line));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the provided Gradle script to add Quality Service plugin.
|
||||
/// </summary>
|
||||
/// <param name="applicationGradleBuildFilePath">The gradle file to update.</param>
|
||||
protected static void AddAppLovinQualityServicePlugin(string applicationGradleBuildFilePath)
|
||||
{
|
||||
if (!AppLovinSettings.Instance.QualityServiceEnabled) return;
|
||||
|
||||
var sdkKey = AppLovinSettings.Instance.SdkKey;
|
||||
if (string.IsNullOrEmpty(sdkKey))
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. SDK Key is empty. Please enter the AppLovin SDK Key in the Integration Manager.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve the API Key using the SDK Key.
|
||||
var qualityServiceData = RetrieveQualityServiceData(sdkKey);
|
||||
var apiKey = qualityServiceData.api_key;
|
||||
if (string.IsNullOrEmpty(apiKey))
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. API Key is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate the updated Gradle file that needs to be written.
|
||||
var lines = File.ReadAllLines(applicationGradleBuildFilePath).ToList();
|
||||
var sanitizedLines = RemoveLegacySafeDkPlugin(lines);
|
||||
var outputLines = GenerateUpdatedBuildFileLines(
|
||||
sanitizedLines,
|
||||
apiKey,
|
||||
false // The buildscript closure related lines will to be added to the root build.gradle file.
|
||||
);
|
||||
// outputLines can be null if we couldn't add the plugin.
|
||||
if (outputLines == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(applicationGradleBuildFilePath, string.Join("\n", outputLines.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Gradle file write failed.");
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds AppLovin Quality Service plugin DSL element to the project's root build.gradle file.
|
||||
/// Sample build.gradle file after adding quality service:
|
||||
/// plugins {
|
||||
/// id 'com.android.application' version '7.4.2' apply false
|
||||
/// id 'com.android.library' version '7.4.2' apply false
|
||||
/// id 'com.applovin.quality' version '+' apply false
|
||||
/// }
|
||||
/// tasks.register('clean', Delete) {
|
||||
/// delete rootProject.layout.buildDirectory
|
||||
/// }
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="rootGradleBuildFile">The path to project's root build.gradle file.</param>
|
||||
/// <returns><c>true</c> when the plugin was added successfully.</returns>
|
||||
private static bool AddPluginToRootGradleBuildFile(string rootGradleBuildFile)
|
||||
{
|
||||
var lines = File.ReadAllLines(rootGradleBuildFile).ToList();
|
||||
|
||||
// Check if the plugin is already added to the file.
|
||||
var pluginAdded = lines.Any(line => line.Contains(QualityServicePluginRoot));
|
||||
if (pluginAdded) return true;
|
||||
|
||||
var outputLines = new List<string>();
|
||||
var insidePluginsClosure = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (line.Contains(PluginsMatcher))
|
||||
{
|
||||
insidePluginsClosure = true;
|
||||
}
|
||||
|
||||
if (!pluginAdded && insidePluginsClosure && line.Contains("}"))
|
||||
{
|
||||
outputLines.Add(QualityServicePluginRoot);
|
||||
pluginAdded = true;
|
||||
insidePluginsClosure = false;
|
||||
}
|
||||
|
||||
outputLines.Add(line);
|
||||
}
|
||||
|
||||
if (!pluginAdded) return false;
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(rootGradleBuildFile, string.Join("\n", outputLines.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Root Gradle file write failed.");
|
||||
Console.WriteLine(exception);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the AppLovin maven repository to the project's settings.gradle file.
|
||||
/// Sample settings.gradle file after adding AppLovin Repository:
|
||||
/// pluginManagement {
|
||||
/// repositories {
|
||||
/// maven { url 'https://artifacts.applovin.com/android'; content { includeGroupByRegex 'com.applovin.*' } }
|
||||
///
|
||||
/// gradlePluginPortal()
|
||||
/// google()
|
||||
/// mavenCentral()
|
||||
/// }
|
||||
/// }
|
||||
/// ...
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="settingsGradleFile">The path to the project's settings.gradle file.</param>
|
||||
/// <returns><c>true</c> if the repository was added successfully.</returns>
|
||||
private static bool AddAppLovinRepository(string settingsGradleFile)
|
||||
{
|
||||
var lines = File.ReadLines(settingsGradleFile).ToList();
|
||||
var outputLines = new List<string>();
|
||||
var mavenRepoAdded = false;
|
||||
var pluginManagementClosureDepth = 0;
|
||||
var insidePluginManagementClosure = false;
|
||||
var pluginManagementMatched = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
outputLines.Add(line);
|
||||
|
||||
if (!pluginManagementMatched && line.Contains(PluginManagementMatcher))
|
||||
{
|
||||
pluginManagementMatched = true;
|
||||
insidePluginManagementClosure = true;
|
||||
}
|
||||
|
||||
if (insidePluginManagementClosure)
|
||||
{
|
||||
if (line.Contains("{"))
|
||||
{
|
||||
pluginManagementClosureDepth++;
|
||||
}
|
||||
|
||||
if (line.Contains("}"))
|
||||
{
|
||||
pluginManagementClosureDepth--;
|
||||
}
|
||||
|
||||
if (pluginManagementClosureDepth == 0)
|
||||
{
|
||||
insidePluginManagementClosure = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (insidePluginManagementClosure)
|
||||
{
|
||||
if (!mavenRepoAdded && TokenBuildScriptRepositories.IsMatch(line))
|
||||
{
|
||||
outputLines.Add(GetFormattedBuildScriptLine(QualityServiceMavenRepo));
|
||||
mavenRepoAdded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mavenRepoAdded) return false;
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(settingsGradleFile, string.Join("\n", outputLines.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Setting Gradle file write failed.");
|
||||
Console.WriteLine(exception);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the necessary AppLovin Quality Service dependency and maven repo lines to the provided root build.gradle file.
|
||||
/// Sample build.gradle file after adding quality service:
|
||||
/// allprojects {
|
||||
/// buildscript {
|
||||
/// repositories {
|
||||
/// maven { url 'https://artifacts.applovin.com/android'; content { includeGroupByRegex 'com.applovin.*' } }
|
||||
/// google()
|
||||
/// jcenter()
|
||||
/// }
|
||||
///
|
||||
/// dependencies {
|
||||
/// classpath 'com.android.tools.build:gradle:4.0.1'
|
||||
/// classpath 'com.applovin.quality:AppLovinQualityServiceGradlePlugin:+'
|
||||
/// }
|
||||
/// ...
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="rootGradleBuildFile">The root build.gradle file path</param>
|
||||
/// <returns><c>true</c> if the build script lines were applied correctly.</returns>
|
||||
private static bool AddQualityServiceBuildScriptLines(string rootGradleBuildFile)
|
||||
{
|
||||
var lines = File.ReadAllLines(rootGradleBuildFile).ToList();
|
||||
var outputLines = GenerateUpdatedBuildFileLines(lines, null, true);
|
||||
|
||||
// outputLines will be null if we couldn't add the build script lines.
|
||||
if (outputLines == null) return false;
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(rootGradleBuildFile, string.Join("\n", outputLines.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to install AppLovin Quality Service plugin. Root Gradle file write failed.");
|
||||
Console.WriteLine(exception);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the AppLovin Quality Service Plugin or Legacy SafeDK plugin from the given gradle template file if either of them are present.
|
||||
/// </summary>
|
||||
/// <param name="gradleTemplateFile">The gradle template file from which to remove the plugin from</param>
|
||||
protected static void RemoveAppLovinQualityServiceOrSafeDkPlugin(string gradleTemplateFile)
|
||||
{
|
||||
var lines = File.ReadAllLines(gradleTemplateFile).ToList();
|
||||
lines = RemoveLegacySafeDkPlugin(lines);
|
||||
lines = RemoveAppLovinQualityServicePlugin(lines);
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllText(gradleTemplateFile, string.Join("\n", lines.ToArray()) + "\n");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to remove AppLovin Quality Service Plugin from mainTemplate.gradle. Please remove the Quality Service plugin from the mainTemplate.gradle manually.");
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static AppLovinQualityServiceData RetrieveQualityServiceData(string sdkKey)
|
||||
{
|
||||
var webRequestConfig = new WebRequestConfig()
|
||||
{
|
||||
JsonString = string.Format("{{\"sdk_key\" : \"{0}\"}}", sdkKey),
|
||||
EndPoint = "https://api2.safedk.com/v1/build/cred",
|
||||
RequestType = WebRequestType.Post,
|
||||
};
|
||||
|
||||
webRequestConfig.Headers.Add("Content-Type", "application/json");
|
||||
|
||||
var maxWebRequest = new MaxWebRequest(webRequestConfig);
|
||||
var webResponse = maxWebRequest.SendSync();
|
||||
|
||||
if (!webResponse.IsSuccess)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to retrieve API Key for SDK Key: " + sdkKey + "with error: " + webResponse.ErrorMessage);
|
||||
return new AppLovinQualityServiceData();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return JsonUtility.FromJson<AppLovinQualityServiceData>(webResponse.ResponseMessage);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to parse API Key." + exception);
|
||||
return new AppLovinQualityServiceData();
|
||||
}
|
||||
}
|
||||
|
||||
private static List<string> RemoveLegacySafeDkPlugin(List<string> lines)
|
||||
{
|
||||
return RemovePlugin(lines, SafeDkLegacyPlugin, SafeDkLegacyMavenRepo, SafeDkLegacyDependencyClassPath, TokenSafeDkLegacyApplyPlugin);
|
||||
}
|
||||
|
||||
private static List<string> RemoveAppLovinQualityServicePlugin(List<string> lines)
|
||||
{
|
||||
return RemovePlugin(lines, QualityServicePlugin, QualityServiceMavenRepo, QualityServiceDependencyClassPath, TokenAppLovinPlugin);
|
||||
}
|
||||
|
||||
private static List<string> RemovePlugin(List<string> lines, string pluginLine, string mavenRepo, string dependencyClassPath, Regex applyPluginToken)
|
||||
{
|
||||
var sanitizedLines = new List<string>();
|
||||
var legacyRepoRemoved = false;
|
||||
var legacyDependencyClassPathRemoved = false;
|
||||
var legacyPluginRemoved = false;
|
||||
var legacyPluginMatched = false;
|
||||
var insideLegacySafeDkClosure = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
if (!legacyPluginMatched && line.Contains(pluginLine))
|
||||
{
|
||||
legacyPluginMatched = true;
|
||||
insideLegacySafeDkClosure = true;
|
||||
}
|
||||
|
||||
if (insideLegacySafeDkClosure && line.Contains("}"))
|
||||
{
|
||||
insideLegacySafeDkClosure = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (insideLegacySafeDkClosure)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!legacyRepoRemoved && line.Contains(mavenRepo))
|
||||
{
|
||||
legacyRepoRemoved = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!legacyDependencyClassPathRemoved && line.Contains(dependencyClassPath))
|
||||
{
|
||||
legacyDependencyClassPathRemoved = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!legacyPluginRemoved && applyPluginToken.IsMatch(line))
|
||||
{
|
||||
legacyPluginRemoved = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
sanitizedLines.Add(line);
|
||||
}
|
||||
|
||||
return sanitizedLines;
|
||||
}
|
||||
|
||||
private static List<string> GenerateUpdatedBuildFileLines(List<string> lines, string apiKey, bool addBuildScriptLines)
|
||||
{
|
||||
// Check if the plugin exists, if so, update the SDK Key.
|
||||
var pluginExists = lines.Any(line => TokenAppLovinPlugin.IsMatch(line));
|
||||
return pluginExists ? UpdateExistingPlugin(lines, apiKey) : AddPluginAndBuildScript(lines, apiKey, addBuildScriptLines);
|
||||
}
|
||||
|
||||
private static List<string> UpdateExistingPlugin(List<string> lines, string apiKey)
|
||||
{
|
||||
// A sample of the template file.
|
||||
// ...
|
||||
// allprojects {
|
||||
// repositories {**ARTIFACTORYREPOSITORY**
|
||||
// google()
|
||||
// jcenter()
|
||||
// flatDir {
|
||||
// dirs 'libs'
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// apply plugin: 'com.android.application'
|
||||
// **APPLY_PLUGINS**
|
||||
//
|
||||
// dependencies {
|
||||
// implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
// **DEPS**}
|
||||
// ...
|
||||
var outputLines = new List<string>();
|
||||
var pluginMatched = false;
|
||||
var insideAppLovinClosure = false;
|
||||
var updatedApiKey = false;
|
||||
var mavenRepoUpdated = false;
|
||||
var dependencyClassPathUpdated = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
// Bintray maven repo is no longer being used. Update to s3 maven repo with regex check
|
||||
if (!mavenRepoUpdated && (line.Contains(QualityServiceBintrayMavenRepo) || line.Contains(QualityServiceNoRegexMavenRepo)))
|
||||
{
|
||||
outputLines.Add(GetFormattedBuildScriptLine(QualityServiceMavenRepo));
|
||||
mavenRepoUpdated = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We no longer use version specific dependency class path. Just use + for version to always pull the latest.
|
||||
if (!dependencyClassPathUpdated && line.Contains(QualityServiceDependencyClassPathV3))
|
||||
{
|
||||
outputLines.Add(GetFormattedBuildScriptLine(QualityServiceDependencyClassPath));
|
||||
dependencyClassPathUpdated = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!pluginMatched && line.Contains(QualityServicePlugin))
|
||||
{
|
||||
insideAppLovinClosure = true;
|
||||
pluginMatched = true;
|
||||
}
|
||||
|
||||
if (insideAppLovinClosure && line.Contains("}"))
|
||||
{
|
||||
insideAppLovinClosure = false;
|
||||
}
|
||||
|
||||
// Update the API key.
|
||||
if (insideAppLovinClosure && !updatedApiKey && TokenApiKey.IsMatch(line))
|
||||
{
|
||||
outputLines.Add(string.Format(QualityServiceApiKey, apiKey));
|
||||
updatedApiKey = true;
|
||||
}
|
||||
// Keep adding the line until we find and update the plugin.
|
||||
else
|
||||
{
|
||||
outputLines.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
|
||||
private static List<string> AddPluginAndBuildScript(List<string> lines, string apiKey, bool addBuildScriptLines)
|
||||
{
|
||||
var shouldAddPlugin = MaxSdkUtils.IsValidString(apiKey);
|
||||
if (shouldAddPlugin)
|
||||
{
|
||||
lines = AddPlugin(lines, apiKey);
|
||||
if (lines == null) return null;
|
||||
}
|
||||
|
||||
if (!addBuildScriptLines) return lines;
|
||||
|
||||
lines = AddBuildScript(lines);
|
||||
return lines;
|
||||
}
|
||||
|
||||
private static List<string> AddBuildScript(List<string> lines)
|
||||
{
|
||||
var outputLines = new List<string>();
|
||||
var buildScriptClosureDepth = 0;
|
||||
var insideBuildScriptClosure = false;
|
||||
var buildScriptMatched = false;
|
||||
var qualityServiceRepositoryAdded = false;
|
||||
var qualityServiceDependencyClassPathAdded = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
// Add the line to the output lines.
|
||||
outputLines.Add(line);
|
||||
|
||||
if (!buildScriptMatched && line.Contains(BuildScriptMatcher))
|
||||
{
|
||||
buildScriptMatched = true;
|
||||
insideBuildScriptClosure = true;
|
||||
}
|
||||
|
||||
// Match the parenthesis to track if we are still inside the buildscript closure.
|
||||
if (insideBuildScriptClosure)
|
||||
{
|
||||
if (line.Contains("{"))
|
||||
{
|
||||
buildScriptClosureDepth++;
|
||||
}
|
||||
|
||||
if (line.Contains("}"))
|
||||
{
|
||||
buildScriptClosureDepth--;
|
||||
}
|
||||
|
||||
if (buildScriptClosureDepth == 0)
|
||||
{
|
||||
insideBuildScriptClosure = false;
|
||||
|
||||
// There may be multiple buildscript closures and we need to keep looking until we added both the repository and classpath.
|
||||
buildScriptMatched = qualityServiceRepositoryAdded && qualityServiceDependencyClassPathAdded;
|
||||
}
|
||||
}
|
||||
|
||||
if (insideBuildScriptClosure)
|
||||
{
|
||||
// Add the build script dependency repositories.
|
||||
if (!qualityServiceRepositoryAdded && TokenBuildScriptRepositories.IsMatch(line))
|
||||
{
|
||||
outputLines.Add(GetFormattedBuildScriptLine(QualityServiceMavenRepo));
|
||||
qualityServiceRepositoryAdded = true;
|
||||
}
|
||||
// Add the build script dependencies.
|
||||
else if (!qualityServiceDependencyClassPathAdded && TokenBuildScriptDependencies.IsMatch(line))
|
||||
{
|
||||
outputLines.Add(GetFormattedBuildScriptLine(QualityServiceDependencyClassPath));
|
||||
qualityServiceDependencyClassPathAdded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!qualityServiceRepositoryAdded || !qualityServiceDependencyClassPathAdded)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return outputLines;
|
||||
}
|
||||
|
||||
private static List<string> AddPlugin(List<string> lines, string apiKey)
|
||||
{
|
||||
var outputLines = new List<string>();
|
||||
var qualityServicePluginAdded = false;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
outputLines.Add(line);
|
||||
|
||||
// Add the plugin.
|
||||
if (qualityServicePluginAdded || !TokenApplicationPlugin.IsMatch(line)) continue;
|
||||
|
||||
outputLines.Add(QualityServiceApplyPlugin);
|
||||
outputLines.AddRange(GenerateAppLovinPluginClosure(apiKey));
|
||||
qualityServicePluginAdded = true;
|
||||
}
|
||||
|
||||
return qualityServicePluginAdded ? outputLines : null;
|
||||
}
|
||||
|
||||
public static string GetFormattedBuildScriptLine(string buildScriptLine)
|
||||
{
|
||||
#if UNITY_2022_2_OR_NEWER
|
||||
return " "
|
||||
#else
|
||||
return " "
|
||||
#endif
|
||||
+ buildScriptLine;
|
||||
}
|
||||
|
||||
private static IEnumerable<string> GenerateAppLovinPluginClosure(string apiKey)
|
||||
{
|
||||
// applovin {
|
||||
// // NOTE: DO NOT CHANGE - this is NOT your AppLovin MAX SDK key - this is a derived key.
|
||||
// apiKey "456...a1b"
|
||||
// }
|
||||
var linesToInject = new List<string>(5);
|
||||
linesToInject.Add("");
|
||||
linesToInject.Add("applovin {");
|
||||
linesToInject.Add(" // NOTE: DO NOT CHANGE - this is NOT your AppLovin MAX SDK key - this is a derived key.");
|
||||
linesToInject.Add(string.Format(QualityServiceApiKey, apiKey));
|
||||
linesToInject.Add("}");
|
||||
|
||||
return linesToInject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 732b7510bc9c94aafb3fd3b8c0dc5d2d
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinProcessGradleBuildFile.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,159 @@
|
||||
////
|
||||
//// AppLovinSettings.cs
|
||||
//// AppLovin MAX Unity Plugin
|
||||
////
|
||||
//// Created by Santosh Bagadi on 1/27/20.
|
||||
//// Copyright © 2019 AppLovin. All rights reserved.
|
||||
////
|
||||
|
||||
//using AppLovinMax.Scripts.IntegrationManager.Editor;
|
||||
//using System.IO;
|
||||
//using UnityEditor;
|
||||
//using UnityEngine;
|
||||
//using UnityEngine.Serialization;
|
||||
|
||||
///// <summary>
|
||||
///// A <see cref="ScriptableObject"/> representing the AppLovin Settings that can be set in the Integration Manager Window.
|
||||
/////
|
||||
///// The scriptable object asset is created with the name <c>AppLovinSettings.asset</c> and is placed under the directory <c>Assets/MaxSdk/Resources</c>.
|
||||
/////
|
||||
///// NOTE: Not name spacing this class since it is reflected upon by the Google adapter and will break compatibility.
|
||||
///// </summary>
|
||||
//public class AppLovinSettings : ScriptableObject
|
||||
//{
|
||||
// private const string SettingsExportPath = "MaxSdk/Resources/AppLovinSettings.asset";
|
||||
|
||||
// private static AppLovinSettings instance;
|
||||
|
||||
// [SerializeField] private bool qualityServiceEnabled = true;
|
||||
// [SerializeField] private string sdkKey;
|
||||
|
||||
// [SerializeField] private string customGradleVersionUrl;
|
||||
// [SerializeField] private string customGradleToolsVersion;
|
||||
|
||||
// [SerializeField] private string adMobAndroidAppId = string.Empty;
|
||||
// [SerializeField] private string adMobIosAppId = string.Empty;
|
||||
|
||||
// /// <summary>
|
||||
// /// An instance of AppLovin Setting.
|
||||
// /// </summary>
|
||||
// public static AppLovinSettings Instance
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// if (instance == null)
|
||||
// {
|
||||
// // Check for an existing AppLovinSettings somewhere in the project
|
||||
// var guids = AssetDatabase.FindAssets("AppLovinSettings t:ScriptableObject");
|
||||
// if (guids.Length > 1)
|
||||
// {
|
||||
// MaxSdkLogger.UserWarning("Multiple AppLovinSettings found. This may cause unexpected results.");
|
||||
// }
|
||||
|
||||
// if (guids.Length != 0)
|
||||
// {
|
||||
// var path = AssetDatabase.GUIDToAssetPath(guids[0]);
|
||||
// instance = AssetDatabase.LoadAssetAtPath<AppLovinSettings>(path);
|
||||
// return instance;
|
||||
// }
|
||||
|
||||
// string settingsFilePath;
|
||||
// // The settings file should be under the Assets/ folder so that it can be version controlled and cannot be overriden when updating.
|
||||
// // If the plugin is outside the Assets folder or if there is no existing AppLovinSettings asset, create the settings asset at the default location.
|
||||
// if (AppLovinIntegrationManager.IsPluginInPackageManager)
|
||||
// {
|
||||
// // Note: Can't use absolute path when calling `CreateAsset`. Should use path relative to Assets/ directory.
|
||||
// settingsFilePath = MaxSdkUtils.NormalizeToUnityPath(Path.Combine("Assets", SettingsExportPath));
|
||||
|
||||
// var maxSdkDir = MaxSdkUtils.NormalizeToUnityPath(Path.Combine(Application.dataPath, "MaxSdk"));
|
||||
// if (!Directory.Exists(maxSdkDir))
|
||||
// {
|
||||
// Directory.CreateDirectory(maxSdkDir);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// settingsFilePath = MaxSdkUtils.NormalizeToUnityPath(Path.Combine(AppLovinIntegrationManager.PluginParentDirectory, SettingsExportPath));
|
||||
// }
|
||||
|
||||
// var settingsDir = Path.GetDirectoryName(settingsFilePath);
|
||||
// if (!Directory.Exists(settingsDir))
|
||||
// {
|
||||
// Directory.CreateDirectory(settingsDir);
|
||||
// }
|
||||
|
||||
// // On script reload AssetDatabase.FindAssets() can fail and will overwrite AppLovinSettings without this check
|
||||
// if (!File.Exists(settingsFilePath))
|
||||
// {
|
||||
// instance = CreateInstance<AppLovinSettings>();
|
||||
// AssetDatabase.CreateAsset(instance, settingsFilePath);
|
||||
// MaxSdkLogger.D("Creating new AppLovinSettings asset at path: " + settingsFilePath);
|
||||
// }
|
||||
// }
|
||||
|
||||
// return instance;
|
||||
// }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Whether or not to install Quality Service plugin.
|
||||
// /// </summary>
|
||||
// public bool QualityServiceEnabled
|
||||
// {
|
||||
// get { return Instance.qualityServiceEnabled; }
|
||||
// set { Instance.qualityServiceEnabled = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// AppLovin SDK Key.
|
||||
// /// </summary>
|
||||
// public string SdkKey
|
||||
// {
|
||||
// get { return Instance.sdkKey; }
|
||||
// set { Instance.sdkKey = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// A URL to set the distributionUrl in the gradle-wrapper.properties file (ex: https\://services.gradle.org/distributions/gradle-6.9.3-bin.zip)
|
||||
// /// </summary>
|
||||
// public string CustomGradleVersionUrl
|
||||
// {
|
||||
// get { return Instance.customGradleVersionUrl; }
|
||||
// set { Instance.customGradleVersionUrl = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// A string to set the custom gradle tools version (ex: com.android.tools.build:gradle:4.2.0)
|
||||
// /// </summary>
|
||||
// public string CustomGradleToolsVersion
|
||||
// {
|
||||
// get { return Instance.customGradleToolsVersion; }
|
||||
// set { Instance.customGradleToolsVersion = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// AdMob Android App ID.
|
||||
// /// </summary>
|
||||
// public string AdMobAndroidAppId
|
||||
// {
|
||||
// get { return Instance.adMobAndroidAppId; }
|
||||
// set { Instance.adMobAndroidAppId = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// AdMob iOS App ID.
|
||||
// /// </summary>
|
||||
// public string AdMobIosAppId
|
||||
// {
|
||||
// get { return Instance.adMobIosAppId; }
|
||||
// set { Instance.adMobIosAppId = value; }
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Saves the instance of the settings.
|
||||
// /// </summary>
|
||||
// public void SaveAsync()
|
||||
// {
|
||||
// EditorUtility.SetDirty(instance);
|
||||
// }
|
||||
//}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ebc0ba1b5ef6b4a6b9dd53d7eadfea16
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinSettings.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,141 @@
|
||||
//
|
||||
// AppLovinSettings.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 1/27/20.
|
||||
// Copyright © 2019 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using AppLovinMax.Scripts.IntegrationManager.Editor;
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="ScriptableObject"/> representing the AppLovin Settings that can be set in the Integration Manager Window.
|
||||
///
|
||||
/// The scriptable object asset is created with the name <c>AppLovinSettings.asset</c> and is placed under the directory <c>Assets/MaxSdk/Resources</c>.
|
||||
///
|
||||
/// NOTE: Not name spacing this class since it is reflected upon by the Google adapter and will break compatibility.
|
||||
/// </summary>
|
||||
public class AppLovinSettings : ScriptableObject
|
||||
{
|
||||
private const string SettingsExportPath = "ProjectSettings/Packages/com.bywaystudios.applovin/AppLovinSettings.json";
|
||||
|
||||
private static AppLovinSettings instance;
|
||||
|
||||
[SerializeField] private bool qualityServiceEnabled = true;
|
||||
[SerializeField] private string sdkKey;
|
||||
|
||||
[SerializeField] private string customGradleVersionUrl;
|
||||
[SerializeField] private string customGradleToolsVersion;
|
||||
|
||||
[SerializeField] private string adMobAndroidAppId = string.Empty;
|
||||
[SerializeField] private string adMobIosAppId = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// An instance of AppLovin Setting.
|
||||
/// </summary>
|
||||
public static AppLovinSettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance != null) return instance;
|
||||
|
||||
instance = CreateInstance<AppLovinSettings>();
|
||||
|
||||
var projectRootPath = Path.GetDirectoryName(Application.dataPath);
|
||||
var settingsFilePath = Path.Combine(projectRootPath, SettingsExportPath);
|
||||
if (!File.Exists(settingsFilePath))
|
||||
{
|
||||
instance.SaveAsync();
|
||||
return instance;
|
||||
}
|
||||
|
||||
var settingsJson = File.ReadAllText(settingsFilePath);
|
||||
if (string.IsNullOrEmpty(settingsJson))
|
||||
{
|
||||
instance.SaveAsync();
|
||||
return instance;
|
||||
}
|
||||
|
||||
JsonUtility.FromJsonOverwrite(settingsJson, instance);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to install Quality Service plugin.
|
||||
/// </summary>
|
||||
public bool QualityServiceEnabled
|
||||
{
|
||||
get { return Instance.qualityServiceEnabled; }
|
||||
set { Instance.qualityServiceEnabled = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AppLovin SDK Key.
|
||||
/// </summary>
|
||||
public string SdkKey
|
||||
{
|
||||
get { return Instance.sdkKey; }
|
||||
set { Instance.sdkKey = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A URL to set the distributionUrl in the gradle-wrapper.properties file (ex: https\://services.gradle.org/distributions/gradle-6.9.3-bin.zip)
|
||||
/// </summary>
|
||||
public string CustomGradleVersionUrl
|
||||
{
|
||||
get { return Instance.customGradleVersionUrl; }
|
||||
set { Instance.customGradleVersionUrl = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A string to set the custom gradle tools version (ex: com.android.tools.build:gradle:4.2.0)
|
||||
/// </summary>
|
||||
public string CustomGradleToolsVersion
|
||||
{
|
||||
get { return Instance.customGradleToolsVersion; }
|
||||
set { Instance.customGradleToolsVersion = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AdMob Android App ID.
|
||||
/// </summary>
|
||||
public string AdMobAndroidAppId
|
||||
{
|
||||
get { return Instance.adMobAndroidAppId; }
|
||||
set { Instance.adMobAndroidAppId = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AdMob iOS App ID.
|
||||
/// </summary>
|
||||
public string AdMobIosAppId
|
||||
{
|
||||
get { return Instance.adMobIosAppId; }
|
||||
set { Instance.adMobIosAppId = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the instance of the settings.
|
||||
/// </summary>
|
||||
public void SaveAsync()
|
||||
{
|
||||
var settingsJson = JsonUtility.ToJson(instance);
|
||||
try
|
||||
{
|
||||
var projectRootPath = Path.GetDirectoryName(Application.dataPath);
|
||||
var settingsFilePath = Path.Combine(projectRootPath, SettingsExportPath);
|
||||
File.WriteAllText(settingsFilePath, settingsJson);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Failed to save settings.");
|
||||
Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb903d725e593d1458c49ff603bf5def
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinSettings.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,190 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using AppLovinMax.ThirdParty.MiniJson;
|
||||
|
||||
namespace AppLovinMax.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
public class AppLovinUpmManifest
|
||||
{
|
||||
private const string KeyUrl = "url";
|
||||
private const string KeyName = "name";
|
||||
private const string KeyScopes = "scopes";
|
||||
private const string KeyScopedRegistry = "scopedRegistries";
|
||||
|
||||
private Dictionary<string, object> manifest;
|
||||
|
||||
private static string ManifestPath
|
||||
{
|
||||
get { return Path.Combine(Directory.GetCurrentDirectory(), "Packages/manifest.json"); }
|
||||
}
|
||||
|
||||
// Private constructor to enforce the use of the Load() method
|
||||
private AppLovinUpmManifest() { }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of AppLovinUpmManifest and loads the manifest.json file.
|
||||
/// </summary>
|
||||
/// <returns>An instance of AppLovinUpmManifest</returns>
|
||||
public static AppLovinUpmManifest Load()
|
||||
{
|
||||
return new AppLovinUpmManifest { manifest = GetManifest() };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds or updates a scoped registry in the manifest.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the registry</param>
|
||||
/// <param name="url">The url of the registry</param>
|
||||
/// <param name="scopes">The scopes of the registry</param>
|
||||
public void AddOrUpdateRegistry(string name, string url, List<string> scopes)
|
||||
{
|
||||
var registry = GetRegistry(name);
|
||||
if (registry == null)
|
||||
{
|
||||
var registries = GetRegistries();
|
||||
if (registries == null) return;
|
||||
|
||||
registries.Add(new Dictionary<string, object>
|
||||
{
|
||||
{KeyName, name},
|
||||
{KeyUrl, url},
|
||||
{KeyScopes, scopes}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateRegistry(registry, scopes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the manifest by serializing it back to JSON and writing to file.
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
var content = Json.Serialize(manifest, true);
|
||||
File.WriteAllText(ManifestPath, content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a dependency to the manifest.
|
||||
/// </summary>
|
||||
/// <param name="packageName">The name of the package to add</param>
|
||||
/// <param name="version">The version of the package to add</param>
|
||||
public void AddPackageDependency(string packageName, string version)
|
||||
{
|
||||
var manifestDependencies = GetDependencies();
|
||||
manifestDependencies[packageName] = version;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a dependency from the manifest.
|
||||
/// </summary>
|
||||
/// <param name="packageName">The name of the package to remove</param>
|
||||
public void RemovePackageDependency(string packageName)
|
||||
{
|
||||
var manifestDependencies = GetDependencies();
|
||||
manifestDependencies.Remove(packageName);
|
||||
}
|
||||
|
||||
#region Utility
|
||||
|
||||
/// <summary>
|
||||
/// Returns the manifest.json file as a dictionary.
|
||||
/// </summary>
|
||||
private static Dictionary<string, object> GetManifest()
|
||||
{
|
||||
if (!File.Exists(ManifestPath))
|
||||
{
|
||||
throw new Exception("Manifest not Found!");
|
||||
}
|
||||
|
||||
var manifestJson = File.ReadAllText(ManifestPath);
|
||||
if (string.IsNullOrEmpty(manifestJson))
|
||||
{
|
||||
throw new Exception("Manifest is empty!");
|
||||
}
|
||||
|
||||
var deserializedManifest = Json.Deserialize(manifestJson) as Dictionary<string, object>;
|
||||
if (deserializedManifest == null)
|
||||
{
|
||||
throw new Exception("Failed to deserialize manifest");
|
||||
}
|
||||
|
||||
return deserializedManifest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the manifest's dependencies section.
|
||||
/// </summary>
|
||||
/// <returns>The dependencies section of the manifest.</returns>
|
||||
private Dictionary<string, object> GetDependencies()
|
||||
{
|
||||
var dependencies = manifest["dependencies"] as Dictionary<string, object>;
|
||||
if (dependencies == null)
|
||||
{
|
||||
throw new Exception("No dependencies found in manifest.");
|
||||
}
|
||||
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the manifest's registries section. Creates a new registries section if one does not exist.
|
||||
/// </summary>
|
||||
/// <returns>The registries section of the manifest.</returns>
|
||||
private List<object> GetRegistries()
|
||||
{
|
||||
EnsureScopedRegistryExists();
|
||||
return manifest[KeyScopedRegistry] as List<object>;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a scoped registry with the given name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the registry</param>
|
||||
/// <returns>Returns the registry, or null if it can't be found</returns>
|
||||
private Dictionary<string, object> GetRegistry(string name)
|
||||
{
|
||||
var registries = GetRegistries();
|
||||
if (registries == null) return null;
|
||||
|
||||
return registries
|
||||
.OfType<Dictionary<string, object>>()
|
||||
.FirstOrDefault(registry => MaxSdkUtils.GetStringFromDictionary(registry, KeyName).Equals(name));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the section for scoped registries in the manifest.json file if it doesn't exist.
|
||||
/// </summary>
|
||||
private void EnsureScopedRegistryExists()
|
||||
{
|
||||
if (manifest.ContainsKey(KeyScopedRegistry)) return;
|
||||
|
||||
manifest.Add(KeyScopedRegistry, new List<object>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates a registry to make sure it contains the new scopes.
|
||||
/// </summary>
|
||||
/// <param name="registry">The registry to update</param>
|
||||
/// <param name="newScopes">The scopes we want added to the registry</param>
|
||||
private static void UpdateRegistry(Dictionary<string, object> registry, List<string> newScopes)
|
||||
{
|
||||
var scopes = MaxSdkUtils.GetListFromDictionary(registry, KeyScopes);
|
||||
if (scopes == null)
|
||||
{
|
||||
registry[KeyScopes] = new List<string>(newScopes);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only add scopes that are not already in the list
|
||||
var uniqueNewScopes = newScopes.Where(scope => !scopes.Contains(scope)).ToList();
|
||||
scopes.AddRange(uniqueNewScopes);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40e2ad4a252104688b8627f82e806b2e
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/AppLovinUpmManifest.cs
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinUpmManifest.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "MaxSdk.Scripts.IntegrationManager.Editor",
|
||||
"references": [
|
||||
"MaxSdk.Scripts"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a10a05a8449c42519fd80f2b8b580de3
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/MaxSdk.IntegrationManager.Editor.asmdef
|
||||
timeCreated: 1591749873
|
||||
@ -0,0 +1,170 @@
|
||||
//
|
||||
// MaxCmpService.cs
|
||||
// AppLovin User Engagement Unity Plugin
|
||||
//
|
||||
// Created by Santosh Bagadi on 10/1/23.
|
||||
// Copyright © 2023 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
#elif UNITY_ANDROID
|
||||
using UnityEngine;
|
||||
#elif UNITY_IOS
|
||||
using System.Runtime.InteropServices;
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// This class provides direct APIs for interfacing with the Google-certified CMP installed, if any.
|
||||
/// </summary>
|
||||
public class MaxCmpService
|
||||
{
|
||||
private static readonly MaxCmpService _instance = new MaxCmpService();
|
||||
|
||||
private MaxCmpService() { }
|
||||
|
||||
private static Action<MaxCmpError> _onCompletedAction;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
#elif UNITY_ANDROID
|
||||
private static readonly AndroidJavaClass MaxUnityPluginClass = new AndroidJavaClass("com.applovin.mediation.unity.MaxUnityPlugin");
|
||||
#elif UNITY_IOS
|
||||
[DllImport("__Internal")]
|
||||
private static extern void _MaxShowCmpForExistingUser();
|
||||
|
||||
[DllImport("__Internal")]
|
||||
private static extern bool _MaxHasSupportedCmp();
|
||||
#endif
|
||||
|
||||
internal static MaxCmpService Instance
|
||||
{
|
||||
get { return _instance; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the CMP flow to an existing user.
|
||||
/// Note that the user's current consent will be reset before the CMP alert is shown.
|
||||
/// </summary>
|
||||
/// <param name="onCompletedAction">Called when the CMP flow finishes showing.</param>
|
||||
public void ShowCmpForExistingUser(Action<MaxCmpError> onCompletedAction)
|
||||
{
|
||||
_onCompletedAction = onCompletedAction;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
var errorProps = new Dictionary<string, object>
|
||||
{
|
||||
{"code", (int) MaxCmpError.ErrorCode.FormUnavailable},
|
||||
{"message", "CMP is not supported in Unity editor"}
|
||||
};
|
||||
|
||||
NotifyCompletedIfNeeded(errorProps);
|
||||
#elif UNITY_ANDROID
|
||||
MaxUnityPluginClass.CallStatic("showCmpForExistingUser");
|
||||
#elif UNITY_IOS
|
||||
_MaxShowCmpForExistingUser();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <code>true</code> if a supported CMP SDK is detected.
|
||||
/// </summary>
|
||||
public bool HasSupportedCmp
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
return false;
|
||||
#elif UNITY_ANDROID
|
||||
return MaxUnityPluginClass.CallStatic<bool>("hasSupportedCmp");
|
||||
#elif UNITY_IOS
|
||||
return _MaxHasSupportedCmp();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
internal static void NotifyCompletedIfNeeded(Dictionary<string, object> errorProps)
|
||||
{
|
||||
if (_onCompletedAction == null) return;
|
||||
|
||||
var error = (errorProps == null) ? null : MaxCmpError.Create(errorProps);
|
||||
_onCompletedAction(error);
|
||||
}
|
||||
}
|
||||
|
||||
public class MaxCmpError
|
||||
{
|
||||
public enum ErrorCode
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that an unspecified error has occurred.
|
||||
/// </summary>
|
||||
Unspecified = -1,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the CMP has not been integrated correctly.
|
||||
/// </summary>
|
||||
IntegrationError = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the CMP form is unavailable.
|
||||
/// </summary>
|
||||
FormUnavailable = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the CMP form is not required.
|
||||
/// </summary>
|
||||
FormNotRequired = 3
|
||||
}
|
||||
|
||||
public static MaxCmpError Create(IDictionary<string, object> error)
|
||||
{
|
||||
return new MaxCmpError()
|
||||
{
|
||||
Code = GetCode(MaxSdkUtils.GetIntFromDictionary(error, "code")),
|
||||
Message = MaxSdkUtils.GetStringFromDictionary(error, "message"),
|
||||
CmpCode = MaxSdkUtils.GetIntFromDictionary(error, "cmpCode", -1),
|
||||
CmpMessage = MaxSdkUtils.GetStringFromDictionary(error, "cmpMessage")
|
||||
};
|
||||
}
|
||||
|
||||
private static ErrorCode GetCode(int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case 1:
|
||||
return ErrorCode.IntegrationError;
|
||||
case 2:
|
||||
return ErrorCode.FormUnavailable;
|
||||
case 3:
|
||||
return ErrorCode.FormNotRequired;
|
||||
default:
|
||||
return ErrorCode.Unspecified;
|
||||
}
|
||||
}
|
||||
|
||||
private MaxCmpError() { }
|
||||
|
||||
/// <summary>
|
||||
/// The error code for this error.
|
||||
/// </summary>
|
||||
public ErrorCode Code { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The error message for this error.
|
||||
/// </summary>
|
||||
public string Message { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The error code returned by the CMP.
|
||||
/// </summary>
|
||||
public int CmpCode { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The error message returned by the CMP.
|
||||
/// </summary>
|
||||
public string CmpMessage { get; private set; }
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b2f72e42417bf4409caec18f464cfca
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/MaxCmpService.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,108 @@
|
||||
//
|
||||
// MaxEventExecutor.cs
|
||||
// Max Unity Plugin
|
||||
//
|
||||
// Created by Jonathan Liu on 1/22/2024.
|
||||
// Copyright © 2024 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace AppLovinMax.Internal
|
||||
{
|
||||
public class MaxEventExecutor : MonoBehaviour
|
||||
{
|
||||
private static MaxEventExecutor _instance;
|
||||
private static readonly List<MaxAction> AdEventsQueue = new List<MaxAction>();
|
||||
|
||||
private static volatile bool _adEventsQueueEmpty = true;
|
||||
|
||||
struct MaxAction
|
||||
{
|
||||
public readonly Action ActionToExecute;
|
||||
public readonly string EventName;
|
||||
|
||||
public MaxAction(Action actionToExecute, string nameOfEvent)
|
||||
{
|
||||
ActionToExecute = actionToExecute;
|
||||
EventName = nameOfEvent;
|
||||
}
|
||||
}
|
||||
|
||||
public static void InitializeIfNeeded()
|
||||
{
|
||||
if (_instance != null) return;
|
||||
|
||||
var executor = new GameObject("MaxEventExecutor");
|
||||
executor.hideFlags = HideFlags.HideAndDontSave;
|
||||
DontDestroyOnLoad(executor);
|
||||
_instance = executor.AddComponent<MaxEventExecutor>();
|
||||
}
|
||||
|
||||
#region Public API
|
||||
|
||||
#if UNITY_EDITOR || !(UNITY_ANDROID || UNITY_IPHONE || UNITY_IOS)
|
||||
public static MaxEventExecutor Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
InitializeIfNeeded();
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public static void ExecuteOnMainThread(Action action, string eventName)
|
||||
{
|
||||
lock (AdEventsQueue)
|
||||
{
|
||||
AdEventsQueue.Add(new MaxAction(action, eventName));
|
||||
_adEventsQueueEmpty = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void InvokeOnMainThread(UnityEvent unityEvent, string eventName)
|
||||
{
|
||||
ExecuteOnMainThread(() => unityEvent.Invoke(), eventName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_adEventsQueueEmpty) return;
|
||||
|
||||
var actionsToExecute = new List<MaxAction>();
|
||||
lock (AdEventsQueue)
|
||||
{
|
||||
actionsToExecute.AddRange(AdEventsQueue);
|
||||
AdEventsQueue.Clear();
|
||||
_adEventsQueueEmpty = true;
|
||||
}
|
||||
|
||||
foreach (var maxAction in actionsToExecute)
|
||||
{
|
||||
if (maxAction.ActionToExecute.Target != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
maxAction.ActionToExecute.Invoke();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MaxSdkLogger.UserError("Caught exception in publisher event: " + maxAction.EventName + ", exception: " + exception);
|
||||
MaxSdkLogger.LogException(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Disable()
|
||||
{
|
||||
_instance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fdc142f49f2efe4490e57041b79c99c
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/MaxEventExecutor.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,37 @@
|
||||
//
|
||||
// EventSystemChecker.cs
|
||||
// AppLovin MAX Unity Plugin
|
||||
//
|
||||
// Created by Jonathan Liu on 10/23/2022.
|
||||
// Copyright © 2022 AppLovin. All rights reserved.
|
||||
//
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace AppLovinMax.Scripts
|
||||
{
|
||||
/// <summary>
|
||||
/// A script to check and enable event system as needed for the AppLovin MAX ad prefabs.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(EventSystem))]
|
||||
public class MaxEventSystemChecker : MonoBehaviour
|
||||
{
|
||||
private void Awake()
|
||||
{
|
||||
// Enable the EventSystem if there is no other EventSystem in the scene
|
||||
var eventSystem = GetComponent<EventSystem>();
|
||||
var currentSystem = EventSystem.current;
|
||||
if (currentSystem == null || currentSystem == eventSystem)
|
||||
{
|
||||
eventSystem.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
eventSystem.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d6adb51e5c67274ab54d8d8bccc53f7
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/MaxEventSystemChecker.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Class containing pre-defined constants to use with AppLovin event tracking APIs.
|
||||
*/
|
||||
public static class MaxEvents
|
||||
{
|
||||
/**
|
||||
* Nested class representing pre-defined AppLovin events to be fired with AppLovin event tracking APIs.
|
||||
*/
|
||||
public class AppLovin
|
||||
{
|
||||
public const string UserLoggedIn = "login";
|
||||
public const string UserCreatedAccount = "registration";
|
||||
public const string UserCompletedTutorial = "tutorial";
|
||||
public const string UserCompletedLevel = "level";
|
||||
public const string UserCompletedAchievement = "achievement";
|
||||
public const string UserSpentVirtualCurrency = "vcpurchase";
|
||||
public const string UserCompletedInAppPurchase = "iap";
|
||||
public const string UserSentInvitation = "invite";
|
||||
public const string UserSharedLink = "share";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18bfdf77590b723469598a1fd6f79d20
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/MaxEvents.cs
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "MaxSdk.Scripts",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": []
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67fcebe2179dc574b837f25bf83e5c2d
|
||||
labels:
|
||||
- al_max
|
||||
- al_max_export_path-MaxSdk/Scripts/MaxSdk.Scripts.asmdef
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user