This commit is contained in:
corn
2026-06-07 22:59:32 +08:00
commit a62ff7379b
7171 changed files with 10015624 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 87b08baeabd7b49ecb4c54aaceae88cb
labels:
- al_max
- al_max_export_path-MaxSdk/AppLovin
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1d2d3ff055e024c328260aae0ea8898a
labels:
- al_max
- al_max_export_path-MaxSdk/AppLovin/Editor
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<dependencies>
<androidPackages>
<androidPackage spec="com.applovin:applovin-sdk:12.4.2" />
</androidPackages>
<iosPods>
<iosPod name="AppLovinSDK" version="12.4.1" />
</iosPods>
</dependencies>

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 746da98302dc0402aaa37e8f7bd97e77
labels:
- al_max
- al_max_export_path-MaxSdk/AppLovin/Editor/Dependencies.xml
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ba43539623e3049cb9318ed1a5418473
labels:
- al_max
- al_max_export_path-MaxSdk/AppLovin/Plugins
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 666c64b10aae14f1da56959c3539e4d1
labels:
- al_max
- al_max_export_path-MaxSdk/AppLovin/Plugins/Android
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
fileFormatVersion: 2
guid: 1db980bd612824d2097f78fd779e6051
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:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8354788eaf5cd47c581fd7944afdc804
labels:
- al_max
- al_max_export_path-MaxSdk/AppLovin/Plugins/iOS
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,104 @@
//
// 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
- (ALSdk *)initializeSdkWithSettings:(ALSdkSettings *)settings backgroundCallback:(ALUnityBackgroundCallback)unityBackgroundCallback andCompletionHandler:(ALSdkInitializationCompletionHandler)completionHandler;
- (void)createBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier atPosition:(nullable NSString *)bannerPosition;
- (void)createBannerWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier x:(CGFloat)xOffset y:(CGFloat)yOffset;
- (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;
- (void)loadRewardedInterstitialAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
- (BOOL)isRewardedInterstitialAdReadyWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
- (void)showRewardedInterstitialAdWithAdUnitIdentifier:(nullable NSString *)adUnitIdentifier placement:(nullable NSString *)placement customData:(nullable NSString *)customData;
- (void)setRewardedInterstitialAdExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable NSString *)value;
- (void)setRewardedInterstitialAdLocalExtraParameterForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier key:(nullable NSString *)key value:(nullable id)value;
// Event Tracking
- (void)trackEvent:(nullable NSString *)event parameters:(nullable NSString *)parameters;
// Ad Info
- (NSString *)adInfoForAdUnitIdentifier:(nullable NSString *)adUnitIdentifier;
// 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;
/**
* Creates an instance of @c MAUnityAdManager if needed and returns the singleton instance.
*/
+ (instancetype)shared;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,115 @@
fileFormatVersion: 2
guid: 4209563f82b8a4f7dabf03705ab761c6
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

View File

@@ -0,0 +1,109 @@
fileFormatVersion: 2
guid: 2973e70bd2fa74984b35aea07ae9db52
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

View File

@@ -0,0 +1,109 @@
fileFormatVersion: 2
guid: 7e373ed7168b243e6b706e991ab5a643
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:

Binary file not shown.

View File

@@ -0,0 +1,25 @@
fileFormatVersion: 2
guid: ff72041106c504e268ea0ba778b962ee
labels:
- al_max
- al_max_export_path-MaxSdk/AvenirNext.ttc
TrueTypeFontImporter:
externalObjects: {}
serializedVersion: 4
fontSize: 16
forceTextureCase: -2
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontName: Avenir Next
fontNames:
- Avenir Next
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 1
useLegacyBoundsCalculation: 0
shouldRoundAdvanceValue: 1
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/MaxSdk/ButtonPressed.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,131 @@
fileFormatVersion: 2
guid: 482bb6becec9f49fda9230607c1e1097
labels:
- al_max
- al_max_export_path-MaxSdk/ButtonPressed.png
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
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: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 17, y: 21, z: 15, w: 17}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
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
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
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: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dcf2020c4018447c9b91170c0f62d799
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 91403944b5f324e2e97449216ed04dbb
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/AdColony
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d334fe96a783c44d199a5a5760c8b82f
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/ByteDance
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2f3dfc57e1b4644d8beac44054356a98
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/Chartboost
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c44d4f0f178014127a271c8dbcbeffe5
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/Facebook
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bd173679e095e434cba0d7d8261166e5
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/Google
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e8015bd045cea462c8f39c8a05867d08
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/Google/Editor
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<dependencies>
<androidPackages>
<!-- Ensure that Resolver doesn't inadvertently pull the latest Play Services Ads' SDK that we haven't certified against. -->
<androidPackage spec="com.applovin.mediation:google-adapter:[23.0.0.1]" />
</androidPackages>
<iosPods>
<iosPod name="AppLovinMediationGoogleAdapter" version="11.3.0.0" />
</iosPods>
</dependencies>

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 053b810d3594744e38b6fd0fa378fb57
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/Google/Editor/Dependencies.xml
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2352bb79848564d1fad31c7849d2cfe0
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/InMobi
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d08b49a014c4a48e386fe2501a645cf8
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/IronSource
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,2 @@
A placeholder file to make sure that the Mediation folder asset is exported with the base plugin.
This ensures that the adapters are imported into this directory even when the plugin has been moved to a different folder.

View File

@@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 9a8f83e97729443c86120be3bb24190d
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/MediationAdapters.txt
timeCreated: 1609308536

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cab786f5f9cf6472193f9b0e0efc04ef
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/Mintegral
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 36d57557ffaf949c79d9870e518fa3e7
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/Tapjoy
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3db55a3dd5be744b3adbebe418538132
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/UnityAds
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 015a801f601234cfcb346dcb44f7fe5a
labels:
- al_max
- al_max_export_path-MaxSdk/Mediation/Vungle
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1b0e7d9cb1ac8437d90669c0d6042384
labels:
- al_max
- al_max_export_path-MaxSdk/Prefabs
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 54c062c0526b148efa2ea2e9489b3aa0
labels:
- al_max
- al_max_export_path-MaxSdk/Prefabs/BannerBottom.prefab
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 6521750c87fd14f709d09a1e38ffde47
labels:
- al_max
- al_max_export_path-MaxSdk/Prefabs/BannerTop.prefab
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 3fc0c2627ce8a4490b8e319326f8a535
labels:
- al_max
- al_max_export_path-MaxSdk/Prefabs/Interstitial.prefab
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: a28c1544d6f094d5eafc8da2343c9119
labels:
- al_max
- al_max_export_path-MaxSdk/Prefabs/Rewarded.prefab
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 280109eb15e6d4f3dac4ee16550317fb
labels:
- al_max
- al_max_export_path-MaxSdk/Resources
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ebc0ba1b5ef6b4a6b9dd53d7eadfea16, type: 3}
m_Name: AppLovinSettings
m_EditorClassIdentifier:
qualityServiceEnabled: 0
sdkKey: psZVEAMEWH5iW2zGUnOMSoVUytal0OxRPslmW0QNaDaGKuAZIVm2LaAfwCMoEA89NZS7TgPWdXFxEygQDpWgpD
setAttributionReportEndpoint: 0
addApsSkAdNetworkIds: 0
customGradleVersionUrl:
customGradleToolsVersion:
consentFlowEnabled: 0
consentFlowPlatform: 0
consentFlowPrivacyPolicyUrl:
consentFlowTermsOfServiceUrl:
userTrackingUsageDescriptionEn:
userTrackingUsageLocalizationEnabled: 0
userTrackingUsageDescriptionDe:
userTrackingUsageDescriptionEs:
userTrackingUsageDescriptionFr:
userTrackingUsageDescriptionJa:
userTrackingUsageDescriptionKo:
userTrackingUsageDescriptionZhHans:
userTrackingUsageDescriptionZhHant:
adMobAndroidAppId: ca-app-pub-1796222250727878~7109214110
adMobIosAppId: ca-app-pub-1796222250727878~7109214110
showInternalSettingsInIntegrationManager: 0

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2b1af96dc48554b2a88fa706581c3826
labels:
- al_max
- al_max_export_path-MaxSdk/Resources/AppLovinSettings.asset
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f995c00229dd241ec92807311868d023
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

View File

@@ -0,0 +1,94 @@
fileFormatVersion: 2
guid: 572fee4574afa4f6dbf2846e0c152fe8
labels:
- al_max
- al_max_export_path-MaxSdk/Resources/Images/alert_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: 159 B

View File

@@ -0,0 +1,94 @@
fileFormatVersion: 2
guid: d24994f48fdd0430692e3d49279cd782
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

View File

@@ -0,0 +1,91 @@
fileFormatVersion: 2
guid: b504c956e7ed744b6b0e7f014e1cac5a
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:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 541289d223ee64a66a08db53f3d469c0
labels:
- al_max
- al_max_export_path-MaxSdk/Scripts
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e01816bc45c944d03afb95d035caf0e1
labels:
- al_max
- al_max_export_path-MaxSdk/Scripts/IntegrationManager
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0da229e279400497786c39933fe02e52
labels:
- al_max
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,164 @@
//
// 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 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_19.3.0.3_ios_7.65.0.0"},
{"CHARTBOOST_NETWORK", "android_8.1.0.7_ios_8.2.1.3"},
{"FACEBOOK_MEDIATE", "android_6.0.0.1_ios_6.0.0.3"},
{"FYBER_NETWORK", "android_7.7.0.1_ios_7.6.4.1"},
{"GOOGLE_AD_MANAGER_NETWORK", "android_19.3.0.3_ios_7.65.0.0"},
{"INMOBI_NETWORK", "android_9.0.9.2_ios_9.0.7.9"},
{"IRONSOURCE_NETWORK", "android_7.0.1.1.1_ios_7.0.1.0.1"},
{"MYTARGET_NETWORK", "android_5.9.1.2_ios_5.7.5.1"},
{"SMAATO_NETWORK", "android_21.5.2.5_ios_21.5.2.3"},
{"TIKTOK_NETWORK", "android_3.1.0.1.6_ios_3.2.5.1.1"},
{"UNITY_NETWORK", "android_3.4.8.2_ios_3.4.8.2"},
{"VUNGLE_NETWORK", "android_6.7.1.2_ios_6.7.1.3"},
{"YANDEX_NETWORK", "android_2.170.2_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...");
AppLovinIntegrationManager.downloadPluginProgressCallback = AppLovinIntegrationManagerWindow.OnDownloadPluginProgress;
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;
}
}
}

View File

@@ -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:

View File

@@ -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 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

View File

@@ -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:

View File

@@ -0,0 +1,75 @@
//
// AppLovinDownloadHandler.cs
// AppLovin MAX Unity Plugin
//
// Created by Santosh Bagadi on 7/26/19.
// Copyright © 2019 AppLovin. All rights reserved.
//
#if !UNITY_2017_2_OR_NEWER
using System;
using System.IO;
using UnityEngine.Networking;
namespace AppLovinMax.Scripts.IntegrationManager.Editor
{
public class AppLovinDownloadHandler : DownloadHandlerScript
{
// Required by DownloadHandler base class. Called when you address the 'bytes' property.
protected override byte[] GetData()
{
return null;
}
private FileStream fileStream;
public AppLovinDownloadHandler(string path) : base(new byte[2048])
{
var downloadDirectory = Path.GetDirectoryName(path);
if (!Directory.Exists(downloadDirectory))
{
Directory.CreateDirectory(downloadDirectory);
}
try
{
//Open the current file to write to
fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
}
catch (Exception exception)
{
MaxSdkLogger.UserError(string.Format("Failed to create file at {0}\n{1}", path, exception.Message));
}
}
protected override bool ReceiveData(byte[] byteFromServer, int dataLength)
{
if (byteFromServer == null || byteFromServer.Length < 1 || fileStream == null)
{
return false;
}
try
{
//Write the current data to the file
fileStream.Write(byteFromServer, 0, dataLength);
}
catch (Exception exception)
{
fileStream.Close();
fileStream = null;
MaxSdkLogger.UserError(string.Format("Failed to download file{0}", exception.Message));
}
return true;
}
protected override void CompleteContent()
{
fileStream.Close();
}
}
}
#endif

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: c85c3812a13e04838951767c1285e4da
labels:
- al_max
- al_max_export_path-MaxSdk/Scripts/IntegrationManager/Editor/AppLovinDownloadHandler.cs
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}
}
}

View File

@@ -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:

View File

@@ -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 AppLovinMax.Scripts.IntegrationManager.Editor;
using System.Collections.Generic;
using System.IO;
using System.Linq;
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"
};
static AppLovinInitialize()
{
#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 pluginParentDir = AppLovinIntegrationManager.PluginParentDirectory;
var isPluginOutsideAssetsDir = AppLovinIntegrationManager.IsPluginOutsideAssetsDirectory;
var changesMade = AppLovinIntegrationManager.MovePluginFilesIfNeeded(pluginParentDir, isPluginOutsideAssetsDir);
if (isPluginOutsideAssetsDir)
{
// If the plugin is not under the assets folder, delete the MaxSdk/Mediation folder in the plugin, so that the adapters are not imported at that location and imported to the default location.
var mediationDir = Path.Combine(pluginParentDir, "MaxSdk/Mediation");
if (Directory.Exists(mediationDir))
{
FileUtil.DeleteFileOrDirectory(mediationDir);
FileUtil.DeleteFileOrDirectory(mediationDir + ".meta");
changesMade = true;
}
}
AppLovinIntegrationManager.AddLabelsToAssetsIfNeeded(pluginParentDir, isPluginOutsideAssetsDir);
foreach (var obsoleteFileExportPathToDelete in ObsoleteFileExportPathsToDelete)
{
var pathToDelete = MaxSdkUtils.GetAssetPathForExportPath(obsoleteFileExportPathToDelete);
if (CheckExistence(pathToDelete))
{
MaxSdkLogger.UserDebug("Deleting obsolete file '" + pathToDelete + "' that are no longer needed.");
FileUtil.DeleteFileOrDirectory(pathToDelete);
changesMade = true;
}
}
// 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);
changesMade = true;
}
}
// Refresh UI
if (changesMade)
{
AssetDatabase.Refresh();
MaxSdkLogger.UserDebug("AppLovin MAX Migration completed");
}
AppLovinAutoUpdater.Update();
}
private static bool CheckExistence(string location)
{
return File.Exists(location) ||
Directory.Exists(location) ||
(location.EndsWith("/*") && Directory.Exists(Path.GetDirectoryName(location)));
}
}
}

View File

@@ -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:

View File

@@ -0,0 +1,799 @@
//
// 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.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.Networking;
using VersionComparisonResult = MaxSdkUtils.VersionComparisonResult;
namespace AppLovinMax.Scripts.IntegrationManager.Editor
{
[Serializable]
public class PluginData
{
public Network AppLovinMax;
public Network[] MediatedNetworks;
public Network[] PartnerMicroSdks;
}
[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"
// }
// }
//
public string Name;
public string DisplayName;
public string DownloadUrl;
public string DependenciesFilePath;
public string[] PluginFilePaths;
public Versions LatestVersions;
[NonSerialized] public Versions CurrentVersions;
[NonSerialized] public VersionComparisonResult CurrentToLatestVersionComparisonResult = VersionComparisonResult.Lesser;
[NonSerialized] public bool RequiresUpdate;
}
/// <summary>
/// A helper data class used to get current versions from Dependency.xml files.
/// </summary>
[Serializable]
public class Versions
{
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, Android, Ios}.GetHashCode();
}
private static string AdapterSdkVersion(string adapterVersion)
{
var index = adapterVersion.LastIndexOf(".");
return index > 0 ? adapterVersion.Substring(0, index) : adapterVersion;
}
}
/// <summary>
/// A manager class for MAX integration manager window.
///
/// TODO: Decide if we should namespace these classes.
/// </summary>
public class AppLovinIntegrationManager
{
/// <summary>
/// Delegate to be called when downloading a plugin with the progress percentage.
/// </summary>
/// <param name="pluginName">The name of the plugin being downloaded.</param>
/// <param name="progress">Percentage downloaded.</param>
/// <param name="done">Whether or not the download is complete.</param>
public delegate void DownloadPluginProgressCallback(string pluginName, float progress, bool done);
/// <summary>
/// Delegate to be called when a plugin package is imported.
/// </summary>
/// <param name="network">The network data for which the package is imported.</param>
public delegate void ImportPackageCompletedCallback(Network network);
private static readonly AppLovinIntegrationManager instance = new AppLovinIntegrationManager();
public static readonly string GradleTemplatePath = Path.Combine("Assets/Plugins/Android", "mainTemplate.gradle");
public static readonly string DefaultPluginExportPath = Path.Combine("Assets", "MaxSdk");
private const string MaxSdkAssetExportPath = "MaxSdk/Scripts/MaxSdk.cs";
/// <summary>
/// Some publishers might re-export our plugin via Unity Package Manager and the plugin will not be under the Assets folder. This means that the mediation adapters, settings files should not be moved to the packages folder,
/// since they get overridden when the package is updated. These are the files that should not be moved, if the plugin is not under the Assets/ folder.
///
/// Note: When we distribute the plugin via Unity Package Manager, we need to distribute the adapters as separate packages, and the adapters won't be in the MaxSdk folder. So we need to take that into account.
/// </summary>
private static readonly List<string> PluginPathsToIgnoreMoveWhenPluginOutsideAssetsDirectory = new List<string>
{
"MaxSdk/Mediation",
"MaxSdk/Mediation.meta",
"MaxSdk/Resources.meta",
AppLovinSettings.SettingsExportPath,
AppLovinSettings.SettingsExportPath + ".meta"
};
private static string externalDependencyManagerVersion;
public static DownloadPluginProgressCallback downloadPluginProgressCallback;
public static ImportPackageCompletedCallback importPackageCompletedCallback;
private UnityWebRequest webRequest;
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 default exported path first, In most cases, we should be able to find the asset.
// In some cases where we don't, use the platform specific export path to search for the asset (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);
}
}
/// <summary>
/// When the base plugin is outside the <c>Assets/</c> directory, the mediation plugin files are still imported to the default location under <c>Assets/</c>.
/// Returns the parent directory where the mediation adapter plugins are imported.
/// </summary>
public static string MediationSpecificPluginParentDirectory
{
get { return IsPluginOutsideAssetsDirectory ? "Assets" : PluginParentDirectory; }
}
/// <summary>
/// Whether or not the plugin is under the Assets/ folder.
/// </summary>
public static bool IsPluginOutsideAssetsDirectory
{
get { return !PluginParentDirectory.StartsWith("Assets"); }
}
/// <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 (!string.IsNullOrEmpty(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()
{
// Add asset import callbacks.
AssetDatabase.importPackageCompleted += packageName =>
{
if (!IsImportingNetwork(packageName)) return;
var pluginParentDir = PluginParentDirectory;
var isPluginOutsideAssetsDir = IsPluginOutsideAssetsDirectory;
MovePluginFilesIfNeeded(pluginParentDir, isPluginOutsideAssetsDir);
AddLabelsToAssetsIfNeeded(pluginParentDir, isPluginOutsideAssetsDir);
AssetDatabase.Refresh();
CallImportPackageCompletedCallback(importingNetwork);
importingNetwork = null;
};
AssetDatabase.importPackageCancelled += packageName =>
{
if (!IsImportingNetwork(packageName)) return;
MaxSdkLogger.UserDebug("Package import cancelled.");
importingNetwork = null;
};
AssetDatabase.importPackageFailed += (packageName, errorMessage) =>
{
if (!IsImportingNetwork(packageName)) return;
MaxSdkLogger.UserError(errorMessage);
importingNetwork = null;
};
}
static AppLovinIntegrationManager() { }
/// <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("https://unity.applovin.com/max/1.0/integration_manager_info?plugin_version={0}", MaxSdk.Version);
using (var www = UnityWebRequest.Get(url))
{
var operation = www.SendWebRequest();
while (!operation.isDone) yield return new WaitForSeconds(0.1f); // Just wait till www is done. Our coroutine is pretty rudimentary.
#if UNITY_2020_1_OR_NEWER
if (www.result != UnityWebRequest.Result.Success)
#else
if (www.isNetworkError || www.isHttpError)
#endif
{
callback(null);
}
else
{
PluginData pluginData;
try
{
pluginData = JsonUtility.FromJson<PluginData>(www.downloadHandler.text);
}
catch (Exception exception)
{
Console.WriteLine(exception);
pluginData = null;
}
if (pluginData != null)
{
// Get current version of the plugin
var appLovinMax = pluginData.AppLovinMax;
UpdateCurrentVersions(appLovinMax, PluginParentDirectory);
// Get current versions for all the mediation networks.
var mediationPluginParentDirectory = MediationSpecificPluginParentDirectory;
foreach (var network in pluginData.MediatedNetworks)
{
UpdateCurrentVersions(network, mediationPluginParentDirectory);
}
foreach (var partnerMicroSdk in pluginData.PartnerMicroSdks)
{
UpdateCurrentVersions(partnerMicroSdk, mediationPluginParentDirectory);
}
}
callback(pluginData);
}
}
}
/// <summary>
/// Updates the CurrentVersion fields for a given network data object.
/// </summary>
/// <param name="network">Network for which to update the current versions.</param>
/// <param name="mediationPluginParentDirectory">The parent directory of where the mediation adapter plugins are imported to.</param>
public static void UpdateCurrentVersions(Network network, string mediationPluginParentDirectory)
{
var dependencyFilePath = Path.Combine(mediationPluginParentDirectory, network.DependenciesFilePath);
var currentVersions = GetCurrentVersions(dependencyFilePath);
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 == VersionComparisonResult.Equal &&
androidVersionComparison == VersionComparisonResult.Equal &&
iosVersionComparison == VersionComparisonResult.Equal)
{
network.CurrentToLatestVersionComparisonResult = 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 == VersionComparisonResult.Greater ||
androidVersionComparison == VersionComparisonResult.Greater ||
iosVersionComparison == VersionComparisonResult.Greater)
{
network.CurrentToLatestVersionComparisonResult = VersionComparisonResult.Greater;
}
// We have a new version available if all Android, iOS and Unity has a newer version available in db.
else
{
network.CurrentToLatestVersionComparisonResult = 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 (!string.IsNullOrEmpty(currentVersions.Unity))
{
network.CurrentToLatestVersionComparisonResult = MaxSdkUtils.CompareUnityMediationVersions(currentVersions.Unity, network.LatestVersions.Unity);
}
if (!string.IsNullOrEmpty(network.CurrentVersions.Unity) && AppLovinAutoUpdater.MinAdapterVersions.ContainsKey(network.Name))
{
var comparisonResult = MaxSdkUtils.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>
/// 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 downloadHandler = new DownloadHandlerFile(path);
webRequest = new UnityWebRequest(network.DownloadUrl)
{
method = UnityWebRequest.kHttpVerbGET,
downloadHandler = downloadHandler
};
var operation = webRequest.SendWebRequest();
while (!operation.isDone)
{
yield return new WaitForSeconds(0.1f); // Just wait till webRequest is completed. Our coroutine is pretty rudimentary.
CallDownloadPluginProgressCallback(network.DisplayName, operation.progress, operation.isDone);
}
#if UNITY_2020_1_OR_NEWER
if (webRequest.result != UnityWebRequest.Result.Success)
#else
if (webRequest.isNetworkError || webRequest.isHttpError)
#endif
{
MaxSdkLogger.UserError(webRequest.error);
}
else
{
importingNetwork = network;
AssetDatabase.ImportPackage(path, showImport);
}
webRequest.Dispose();
webRequest = null;
}
/// <summary>
/// Cancels the plugin download if one is in progress.
/// </summary>
public void CancelDownload()
{
if (webRequest == null) return;
webRequest.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);
}
/// <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 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>
public static bool IsAdapterInstalled(string adapterName, string iosVersion = null) // TODO: Add Android version check.
{
var dependencyFilePath = MaxSdkUtils.GetAssetPathForExportPath("MaxSdk/Mediation/" + adapterName + "/Editor/Dependencies.xml");
if (!File.Exists(dependencyFilePath)) return false;
// If version is null, we just need the adapter installed. We don't have to check for a specific version.
if (iosVersion == null) return true;
var currentVersion = GetCurrentVersions(dependencyFilePath);
var iosVersionComparison = MaxSdkUtils.CompareVersions(currentVersion.Ios, iosVersion);
return iosVersionComparison != VersionComparisonResult.Lesser;
}
/// <summary>
/// Checks whether or not an adapter older than the given version exists.
///
/// TODO: Consolidate this method with <see cref="IsAdapterInstalled"/> and return a state enum.
/// </summary>
/// <param name="adapterName">The name of the network (the root adapter folder name in "MaxSdk/Mediation/" folder.</param>
/// <param name="iosVersion">The adapter version to check for.</param>
/// <returns><c>true</c> if an adapter older than the provided version is installed.</returns>
public static bool IsAdapterOlderThanMinVersionInstalled(string adapterName, string iosVersion) // TODO: Add Android version check.
{
var dependencyFilePath = MaxSdkUtils.GetAssetPathForExportPath("MaxSdk/Mediation/" + adapterName + "/Editor/Dependencies.xml");
if (!File.Exists(dependencyFilePath)) return false;
var currentVersion = GetCurrentVersions(dependencyFilePath);
var iosVersionComparison = MaxSdkUtils.CompareVersions(currentVersion.Ios, iosVersion);
return iosVersionComparison == VersionComparisonResult.Lesser;
}
#region Utility Methods
/// <summary>
/// Gets the current versions for a given network's dependency file path.
/// </summary>
/// <param name="dependencyPath">A dependency file path that from which to extract current versions.</param>
/// <returns>Current versions of a given network's dependency file.</returns>
public static Versions GetCurrentVersions(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 new Versions();
}
// <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;
}
}
}
var currentVersions = new Versions();
if (androidVersion != null && iosVersion != null)
{
currentVersions.Unity = string.Format("android_{0}_ios_{1}", androidVersion, iosVersion);
currentVersions.Android = androidVersion;
currentVersions.Ios = iosVersion;
}
else if (androidVersion != null)
{
currentVersions.Unity = string.Format("android_{0}", androidVersion);
currentVersions.Android = androidVersion;
}
else if (iosVersion != null)
{
currentVersions.Unity = string.Format("ios_{0}", iosVersion);
currentVersions.Ios = iosVersion;
}
return currentVersions;
}
/// <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 '.unitypacakge' extension included in its name but the pluginFileName does. So using Contains instead of Equals.
return importingNetwork != null && GetPluginFileName(importingNetwork).Contains(packageName);
}
/// <summary>
/// Adds labels to assets so that they can be easily found.
/// </summary>
/// <param name="pluginParentDir">The MAX Unity plugin's parent directory.</param>
/// <param name="isPluginOutsideAssetsDirectory">Whether or not the plugin is outside the Assets directory.</param>
public static void AddLabelsToAssetsIfNeeded(string pluginParentDir, bool isPluginOutsideAssetsDirectory)
{
if (isPluginOutsideAssetsDirectory)
{
var defaultPluginLocation = Path.Combine("Assets", "MaxSdk");
if (Directory.Exists(defaultPluginLocation))
{
AddLabelsToAssets(defaultPluginLocation, "Assets");
}
}
var pluginDir = Path.Combine(pluginParentDir, "MaxSdk");
AddLabelsToAssets(pluginDir, pluginParentDir);
}
private static void AddLabelsToAssets(string directoryPath, string pluginParentDir)
{
var files = Directory.GetFiles(directoryPath);
foreach (var file in files)
{
if (file.EndsWith(".meta")) continue;
UpdateAssetLabelsIfNeeded(file, pluginParentDir);
}
var directories = Directory.GetDirectories(directoryPath);
foreach (var directory in directories)
{
// Add labels to this directory asset.
UpdateAssetLabelsIfNeeded(directory, pluginParentDir);
// Recursively add labels to all files under this directory.
AddLabelsToAssets(directory, pluginParentDir);
}
}
private static void UpdateAssetLabelsIfNeeded(string assetPath, string pluginParentDir)
{
var asset = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetPath);
var labels = AssetDatabase.GetLabels(asset);
var labelsToAdd = labels.ToList();
var didAddLabels = false;
if (!labels.Contains("al_max"))
{
labelsToAdd.Add("al_max");
didAddLabels = true;
}
var exportPathLabel = "al_max_export_path-" + assetPath.Replace(pluginParentDir, "").Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
if (!labels.Contains(exportPathLabel))
{
labelsToAdd.Add(exportPathLabel);
didAddLabels = true;
}
// We only need to set the labels if they changed.
if (!didAddLabels) return;
AssetDatabase.SetLabels(asset, labelsToAdd.ToArray());
}
/// <summary>
/// Moves the imported plugin files to the MaxSdk directory if the publisher has moved the plugin to a different directory. This is a failsafe for when some plugin files are not imported to the new location.
/// </summary>
/// <returns>True if the adapters have been moved.</returns>
public static bool MovePluginFilesIfNeeded(string pluginParentDirectory, bool isPluginOutsideAssetsDirectory)
{
var pluginDir = Path.Combine(pluginParentDirectory, "MaxSdk");
// Check if the user has moved the Plugin and if new assets have been imported to the default directory.
if (DefaultPluginExportPath.Equals(pluginDir) || !Directory.Exists(DefaultPluginExportPath)) return false;
MovePluginFiles(DefaultPluginExportPath, pluginDir, isPluginOutsideAssetsDirectory);
if (!isPluginOutsideAssetsDirectory)
{
FileUtil.DeleteFileOrDirectory(DefaultPluginExportPath + ".meta");
}
AssetDatabase.Refresh();
return true;
}
/// <summary>
/// A helper function to move all the files recursively from the default plugin dir to a custom location the publisher moved the plugin to.
/// </summary>
private static void MovePluginFiles(string fromDirectory, string pluginRoot, bool isPluginOutsideAssetsDirectory)
{
var files = Directory.GetFiles(fromDirectory);
foreach (var file in files)
{
// We have to ignore some files, if the plugin is outside the Assets/ directory.
if (isPluginOutsideAssetsDirectory && PluginPathsToIgnoreMoveWhenPluginOutsideAssetsDirectory.Any(pluginPathsToIgnore => file.Contains(pluginPathsToIgnore))) continue;
// Check if the destination folder exists and create it if it doesn't exist
var parentDirectory = Path.GetDirectoryName(file);
var destinationDirectoryPath = parentDirectory.Replace(DefaultPluginExportPath, pluginRoot);
if (!Directory.Exists(destinationDirectoryPath))
{
Directory.CreateDirectory(destinationDirectoryPath);
}
// If the meta file is of a folder asset and doesn't have labels (it is auto generated by Unity), just delete it.
if (IsAutoGeneratedFolderMetaFile(file))
{
FileUtil.DeleteFileOrDirectory(file);
continue;
}
var destinationPath = file.Replace(DefaultPluginExportPath, pluginRoot);
// Check if the file is already present at the destination path and delete it.
if (File.Exists(destinationPath))
{
FileUtil.DeleteFileOrDirectory(destinationPath);
}
FileUtil.MoveFileOrDirectory(file, destinationPath);
}
var directories = Directory.GetDirectories(fromDirectory);
foreach (var directory in directories)
{
// We might have to ignore some directories, if the plugin is outside the Assets/ directory.
if (isPluginOutsideAssetsDirectory && PluginPathsToIgnoreMoveWhenPluginOutsideAssetsDirectory.Any(pluginPathsToIgnore => directory.Contains(pluginPathsToIgnore))) continue;
MovePluginFiles(directory, pluginRoot, isPluginOutsideAssetsDirectory);
}
if (!isPluginOutsideAssetsDirectory)
{
FileUtil.DeleteFileOrDirectory(fromDirectory);
}
}
private static bool IsAutoGeneratedFolderMetaFile(string assetPath)
{
// Check if it is a meta file.
if (!assetPath.EndsWith(".meta")) return false;
var lines = File.ReadAllLines(assetPath);
var isFolderAsset = false;
var hasLabels = false;
foreach (var line in lines)
{
if (line.Contains("folderAsset: yes"))
{
isFolderAsset = true;
}
if (line.Contains("labels:"))
{
hasLabels = true;
}
}
// If it is a folder asset and doesn't have a label, the meta file is auto generated by
return isFolderAsset && !hasLabels;
}
private static void CallDownloadPluginProgressCallback(string pluginName, float progress, bool isDone)
{
if (downloadPluginProgressCallback == null) return;
downloadPluginProgressCallback(pluginName, progress, isDone);
}
private static void CallImportPackageCompletedCallback(Network network)
{
if (importPackageCompletedCallback == null) return;
importPackageCompletedCallback(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
}
}

View File

@@ -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:

View File

@@ -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:

View File

@@ -0,0 +1,297 @@
//
// AppLovinInternalSettigns.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;
public const string DefaultUserTrackingDescriptionEn = "This uses device info for more personalized ads and content";
public const string DefaultUserTrackingDescriptionDe = "Dies benutzt Gerätinformationen für relevantere Werbeinhalte";
public const string DefaultUserTrackingDescriptionEs = "Esto utiliza la información del dispositivo para anuncios y contenido más personalizados";
public const string DefaultUserTrackingDescriptionFr = "Cela permet d'utiliser les informations du téléphone pour afficher des contenus publicitaires plus pertinents.";
public const string DefaultUserTrackingDescriptionJa = "これはユーザーデータをもとに、より関連性の高い広告コンテンツをお客様に提供します";
public const string DefaultUserTrackingDescriptionKo = "보다 개인화된 광고 및 콘텐츠를 위해 기기 정보를 사용합니다.";
public const string DefaultUserTrackingDescriptionZhHans = "我们使用设备信息来提供个性化的广告和内容。";
public const string DefaultUserTrackingDescriptionZhHant = "我們使用設備信息來提供個性化的廣告和內容。";
[SerializeField] private bool consentFlowEnabled;
[SerializeField] private string consentFlowPrivacyPolicyUrl = string.Empty;
[SerializeField] private string consentFlowTermsOfServiceUrl = string.Empty;
[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>
/// 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 cref="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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </summary>
public string UserTrackingUsageDescriptionZhHant
{
get { return userTrackingUsageDescriptionZhHant; }
set { userTrackingUsageDescriptionZhHant = value; }
}
}
}

View File

@@ -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:

View File

@@ -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 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://dash.applovin.com/documentation/mediation/unity/getting-started");
}
[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();
}
}
}

View File

@@ -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:

View File

@@ -0,0 +1,416 @@
//
// MaxPostProcessBuildAndroid.cs
// AppLovin MAX Unity Plugin
//
// Created by Santosh Bagadi on 4/10/20.
// Copyright © 2020 AppLovin. All rights reserved.
//
#if UNITY_ANDROID
using AppLovinMax.Scripts.IntegrationManager.Editor;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using UnityEditor;
using UnityEditor.Android;
using UnityEngine;
namespace AppLovinMax.Scripts.Editor
{
/// <summary>
/// A post processor used to update the Android project once it is generated.
/// </summary>
public class AppLovinPostProcessAndroid : IPostGenerateGradleAndroidProject
{
#if UNITY_2019_3_OR_NEWER
private const string PropertyAndroidX = "android.useAndroidX";
private const string PropertyJetifier = "android.enableJetifier";
private const string EnableProperty = "=true";
#endif
private const string PropertyDexingArtifactTransform = "android.enableDexingArtifactTransform";
private const string DisableProperty = "=false";
private const string KeyMetaDataAppLovinSdkKey = "applovin.sdk.key";
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";
#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";
private static string PluginMediationDirectory
{
get
{
var pluginParentDir = AppLovinIntegrationManager.MediationSpecificPluginParentDirectory;
return Path.Combine(pluginParentDir, "MaxSdk/Mediation/");
}
}
public void OnPostGenerateGradleAndroidProject(string path)
{
#if UNITY_2019_3_OR_NEWER
var rootGradleBuildFilePath = Path.Combine(path, "../build.gradle");
var gradlePropertiesPath = Path.Combine(path, "../gradle.properties");
var gradleWrapperPropertiesPath = Path.Combine(path, "../gradle/wrapper/gradle-wrapper.properties");
#else
var rootGradleBuildFilePath = Path.Combine(path, "build.gradle");
var gradlePropertiesPath = Path.Combine(path, "gradle.properties");
var gradleWrapperPropertiesPath = Path.Combine(path, "gradle/wrapper/gradle-wrapper.properties");
#endif
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);
#if UNITY_2019_3_OR_NEWER
// 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)));
#else
// Add all properties except DexingArtifactTransform since it may already exist. We will re-add it below.
gradlePropertiesUpdated.AddRange(lines.Where(line => !line.Contains(PropertyDexingArtifactTransform)));
#endif
}
#if UNITY_2019_3_OR_NEWER
// Enable AndroidX and Jetifier properties
gradlePropertiesUpdated.Add(PropertyAndroidX + EnableProperty);
gradlePropertiesUpdated.Add(PropertyJetifier + EnableProperty);
#endif
// Disable dexing using artifact transform (it causes issues for ExoPlayer with Gradle plugin 3.5.0+)
gradlePropertiesUpdated.Add(PropertyDexingArtifactTransform + DisableProperty);
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);
var rawResourceDirectory = Path.Combine(path, "src/main/res/raw");
if (AppLovinInternalSettings.Instance.ConsentFlowEnabled)
{
AppLovinPreProcessAndroid.EnableConsentFlowIfNeeded(rawResourceDirectory);
}
else
{
AppLovinPreProcessAndroid.EnableTermsFlowIfNeeded(rawResourceDirectory);
}
}
public int callbackOrder
{
get { return int.MaxValue; }
}
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"));
AddSdkKeyIfNeeded(elementApplication);
EnableVerboseLoggingIfNeeded(elementApplication);
AddGoogleApplicationIdIfNeeded(elementApplication, metaDataElements);
AddGoogleOptimizationFlagsIfNeeded(elementApplication, metaDataElements);
DisableAutoInitIfNeeded(elementApplication, metaDataElements);
// Save the updated manifest file.
manifest.Save(manifestPath);
}
private static void AddSdkKeyIfNeeded(XElement elementApplication)
{
var sdkKey = AppLovinSettings.Instance.SdkKey;
if (string.IsNullOrEmpty(sdkKey)) return;
var descendants = elementApplication.Descendants();
var sdkKeyMetaData = descendants.FirstOrDefault(descendant => descendant.FirstAttribute != null &&
descendant.FirstAttribute.Name.LocalName.Equals("name") &&
descendant.FirstAttribute.Value.Equals(KeyMetaDataAppLovinSdkKey) &&
descendant.LastAttribute != null &&
descendant.LastAttribute.Name.LocalName.Equals("value"));
// check if applovin.sdk.key meta data exists.
if (sdkKeyMetaData != null)
{
sdkKeyMetaData.LastAttribute.Value = sdkKey;
}
else
{
// add applovin.sdk.key meta data if it does not exist.
var metaData = CreateMetaDataElement(KeyMetaDataAppLovinSdkKey, sdkKey);
elementApplication.Add(metaData);
}
}
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 (!AppLovinIntegrationManager.IsAdapterInstalled("Google") && !AppLovinIntegrationManager.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 (!AppLovinIntegrationManager.IsAdapterInstalled("Google") && !AppLovinIntegrationManager.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 (AppLovinIntegrationManager.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 (AppLovinIntegrationManager.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 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");
}
}
}
/// <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

View File

@@ -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:

View File

@@ -0,0 +1,65 @@
//
// 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;
using UnityEngine;
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;
#if UNITY_2019_3_OR_NEWER
// On Unity 2019.3+, the path returned is the path to the unityLibrary's module.
// The AppLovin Quality Service buildscript closure related lines need to be added to the root build.gradle file.
var rootGradleBuildFilePath = Path.Combine(path, "../build.gradle");
#if UNITY_2022_2_OR_NEWER
if (!AddPluginToRootGradleBuildFile(rootGradleBuildFilePath)) return;
var rootSettingsGradleFilePath = Path.Combine(path, "../settings.gradle");
if (!AddAppLovinRepository(rootSettingsGradleFilePath)) return;
#else
var buildScriptChangesAdded = AddQualityServiceBuildScriptLines(rootGradleBuildFilePath);
if (!buildScriptChangesAdded) return;
#endif
// The plugin needs to be added to the application module (named launcher)
var applicationGradleBuildFilePath = Path.Combine(path, "../launcher/build.gradle");
#else
// If Gradle template is enabled, we would have already updated the plugin.
if (AppLovinIntegrationManager.GradleTemplateEnabled) return;
var applicationGradleBuildFilePath = Path.Combine(path, "build.gradle");
#endif
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 int.MaxValue; }
}
}
}
#endif

View File

@@ -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:

View File

@@ -0,0 +1,711 @@
//
// 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;
using UnityEditor;
using UnityEditor.Callbacks;
#if UNITY_2019_3_OR_NEWER
using UnityEditor.iOS.Xcode.Extensions;
#endif
using UnityEditor.iOS.Xcode;
using UnityEngine;
using Debug = UnityEngine.Debug;
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";
#if UNITY_2019_3_OR_NEWER
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";
#else
private const string UnityMainTargetName = "Unity-iPhone";
#endif
private const string LegacyResourcesDirectoryName = "Resources";
private const string AppLovinMaxResourcesDirectoryName = "AppLovinMAXResources";
private const string AppLovinAdvertisingAttributionEndpoint = "https://postbacks-app.com";
private const string AppLovinSettingsPlistFileName = "AppLovin-Settings.plist";
private const string KeyConsentFlowInfo = "ConsentFlowInfo";
private const string KeyConsentFlowEnabled = "ConsentFlowEnabled";
private const string KeyConsentFlowTermsOfService = "ConsentFlowTermsOfService";
private const string KeyConsentFlowPrivacyPolicy = "ConsentFlowPrivacyPolicy";
private const string KeyConsentFlowDebugUserGeography = "ConsentFlowDebugUserGeography";
private static List<string> DynamicLibrariesToEmbed
{
get
{
var dynamicLibrariesToEmbed = new List<string>
{
"AppLovinSDK.xcframework",
"DTBiOSSDK.xcframework",
"FBAEMKit.xcframework",
"FBSDKCoreKit_Basics.xcframework",
"FBSDKCoreKit.xcframework",
"FBSDKGamingServicesKit.xcframework",
"FBSDKLoginKit.xcframework",
"FBSDKShareKit.xcframework",
"HyprMX.xcframework",
"Maio.xcframework",
"MobileFuseSDK.xcframework",
"MolocoSDK.xcframework",
"OMSDK_Appodeal.xcframework",
"OMSDK_Ogury.xcframework",
"OMSDK_Pubnativenet.xcframework",
"OMSDK_Smaato.xcframework"
};
// LinkedIn Audience Network SDK is distributed as a static library starting version 1.2.0
if (AppLovinIntegrationManager.IsAdapterOlderThanMinVersionInstalled("LinkedIn", "1.2.0.0"))
{
dynamicLibrariesToEmbed.Add("LinkedinAudienceNetwork.xcframework");
}
// Fyber/IA SDK is distributed as a static library starting version 8.2.7
if (AppLovinIntegrationManager.IsAdapterOlderThanMinVersionInstalled("Fyber", "8.2.7.0"))
{
dynamicLibrariesToEmbed.Add("IASDKCore.xcframework");
}
return dynamicLibrariesToEmbed;
}
}
private static string PluginMediationDirectory
{
get
{
var pluginParentDir = AppLovinIntegrationManager.MediationSpecificPluginParentDirectory;
return Path.Combine(pluginParentDir, "MaxSdk/Mediation/");
}
}
/// <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(int.MaxValue)] // 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;
}
// Download the ruby script needed to install Quality Service
var downloadHandler = new DownloadHandlerFile(outputFilePath);
var postJson = string.Format("{{\"sdk_key\" : \"{0}\"}}", sdkKey);
var bodyRaw = Encoding.UTF8.GetBytes(postJson);
var uploadHandler = new UploadHandlerRaw(bodyRaw);
uploadHandler.contentType = "application/json";
using (var unityWebRequest = new UnityWebRequest("https://api2.safedk.com/v1/build/ios_setup2"))
{
unityWebRequest.method = UnityWebRequest.kHttpVerbPOST;
unityWebRequest.downloadHandler = downloadHandler;
unityWebRequest.uploadHandler = uploadHandler;
var operation = unityWebRequest.SendWebRequest();
// Wait for the download to complete or the request to timeout.
while (!operation.isDone) { }
#if UNITY_2020_1_OR_NEWER
if (unityWebRequest.result != UnityWebRequest.Result.Success)
#else
if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
#endif
{
MaxSdkLogger.UserError("AppLovin Quality Service installation failed. Failed to download script with error: " + unityWebRequest.error);
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);
}
}
[PostProcessBuildAttribute(int.MaxValue)]
public static void MaxPostProcessPbxProject(BuildTarget buildTarget, string buildPath)
{
var projectPath = PBXProject.GetPBXProjectPath(buildPath);
var project = new PBXProject();
project.ReadFromFile(projectPath);
#if UNITY_2019_3_OR_NEWER
var unityMainTargetGuid = project.GetUnityMainTargetGuid();
var unityFrameworkTargetGuid = project.GetUnityFrameworkTargetGuid();
#else
var unityMainTargetGuid = project.TargetGuidByName(UnityMainTargetName);
var unityFrameworkTargetGuid = project.TargetGuidByName(UnityMainTargetName);
#endif
EmbedDynamicLibrariesIfNeeded(buildPath, project, unityMainTargetGuid);
var internalSettingsEnabled = AppLovinInternalSettings.Instance.ConsentFlowEnabled;
var userTrackingUsageDescriptionDe = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionDe : AppLovinSettings.Instance.UserTrackingUsageDescriptionDe;
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionDe, "de", buildPath, project, unityMainTargetGuid);
var userTrackingUsageDescriptionEn = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEn : AppLovinSettings.Instance.UserTrackingUsageDescriptionEn;
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionEn, "en", buildPath, project, unityMainTargetGuid);
var userTrackingUsageDescriptionEs = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionEs : AppLovinSettings.Instance.UserTrackingUsageDescriptionEs;
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionEs, "es", buildPath, project, unityMainTargetGuid);
var userTrackingUsageDescriptionFr = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionFr : AppLovinSettings.Instance.UserTrackingUsageDescriptionFr;
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionFr, "fr", buildPath, project, unityMainTargetGuid);
var userTrackingUsageDescriptionJa = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionJa : AppLovinSettings.Instance.UserTrackingUsageDescriptionJa;
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionJa, "ja", buildPath, project, unityMainTargetGuid);
var userTrackingUsageDescriptionKo = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionKo : AppLovinSettings.Instance.UserTrackingUsageDescriptionKo;
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionKo, "ko", buildPath, project, unityMainTargetGuid);
var userTrackingUsageDescriptionZhHans = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionZhHans : AppLovinSettings.Instance.UserTrackingUsageDescriptionZhHans;
LocalizeUserTrackingDescriptionIfNeeded(userTrackingUsageDescriptionZhHans, "zh-Hans", buildPath, project, unityMainTargetGuid);
var userTrackingUsageDescriptionZhHant = internalSettingsEnabled ? AppLovinInternalSettings.Instance.UserTrackingUsageDescriptionZhHant : AppLovinSettings.Instance.UserTrackingUsageDescriptionZhHant;
LocalizeUserTrackingDescriptionIfNeeded(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)) return;
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 index = dynamicLibraryAbsolutePath.LastIndexOf("Pods");
var relativePath = dynamicLibraryAbsolutePath.Substring(index);
dynamicLibraryPathsPresentInProject.Add(relativePath);
}
if (dynamicLibraryPathsPresentInProject.Count <= 0) return;
#if UNITY_2019_3_OR_NEWER
if (ShouldEmbedDynamicLibraries(buildPath))
{
foreach (var dynamicLibraryPath in dynamicLibraryPathsPresentInProject)
{
var fileGuid = project.AddFile(dynamicLibraryPath, dynamicLibraryPath);
project.AddFileToEmbedFrameworks(targetGuid, fileGuid);
}
}
#else
string runpathSearchPaths;
runpathSearchPaths = project.GetBuildPropertyForAnyConfig(targetGuid, "LD_RUNPATH_SEARCH_PATHS");
runpathSearchPaths += string.IsNullOrEmpty(runpathSearchPaths) ? "" : " ";
// Check if runtime search paths already contains the required search paths for dynamic libraries.
if (runpathSearchPaths.Contains("@executable_path/Frameworks")) return;
runpathSearchPaths += "@executable_path/Frameworks";
project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", runpathSearchPaths);
#endif
}
private static void LocalizeUserTrackingDescriptionIfNeeded(string localizedUserTrackingDescription, string localeCode, string buildPath, PBXProject project, string targetGuid)
{
// Use the legacy resources directory name if the build is being appended (the "Resources" directory already exists if it is an incremental build).
var resourcesDirectoryName = Directory.Exists(Path.Combine(buildPath, LegacyResourcesDirectoryName)) ? LegacyResourcesDirectoryName : AppLovinMaxResourcesDirectoryName;
var resourcesDirectoryPath = Path.Combine(buildPath, resourcesDirectoryName);
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;
}
// 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(resourcesDirectoryName, localeSpecificDirectoryName);
var guid = project.AddFolderReference(localeSpecificDirectoryRelativePath, localeSpecificDirectoryRelativePath);
project.AddFileToBuild(targetGuid, guid);
}
private static bool ShouldRemoveLocalization(string localizedUserTrackingDescription)
{
if (string.IsNullOrEmpty(localizedUserTrackingDescription)) return true;
var settings = AppLovinSettings.Instance;
var internalSettings = AppLovinInternalSettings.Instance;
return (!internalSettings.ConsentFlowEnabled || !internalSettings.UserTrackingUsageLocalizationEnabled)
&& (!settings.ConsentFlowEnabled || !settings.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, PBXSourceTree.Source);
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");
}
// Enable Swift modules
project.AddBuildProperty(unityFrameworkTargetGuid, "CLANG_ENABLE_MODULES", "YES");
project.AddBuildProperty(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();
}
}
[PostProcessBuildAttribute(int.MaxValue)]
public static void MaxPostProcessPlist(BuildTarget buildTarget, string path)
{
var plistPath = Path.Combine(path, "Info.plist");
var plist = new PlistDocument();
plist.ReadFromFile(plistPath);
SetSdkKeyIfNeeded(plist);
SetAttributionReportEndpointIfNeeded(plist);
EnableVerboseLoggingIfNeeded(plist);
AddGoogleApplicationIdIfNeeded(plist);
AddSdkSettingsIfNeeded(plist, path);
EnableTermsFlowIfNeeded(plist);
AddSkAdNetworksInfoIfNeeded(plist);
plist.WriteToFile(plistPath);
}
private static void SetSdkKeyIfNeeded(PlistDocument plist)
{
var sdkKey = AppLovinSettings.Instance.SdkKey;
if (string.IsNullOrEmpty(sdkKey)) return;
const string AppLovinVerboseLoggingOnKey = "AppLovinSdkKey";
plist.root.SetString(AppLovinVerboseLoggingOnKey, sdkKey);
}
private static void SetAttributionReportEndpointIfNeeded(PlistDocument plist)
{
if (AppLovinSettings.Instance.SetAttributionReportEndpoint)
{
plist.root.SetString("NSAdvertisingAttributionReportEndpoint", AppLovinAdvertisingAttributionEndpoint);
}
else
{
PlistElement attributionReportEndPoint;
plist.root.values.TryGetValue("NSAdvertisingAttributionReportEndpoint", out attributionReportEndPoint);
// Check if we had previously set the attribution endpoint and un-set it.
if (attributionReportEndPoint != null && AppLovinAdvertisingAttributionEndpoint.Equals(attributionReportEndPoint.AsString()))
{
plist.root.values.Remove("NSAdvertisingAttributionReportEndpoint");
}
}
}
private static void EnableVerboseLoggingIfNeeded(PlistDocument plist)
{
if (!EditorPrefs.HasKey(MaxSdkLogger.KeyVerboseLoggingEnabled)) return;
var enabled = EditorPrefs.GetBool(MaxSdkLogger.KeyVerboseLoggingEnabled);
const string AppLovinVerboseLoggingOnKey = "AppLovinVerboseLoggingOn";
if (enabled)
{
plist.root.SetBoolean(AppLovinVerboseLoggingOnKey, enabled);
}
else
{
plist.root.values.Remove(AppLovinVerboseLoggingOnKey);
}
}
private static void AddGoogleApplicationIdIfNeeded(PlistDocument plist)
{
if (!AppLovinIntegrationManager.IsAdapterInstalled("Google") && !AppLovinIntegrationManager.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-"))
{
Debug.LogError("[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 (!AppLovinIntegrationManager.IsAdapterInstalled("Yandex")) return;
if (MaxSdkUtils.CompareVersions(PlayerSettings.iOS.targetOSVersionString, "12.0") == MaxSdkUtils.VersionComparisonResult.Lesser)
{
Debug.LogWarning("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 AddSdkSettingsIfNeeded(PlistDocument infoPlist, string buildPath)
{
// Right now internal settings is only needed for Consent Flow. Remove this setting once we add more settings.
if (!AppLovinInternalSettings.Instance.ConsentFlowEnabled) return;
var sdkSettingsPlistPath = Path.Combine(buildPath, AppLovinSettingsPlistFileName);
var sdkSettingsPlist = new PlistDocument();
if (File.Exists(sdkSettingsPlistPath))
{
sdkSettingsPlist.ReadFromFile(sdkSettingsPlistPath);
}
EnableConsentFlowIfNeeded(sdkSettingsPlist, infoPlist);
sdkSettingsPlist.WriteToFile(sdkSettingsPlistPath);
var projectPath = PBXProject.GetPBXProjectPath(buildPath);
var project = new PBXProject();
project.ReadFromFile(projectPath);
#if UNITY_2019_3_OR_NEWER
var unityMainTargetGuid = project.GetUnityMainTargetGuid();
#else
var unityMainTargetGuid = project.TargetGuidByName(UnityMainTargetName);
#endif
var guid = project.AddFile(AppLovinSettingsPlistFileName, AppLovinSettingsPlistFileName, PBXSourceTree.Source);
project.AddFileToBuild(unityMainTargetGuid, guid);
project.WriteToFile(projectPath);
}
private static void EnableConsentFlowIfNeeded(PlistDocument applovinSettingsPlist, PlistDocument infoPlist)
{
var consentFlowEnabled = AppLovinInternalSettings.Instance.ConsentFlowEnabled;
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 debugUserGeography = AppLovinInternalSettings.Instance.DebugUserGeography;
if (debugUserGeography == MaxSdkBase.ConsentFlowUserGeography.Gdpr)
{
consentFlowInfoRoot.SetString(KeyConsentFlowDebugUserGeography, "gdpr");
}
infoPlist.root.SetString("NSUserTrackingUsageDescription", userTrackingUsageDescription);
}
private static void EnableTermsFlowIfNeeded(PlistDocument plist)
{
// Check if terms flow is enabled. No need to update info.plist if consent flow is disabled.
var consentFlowEnabled = AppLovinSettings.Instance.ConsentFlowEnabled;
if (!consentFlowEnabled) return;
// Check if terms flow is enabled for this format.
var consentFlowPlatform = AppLovinSettings.Instance.ConsentFlowPlatform;
if (consentFlowPlatform != Platform.All && consentFlowPlatform != Platform.iOS) return;
var userTrackingUsageDescription = AppLovinSettings.Instance.UserTrackingUsageDescriptionEn;
var privacyPolicyUrl = AppLovinSettings.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 = plist.root.CreateDict("AppLovinConsentFlowInfo");
consentFlowInfoRoot.SetBoolean("AppLovinConsentFlowEnabled", consentFlowEnabled);
consentFlowInfoRoot.SetString("AppLovinConsentFlowPrivacyPolicy", privacyPolicyUrl);
var termsOfServiceUrl = AppLovinSettings.Instance.ConsentFlowTermsOfServiceUrl;
if (!string.IsNullOrEmpty(termsOfServiceUrl))
{
consentFlowInfoRoot.SetString("AppLovinConsentFlowTermsOfService", termsOfServiceUrl);
}
plist.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()
{
var uriBuilder = new UriBuilder("https://unity.applovin.com/max/1.0/skadnetwork_ids");
// Get the list of installed ad networks to be passed up
var maxMediationDirectory = PluginMediationDirectory;
if (Directory.Exists(maxMediationDirectory))
{
var mediationNetworkDirectories = Directory.GetDirectories(maxMediationDirectory);
var installedNetworks = mediationNetworkDirectories.Select(Path.GetFileName).ToList();
if (AppLovinSettings.Instance.AddApsSkAdNetworkIds)
{
installedNetworks.Add("AmazonPublisherServices");
}
var adNetworks = string.Join(",", installedNetworks.ToArray());
if (!string.IsNullOrEmpty(adNetworks))
{
uriBuilder.Query += string.Format("ad_networks={0}", adNetworks);
}
}
using (var unityWebRequest = UnityWebRequest.Get(uriBuilder.ToString()))
{
var operation = unityWebRequest.SendWebRequest();
// Wait for the download to complete or the request to timeout.
while (!operation.isDone) { }
#if UNITY_2020_1_OR_NEWER
if (unityWebRequest.result != UnityWebRequest.Result.Success)
#else
if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
#endif
{
MaxSdkLogger.UserError("Failed to retrieve SKAdNetwork IDs with error: " + unityWebRequest.error);
return new SkAdNetworkData();
}
try
{
return JsonUtility.FromJson<SkAdNetworkData>(unityWebRequest.downloadHandler.text);
}
catch (Exception exception)
{
MaxSdkLogger.UserError("Failed to parse data '" + unityWebRequest.downloadHandler.text + "' with exception: " + exception);
return new SkAdNetworkData();
}
}
}
#if UNITY_2019_3_OR_NEWER
/// <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;
}
#endif
}
}
#endif

View File

@@ -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:

View File

@@ -0,0 +1,105 @@
//
// AppLovinPreProcess.cs
// AppLovin MAX Unity Plugin
//
// Created by Jonathan Liu on 10/19/2023.
// Copyright © 2023 AppLovin. All rights reserved.
//
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using UnityEngine;
namespace AppLovinMax.Scripts.IntegrationManager.Editor
{
public abstract class AppLovinPreProcess
{
private const string AppLovinDependenciesFileExportPath = "MaxSdk/AppLovin/Editor/Dependencies.xml";
private static readonly XmlWriterSettings DependenciesFileXmlWriterSettings = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
NewLineChars = "\n",
NewLineHandling = NewLineHandling.Replace
};
/// <summary>
/// Adds a string into AppLovin's Dependencies.xml file inside the containerElementString if it doesn't exist
/// </summary>
/// <param name="lineToAdd">The line you want to add into the xml file</param>
/// <param name="containerElementString">The root XML element under which to add the line. For example, to add a new dependency to Android, pass in "androidPackages"</param>
protected static void TryAddStringToDependencyFile(string lineToAdd, string containerElementString)
{
try
{
var dependenciesFilePath = MaxSdkUtils.GetAssetPathForExportPath(AppLovinDependenciesFileExportPath);
var dependencies = XDocument.Load(dependenciesFilePath);
// Get the container where we are going to insert the line
var containerElement = dependencies.Descendants(containerElementString).FirstOrDefault();
if (containerElement == null)
{
Debug.LogError(containerElementString + " not found in Dependencies.xml file");
return;
}
var elementToAdd = XElement.Parse(lineToAdd);
// Check if the xml file doesn't already contain the string.
if (containerElement.Elements().Any(element => XNode.DeepEquals(element, elementToAdd))) return;
// Append the new element to the container element
containerElement.Add(elementToAdd);
using (var xmlWriter = XmlWriter.Create(dependenciesFilePath, DependenciesFileXmlWriterSettings))
{
dependencies.Save(xmlWriter);
}
}
catch (Exception exception)
{
Debug.LogError("Google CMP will not function. Unable to add string to dependency file due to exception: " + exception.Message);
}
}
/// <summary>
/// Removes a string from AppLovin's Dependencies.xml file inside the containerElementString if it exists
/// </summary>
/// <param name="lineToRemove">The line you want to remove from the xml file</param>
/// <param name="containerElementString">The root XML element from which to remove the line. For example, to remove an Android dependency, pass in "androidPackages"</param>
protected static void TryRemoveStringFromDependencyFile(string lineToRemove, string containerElementString)
{
try
{
var dependenciesFilePath = MaxSdkUtils.GetAssetPathForExportPath(AppLovinDependenciesFileExportPath);
var dependencies = XDocument.Load(dependenciesFilePath);
var containerElement = dependencies.Descendants(containerElementString).FirstOrDefault();
if (containerElement == null)
{
Debug.LogError(containerElementString + " not found in Dependencies.xml file");
return;
}
// Check if the dependency line exists.
var elementToFind = XElement.Parse(lineToRemove);
var existingElement = containerElement.Elements().FirstOrDefault(element => XNode.DeepEquals(element, elementToFind));
if (existingElement == null) return;
existingElement.Remove();
using (var xmlWriter = XmlWriter.Create(dependenciesFilePath, DependenciesFileXmlWriterSettings))
{
dependencies.Save(xmlWriter);
}
}
catch (Exception exception)
{
Debug.LogError("Unable to remove string from dependency file due to exception: " + exception.Message);
}
}
}
}

View File

@@ -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:

View File

@@ -0,0 +1,204 @@
//
// 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.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using AppLovinMax.ThirdParty.MiniJson;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
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 AppLovinSettingsFileName = "applovin_settings.json";
private const string KeyTermsFlowSettings = "terms_flow_settings";
private const string KeyTermsFlowEnabled = "terms_flow_enabled";
private const string KeyTermsFlowTermsOfService = "terms_flow_terms_of_service";
private const string KeyTermsFlowPrivacyPolicy = "terms_flow_privacy_policy";
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 KeyConsentFlowDebugUserGeography = "consent_flow_debug_user_geography";
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;
#if UNITY_2019_3_OR_NEWER
// 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);
#else
AddAppLovinQualityServicePlugin(AppLovinIntegrationManager.GradleTemplatePath);
#endif
}
public static void EnableConsentFlowIfNeeded(string rawResourceDirectory)
{
// 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;
}
var debugUserGeography = AppLovinInternalSettings.Instance.DebugUserGeography;
if (debugUserGeography == MaxSdkBase.ConsentFlowUserGeography.Gdpr)
{
consentFlowSettings[KeyConsentFlowDebugUserGeography] = "gdpr";
}
var applovinSdkSettings = new Dictionary<string, object>();
applovinSdkSettings[KeyConsentFlowSettings] = consentFlowSettings;
var applovinSdkSettingsJson = Json.Serialize(applovinSdkSettings);
WriteAppLovinSettingsRawResourceFile(applovinSdkSettingsJson, rawResourceDirectory);
}
public static void EnableTermsFlowIfNeeded(string rawResourceDirectory)
{
if (AppLovinInternalSettings.Instance.ConsentFlowEnabled) return;
// Check if terms flow is enabled for this format. No need to create the applovin_consent_flow_settings.json if consent flow is disabled.
var consentFlowEnabled = AppLovinSettings.Instance.ConsentFlowEnabled;
var consentFlowPlatform = AppLovinSettings.Instance.ConsentFlowPlatform;
if (!consentFlowEnabled || (consentFlowPlatform != Platform.All && consentFlowPlatform != Platform.Android))
{
RemoveAppLovinSettingsRawResourceFileIfNeeded(rawResourceDirectory);
return;
}
var privacyPolicyUrl = AppLovinSettings.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[KeyTermsFlowEnabled] = consentFlowEnabled;
consentFlowSettings[KeyTermsFlowPrivacyPolicy] = privacyPolicyUrl;
var termsOfServiceUrl = AppLovinSettings.Instance.ConsentFlowTermsOfServiceUrl;
if (MaxSdkUtils.IsValidString(termsOfServiceUrl))
{
consentFlowSettings[KeyTermsFlowTermsOfService] = termsOfServiceUrl;
}
var applovinSdkSettings = new Dictionary<string, object>();
applovinSdkSettings[KeyTermsFlowSettings] = consentFlowSettings;
var applovinSdkSettingsJson = Json.Serialize(applovinSdkSettings);
WriteAppLovinSettingsRawResourceFile(applovinSdkSettingsJson, rawResourceDirectory);
}
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 AddGoogleCmpDependencyIfNeeded()
{
const string umpDependencyLine = "<androidPackage spec=\"com.google.android.ump:user-messaging-platform:2.1.0\" />";
const string containerElementString = "androidPackages";
if (AppLovinInternalSettings.Instance.ConsentFlowEnabled)
{
TryAddStringToDependencyFile(umpDependencyLine, containerElementString);
}
else
{
TryRemoveStringFromDependencyFile(umpDependencyLine, containerElementString);
}
}
public int callbackOrder
{
get { return int.MaxValue; }
}
}
}
#endif

View File

@@ -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:

View File

@@ -0,0 +1,45 @@
//
// AppLovinBuildPreProcessiOS.cs
// AppLovin MAX Unity Plugin
//
// Created by Jonathan Liu on 10/17/2023.
// Copyright © 2023 AppLovin. All rights reserved.
//
#if UNITY_IOS
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
namespace AppLovinMax.Scripts.IntegrationManager.Editor
{
public class AppLovinPreProcessiOS : AppLovinPreProcess, IPreprocessBuildWithReport
{
public void OnPreprocessBuild(BuildReport report)
{
AddGoogleCmpDependencyIfNeeded();
}
private static void AddGoogleCmpDependencyIfNeeded()
{
const string umpDependencyLine = "<iosPod name=\"GoogleUserMessagingPlatform\" version=\"2.1.0\" />";
const string containerElementString = "iosPods";
if (AppLovinInternalSettings.Instance.ConsentFlowEnabled)
{
TryAddStringToDependencyFile(umpDependencyLine, containerElementString);
}
else
{
TryRemoveStringFromDependencyFile(umpDependencyLine, containerElementString);
}
}
public int callbackOrder
{
get { return int.MaxValue; }
}
}
}
#endif

View File

@@ -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:

View File

@@ -0,0 +1,577 @@
// AppLovin MAX Unity Plugin
//
// Created by Santosh Bagadi on 9/3/19.
// Copyright © 2019 AppLovin. All rights reserved.
//
#if UNITY_ANDROID
using System.Text;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Networking;
using Debug = UnityEngine.Debug;
namespace AppLovinMax.Scripts.IntegrationManager.Editor
{
[Serializable]
public class AppLovinQualityServiceData
{
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).*");
#if UNITY_2022_2_OR_NEWER
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+";
#endif
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>
/// 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,
#if UNITY_2019_3_OR_NEWER
false // On Unity 2019.3+, the buildscript closure related lines will to be added to the root build.gradle file.
#else
true
#endif
);
// 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);
}
}
#if UNITY_2022_2_OR_NEWER
/// <summary>
/// Adds AppLovin Quality Service plugin DSL element to the project's root build.gradle file.
/// </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>
protected 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)
{
MaxSdkLogger.UserError("Failed to add AppLovin Quality Service plugin to root gradle file.");
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.
/// </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>
protected 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)
{
MaxSdkLogger.UserError("Failed to add AppLovin Quality Service plugin maven repo to settings gradle file.");
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;
}
#endif
#if UNITY_2019_3_OR_NEWER
/// <summary>
/// Adds the necessary AppLovin Quality Service dependency and maven repo lines to the provided root build.gradle file.
/// </summary>
/// <param name="rootGradleBuildFile">The root build.gradle file path</param>
/// <returns><c>true</c> if the build script lines were applied correctly.</returns>
protected 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);
}
}
#endif
private static AppLovinQualityServiceData RetrieveQualityServiceData(string sdkKey)
{
var postJson = string.Format("{{\"sdk_key\" : \"{0}\"}}", sdkKey);
var bodyRaw = Encoding.UTF8.GetBytes(postJson);
// Upload handler is automatically disposed when UnityWebRequest is disposed
var uploadHandler = new UploadHandlerRaw(bodyRaw);
uploadHandler.contentType = "application/json";
using (var unityWebRequest = new UnityWebRequest("https://api2.safedk.com/v1/build/cred"))
{
unityWebRequest.method = UnityWebRequest.kHttpVerbPOST;
unityWebRequest.uploadHandler = uploadHandler;
unityWebRequest.downloadHandler = new DownloadHandlerBuffer();
var operation = unityWebRequest.SendWebRequest();
// Wait for the download to complete or the request to timeout.
while (!operation.isDone) { }
#if UNITY_2020_1_OR_NEWER
if (unityWebRequest.result != UnityWebRequest.Result.Success)
#else
if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
#endif
{
MaxSdkLogger.UserError("Failed to retrieve API Key for SDK Key: " + sdkKey + "with error: " + unityWebRequest.error);
return new AppLovinQualityServiceData();
}
try
{
return JsonUtility.FromJson<AppLovinQualityServiceData>(unityWebRequest.downloadHandler.text);
}
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)
{
var addPlugin = !string.IsNullOrEmpty(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>();
// Check if the plugin exists, if so, update the SDK Key.
var pluginExists = lines.Any(line => TokenAppLovinPlugin.IsMatch(line));
if (pluginExists)
{
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);
}
}
}
// Plugin hasn't been added yet, add it.
else
{
var buildScriptClosureDepth = 0;
var insideBuildScriptClosure = false;
var buildScriptMatched = false;
var qualityServiceRepositoryAdded = false;
var qualityServiceDependencyClassPathAdded = false;
var qualityServicePluginAdded = false;
foreach (var line in lines)
{
// Add the line to the output lines.
outputLines.Add(line);
// Check if we need to add the build script lines and add them.
if (addBuildScriptLines)
{
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;
}
}
}
// Check if we need to add the plugin and add it.
if (addPlugin)
{
// Add the plugin.
if (!qualityServicePluginAdded && TokenApplicationPlugin.IsMatch(line))
{
outputLines.Add(QualityServiceApplyPlugin);
outputLines.AddRange(GenerateAppLovinPluginClosure(apiKey));
qualityServicePluginAdded = true;
}
}
}
if ((addBuildScriptLines && (!qualityServiceRepositoryAdded || !qualityServiceDependencyClassPathAdded)) || (addPlugin && !qualityServicePluginAdded))
{
MaxSdkLogger.UserError("Failed to add AppLovin Quality Service plugin. Quality Service Plugin Added?: " + qualityServicePluginAdded + ", Quality Service Repo added?: " + qualityServiceRepositoryAdded + ", Quality Service dependency added?: " + qualityServiceDependencyClassPathAdded);
return null;
}
}
return outputLines;
}
public static string GetFormattedBuildScriptLine(string buildScriptLine)
{
#if UNITY_2022_2_OR_NEWER
return " "
#elif UNITY_2019_3_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

View File

@@ -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:

View File

@@ -0,0 +1,425 @@
//
// 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;
namespace AppLovinMax.Scripts.IntegrationManager.Editor
{
public enum Platform
{
All,
Android,
iOS
}
}
/// <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
{
public const string SettingsExportPath = "MaxSdk/Resources/AppLovinSettings.asset";
public const string DefaultUserTrackingDescriptionEnV0 = "Pressing \\\"Allow\\\" uses device info for more relevant ad content";
public const string DefaultUserTrackingDescriptionEnV1 = "This only uses device info for less annoying, more relevant ads";
public const string DefaultUserTrackingDescriptionEnV2 = "This only uses device info for more interesting and relevant ads";
public const string DefaultUserTrackingDescriptionEnV3 = "This uses device info for more personalized ads and content";
public const string DefaultUserTrackingDescriptionDe = "\\\"Erlauben\\\" drücken benutzt Gerätinformationen für relevantere Werbeinhalte";
public const string DefaultUserTrackingDescriptionEs = "Presionando \\\"Permitir\\\", se usa la información del dispositivo para obtener contenido publicitario más relevante";
public const string DefaultUserTrackingDescriptionFr = "\\\"Autoriser\\\" permet d'utiliser les infos du téléphone pour afficher des contenus publicitaires plus pertinents";
public const string DefaultUserTrackingDescriptionJa = "\\\"許可\\\"をクリックすることで、デバイス情報を元により最適な広告を表示することができます";
public const string DefaultUserTrackingDescriptionKo = "\\\"허용\\\"을 누르면 더 관련성 높은 광고 콘텐츠를 제공하기 위해 기기 정보가 사용됩니다";
public const string DefaultUserTrackingDescriptionZhHans = "点击\\\"允许\\\"以使用设备信息获得更加相关的广告内容";
public const string DefaultUserTrackingDescriptionZhHant = "點擊\\\"允許\\\"以使用設備信息獲得更加相關的廣告內容";
/// <summary>
/// A placeholder constant to be replaced with the actual default localization or an empty string based on whether or not localization is enabled when when the getter is called.
/// </summary>
protected const string DefaultLocalization = "default_localization";
private static AppLovinSettings instance;
[SerializeField] private bool qualityServiceEnabled = true;
[SerializeField] private string sdkKey;
[SerializeField] private bool setAttributionReportEndpoint;
[SerializeField] private bool addApsSkAdNetworkIds;
[SerializeField] private string customGradleVersionUrl;
[SerializeField] private string customGradleToolsVersion;
[SerializeField] private bool consentFlowEnabled;
[SerializeField] private Platform consentFlowPlatform;
[SerializeField] private string consentFlowPrivacyPolicyUrl = string.Empty;
[SerializeField] private string consentFlowTermsOfServiceUrl = string.Empty;
[FormerlySerializedAs("userTrackingUsageDescription")] [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 = DefaultLocalization;
[SerializeField] private string adMobAndroidAppId = string.Empty;
[SerializeField] private string adMobIosAppId = string.Empty;
[SerializeField] private bool showInternalSettingsInIntegrationManager;
/// <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;
}
// If there is no existing AppLovinSettings asset, create one in the default location
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, create the settings asset at the default location.
if (AppLovinIntegrationManager.IsPluginOutsideAssetsDirectory)
{
// Note: Can't use absolute path when calling `CreateAsset`. Should use relative path to Assets/ directory.
settingsFilePath = Path.Combine("Assets", SettingsExportPath);
var maxSdkDir = Path.Combine(Application.dataPath, "MaxSdk");
if (!Directory.Exists(maxSdkDir))
{
Directory.CreateDirectory(maxSdkDir);
}
}
else
{
settingsFilePath = 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>
/// Whether or not to set `NSAdvertisingAttributionReportEndpoint` in Info.plist.
/// </summary>
public bool SetAttributionReportEndpoint
{
get { return Instance.setAttributionReportEndpoint; }
set { Instance.setAttributionReportEndpoint = value; }
}
/// <summary>
/// Whether or not to add Amazon Publisher Services SKAdNetworkID's.
/// </summary>
public bool AddApsSkAdNetworkIds
{
get { return Instance.addApsSkAdNetworkIds; }
set { Instance.addApsSkAdNetworkIds = 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>
/// Whether or not AppLovin Consent Flow is enabled.
/// </summary>
public bool ConsentFlowEnabled
{
get
{
// Update the default EN description if an old version of the description is still being used.
if (DefaultUserTrackingDescriptionEnV0.Equals(Instance.UserTrackingUsageDescriptionEn)
|| DefaultUserTrackingDescriptionEnV1.Equals(Instance.UserTrackingUsageDescriptionEn)
|| DefaultUserTrackingDescriptionEnV2.Equals(Instance.UserTrackingUsageDescriptionEn))
{
Instance.UserTrackingUsageDescriptionEn = DefaultUserTrackingDescriptionEnV3;
}
return Instance.consentFlowEnabled;
}
set
{
var previousValue = Instance.consentFlowEnabled;
Instance.consentFlowEnabled = value;
if (value)
{
// If the value didn't change, we don't need to update anything.
if (previousValue) return;
Instance.UserTrackingUsageDescriptionEn = DefaultUserTrackingDescriptionEnV3;
Instance.UserTrackingUsageLocalizationEnabled = true;
}
else
{
Instance.ConsentFlowPlatform = Platform.All;
Instance.ConsentFlowPrivacyPolicyUrl = string.Empty;
Instance.ConsentFlowTermsOfServiceUrl = string.Empty;
Instance.UserTrackingUsageDescriptionEn = string.Empty;
Instance.UserTrackingUsageLocalizationEnabled = false;
}
}
}
public Platform ConsentFlowPlatform
{
get { return Instance.consentFlowEnabled ? Instance.consentFlowPlatform : Platform.All; }
set { Instance.consentFlowPlatform = value; }
}
/// <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 Instance.consentFlowPrivacyPolicyUrl; }
set { Instance.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 Instance.consentFlowTermsOfServiceUrl; }
set { Instance.consentFlowTermsOfServiceUrl = 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 cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </summary>
public string UserTrackingUsageDescriptionEn
{
get { return Instance.userTrackingUsageDescriptionEn; }
set { Instance.userTrackingUsageDescriptionEn = value; }
}
/// <summary>
/// Whether or not to localize User Tracking Usage Description.
/// For more information see <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </summary>
public bool UserTrackingUsageLocalizationEnabled
{
get { return Instance.userTrackingUsageLocalizationEnabled; }
set
{
var previousValue = Instance.userTrackingUsageLocalizationEnabled;
Instance.userTrackingUsageLocalizationEnabled = value;
if (value)
{
// If the value didn't change or the english localization text is not the default one, we don't need to update anything.
if (previousValue || !DefaultUserTrackingDescriptionEnV3.Equals(Instance.UserTrackingUsageDescriptionEn)) return;
Instance.UserTrackingUsageDescriptionDe = DefaultUserTrackingDescriptionDe;
Instance.UserTrackingUsageDescriptionEs = DefaultUserTrackingDescriptionEs;
Instance.UserTrackingUsageDescriptionFr = DefaultUserTrackingDescriptionFr;
Instance.UserTrackingUsageDescriptionJa = DefaultUserTrackingDescriptionJa;
Instance.UserTrackingUsageDescriptionKo = DefaultUserTrackingDescriptionKo;
Instance.UserTrackingUsageDescriptionZhHans = DefaultUserTrackingDescriptionZhHans;
Instance.UserTrackingUsageDescriptionZhHant = DefaultUserTrackingDescriptionZhHant;
}
else
{
Instance.UserTrackingUsageDescriptionDe = string.Empty;
Instance.UserTrackingUsageDescriptionEs = string.Empty;
Instance.UserTrackingUsageDescriptionFr = string.Empty;
Instance.UserTrackingUsageDescriptionJa = string.Empty;
Instance.UserTrackingUsageDescriptionKo = string.Empty;
Instance.UserTrackingUsageDescriptionZhHans = string.Empty;
Instance.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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </summary>
public string UserTrackingUsageDescriptionDe
{
get { return Instance.userTrackingUsageDescriptionDe; }
set { Instance.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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </summary>
public string UserTrackingUsageDescriptionEs
{
get { return Instance.userTrackingUsageDescriptionEs; }
set { Instance.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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </summary>
public string UserTrackingUsageDescriptionFr
{
get { return Instance.userTrackingUsageDescriptionFr; }
set { Instance.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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </summary>
public string UserTrackingUsageDescriptionJa
{
get { return Instance.userTrackingUsageDescriptionJa; }
set { Instance.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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </summary>
public string UserTrackingUsageDescriptionKo
{
get { return Instance.userTrackingUsageDescriptionKo; }
set { Instance.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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </summary>
public string UserTrackingUsageDescriptionZhHans
{
get { return Instance.userTrackingUsageDescriptionZhHans; }
set { Instance.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 <see cref="https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription">Apple's documentation</see>.
/// </summary>
public string UserTrackingUsageDescriptionZhHant
{
get
{
// Since this localization has been added separate from the other localizations,
// we use a placeholder constant to be replaced with the actual value or an empty string based on whether or not the localization was enabled by the publisher.
if (DefaultLocalization.Equals(Instance.userTrackingUsageDescriptionZhHant))
{
Instance.userTrackingUsageDescriptionZhHant = Instance.UserTrackingUsageLocalizationEnabled ? DefaultUserTrackingDescriptionZhHant : string.Empty;
}
return Instance.userTrackingUsageDescriptionZhHant;
}
set { Instance.userTrackingUsageDescriptionZhHant = 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; }
}
public bool ShowInternalSettingsInIntegrationManager
{
get { return Instance.showInternalSettingsInIntegrationManager; }
set { Instance.showInternalSettingsInIntegrationManager = value; }
}
/// <summary>
/// Saves the instance of the settings.
/// </summary>
public void SaveAsync()
{
EditorUtility.SetDirty(instance);
}
}

View File

@@ -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:

View File

@@ -0,0 +1,10 @@
{
"name": "MaxSdk.Scripts.IntegrationManager.Editor",
"references": [
"MaxSdk.Scripts"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": []
}

View File

@@ -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

View File

@@ -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; }
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: f2e895983b04846af81b59189de0310c
labels:
- al_max
- al_max_export_path-MaxSdk/Scripts/MaxCmpService.cs
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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 List<MaxAction> adEventsQueue = new List<MaxAction>();
private static volatile bool adEventsQueueEmpty = true;
struct MaxAction
{
public Action action;
public string eventName;
public MaxAction(Action actionToExecute, string nameOfEvent)
{
action = 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
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.action.Target != null)
{
try
{
maxAction.action.Invoke();
}
catch (Exception exception)
{
MaxSdkLogger.UserError("Caught exception in publisher event: " + maxAction.eventName + ", exception: " + exception);
Debug.LogException(exception);
}
}
}
}
public void Disable()
{
instance = null;
}
}
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 4715dd62632564dc4810a4dc98243f4a
labels:
- al_max
- al_max_export_path-MaxSdk/Scripts/MaxEventExecutor.cs
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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 = UnityEngine.EventSystems.EventSystem.current;
if (currentSystem == null || currentSystem == eventSystem)
{
eventSystem.enabled = true;
}
else
{
eventSystem.enabled = false;
}
}
}
}
#endif

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: e0acf281ba86b4929a6942ecd998395b
labels:
- al_max
- al_max_export_path-MaxSdk/Scripts/MaxEventSystemChecker.cs
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More