Compare commits
	
		
			66 Commits 
		
	
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
									
								
								 | 
						58cc5a3b46 | |
| 
							
							
								
									
								
								 | 
						1ef9e3ccec | |
| 
							
							
								
									
								
								 | 
						88efffa89f | |
| 
							
							
								
									
								
								 | 
						018fb2c35b | |
| 
							
							
								
									
								
								 | 
						0870e71cf9 | |
| 
							
							
								
									
								
								 | 
						15785b92a2 | |
| 
							
							
								
									
								
								 | 
						a67ba09408 | |
| 
							
							
								
									
								
								 | 
						6dbbd27eb7 | |
| 
							
							
								
									
								
								 | 
						643bb23939 | |
| 
							
							
								
									
								
								 | 
						b0670ccafc | |
| 
							
							
								
									
								
								 | 
						7214c447a6 | |
| 
							
							
								
									
								
								 | 
						49774c3281 | |
| 
							
							
								
									
								
								 | 
						c001fe09ac | |
| 
							
							
								
									
								
								 | 
						a063c4866d | |
| 
							
							
								
									
								
								 | 
						3062467e84 | |
| 
							
							
								
									
								
								 | 
						d4f5342e7f | |
| 
							
							
								
									
								
								 | 
						f099a99c95 | |
| 
							
							
								
									
								
								 | 
						6b95c2ab2f | |
| 
							
							
								
									
								
								 | 
						06792d098f | |
| 
							
							
								
									
								
								 | 
						af1ec1e04f | |
| 
							
							
								
									
								
								 | 
						2494bd2748 | |
| 
							
							
								
									
								
								 | 
						5c3be01eb3 | |
| 
							
							
								
									
								
								 | 
						149bc438ac | |
| 
							
							
								
									
								
								 | 
						e814324e98 | |
| 
							
							
								
									
								
								 | 
						46cd1717fb | |
| 
							
							
								
									
								
								 | 
						aec21f3789 | |
| 
							
							
								
									
								
								 | 
						cc65e9173c | |
| 
							
							
								
									
								
								 | 
						2bde58e27e | |
| 
							
							
								
									
								
								 | 
						b3c541cb84 | |
| 
							
							
								
									
								
								 | 
						ceeeeaf15f | |
| 
							
							
								
									
								
								 | 
						257f9796a5 | |
| 
							
							
								
									
								
								 | 
						fd01939a5f | |
| 
							
							
								
									
								
								 | 
						48c5235335 | |
| 
							
							
								
									
								
								 | 
						42c7302ea3 | |
| 
							
							
								
									
								
								 | 
						4da06c8f96 | |
| 
							
							
								
									
								
								 | 
						ecf615598c | |
| 
							
							
								
									
								
								 | 
						0a2fca05ab | |
| 
							
							
								
									
								
								 | 
						555638e31e | |
| 
							
							
								
									
								
								 | 
						3555b70ea7 | |
| 
							
							
								
									
								
								 | 
						314aaaa88b | |
| 
							
							
								
									
								
								 | 
						4246251295 | |
| 
							
							
								
									
								
								 | 
						1e59e5efa6 | |
| 
							
							
								
									
								
								 | 
						4721e027b2 | |
| 
							
							
								
									
								
								 | 
						b9291e7885 | |
| 
							
							
								
									
								
								 | 
						3050b67a31 | |
| 
							
							
								
									
								
								 | 
						9f0ba03957 | |
| 
							
							
								
									
								
								 | 
						3de35b69e5 | |
| 
							
							
								
									
								
								 | 
						25f4d7e588 | |
| 
							
							
								
									
								
								 | 
						1841edcbf3 | |
| 
							
							
								
									
								
								 | 
						957f60e797 | |
| 
							
							
								
									
								
								 | 
						6e5ede3958 | |
| 
							
							
								
									
								
								 | 
						2724683377 | |
| 
							
							
								
									
								
								 | 
						d89de67e44 | |
| 
							
							
								
									
								
								 | 
						3be05511e4 | |
| 
							
							
								
									
								
								 | 
						6fc0c24823 | |
| 
							
							
								
									
								
								 | 
						52b6af9fd0 | |
| 
							
							
								
									
								
								 | 
						d574ec5757 | |
| 
							
							
								
									
								
								 | 
						855cc61936 | |
| 
							
							
								
									
								
								 | 
						bcaed876f7 | |
| 
							
							
								
									
								
								 | 
						42966759b3 | |
| 
							
							
								
									
								
								 | 
						4a39747d3d | |
| 
							
							
								
									
								
								 | 
						d51759bbd1 | |
| 
							
							
								
									
								
								 | 
						68e90a4ed9 | |
| 
							
							
								
									
								
								 | 
						3d8bc1c642 | |
| 
							
							
								
									
								
								 | 
						338c886ef6 | |
| 
							
							
								
									
								
								 | 
						fa3ec5adef | 
| 
						 | 
					@ -18,3 +18,5 @@ GoodsSort,2PACX-1vQrg6Ss2bNYAI7A250t3_zp10UJtbbQXb8I4LtDJ2Q3uopUG_PUadoJy7T4w0jl
 | 
				
			||||||
CookingBlitz,2PACX-1vShqtSSpwYQ8CvK-BVr-wQ5ygGeKKLdpaaWysSN_QumoDZYATemayAQIOdnFRzMP69nEwFYSx51oey8
 | 
					CookingBlitz,2PACX-1vShqtSSpwYQ8CvK-BVr-wQ5ygGeKKLdpaaWysSN_QumoDZYATemayAQIOdnFRzMP69nEwFYSx51oey8
 | 
				
			||||||
WoodNuts,2PACX-1vQhtRg354eThBpWGCEk5f_2cLVbz1clQXv0n6w4Cyip0Knl6EQ4XwWMlcCec-legZdHU3E0-_cqKipc
 | 
					WoodNuts,2PACX-1vQhtRg354eThBpWGCEk5f_2cLVbz1clQXv0n6w4Cyip0Knl6EQ4XwWMlcCec-legZdHU3E0-_cqKipc
 | 
				
			||||||
MahjongSolitaire,2PACX-1vQpcaj8CpO__K1KGl-mg_940WOOIXBVzi0lmcjYTt1sqBI2PtK37s29McLTGU2I6N3fWM0ZepChedq7
 | 
					MahjongSolitaire,2PACX-1vQpcaj8CpO__K1KGl-mg_940WOOIXBVzi0lmcjYTt1sqBI2PtK37s29McLTGU2I6N3fWM0ZepChedq7
 | 
				
			||||||
 | 
					NutsSort,2PACX-1vShdEGGEeMp51fMhg0UnMRHA51xfP8OkCdaD3gu-GTZCcJ6NvveP9Q0ahWDwSi1HS4Okyabn3gnLoLU
 | 
				
			||||||
 | 
					FindMaster,2PACX-1vRXB42qVcqE0nhWxPScs_qtaUkkVz_BXmdMiEZm580VC4a3I6Av8MrhOEhixVzg2NcPhQh_8HIHt7wk
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					allprojects {
 | 
				
			||||||
 | 
					    buildscript {
 | 
				
			||||||
 | 
					        repositories {**ARTIFACTORYREPOSITORY**
 | 
				
			||||||
 | 
					            google()
 | 
				
			||||||
 | 
					            jcenter()
 | 
				
			||||||
 | 
					            mavenCentral()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        dependencies {
 | 
				
			||||||
 | 
					            // If you are changing the Android Gradle Plugin version, make sure it is compatible with the Gradle version preinstalled with Unity
 | 
				
			||||||
 | 
					            // See which Gradle version is preinstalled with Unity here https://docs.unity3d.com/Manual/android-gradle-overview.html
 | 
				
			||||||
 | 
					            // See official Gradle and Android Gradle Plugin compatibility table here https://developer.android.com/studio/releases/gradle-plugin#updating-gradle
 | 
				
			||||||
 | 
					            // To specify a custom Gradle version in Unity, go do "Preferences > External Tools", uncheck "Gradle Installed with Unity (recommended)" and specify a path to a custom Gradle version
 | 
				
			||||||
 | 
					//             classpath 'com.android.tools.build:gradle:4.0.1'
 | 
				
			||||||
 | 
					            classpath 'com.android.tools.build:gradle:7.4.2'
 | 
				
			||||||
 | 
					            **BUILD_SCRIPT_DEPS**
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    repositories {**ARTIFACTORYREPOSITORY**
 | 
				
			||||||
 | 
					        google()
 | 
				
			||||||
 | 
					        jcenter()
 | 
				
			||||||
 | 
					        flatDir {
 | 
				
			||||||
 | 
					            dirs "${project(':unityLibrary').projectDir}/libs"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					task clean(type: Delete) {
 | 
				
			||||||
 | 
					    delete rootProject.buildDir
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					fileFormatVersion: 2
 | 
				
			||||||
 | 
					guid: 210888b84fe449e88319129ae097514d
 | 
				
			||||||
 | 
					timeCreated: 1722245010
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@ org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M
 | 
				
			||||||
org.gradle.parallel=true
 | 
					org.gradle.parallel=true
 | 
				
			||||||
org.gradle.daemon=true
 | 
					org.gradle.daemon=true
 | 
				
			||||||
org.gradle.caching=true
 | 
					org.gradle.caching=true
 | 
				
			||||||
android.enableR8=**MINIFY_WITH_R_EIGHT**
 | 
					 | 
				
			||||||
unityStreamingAssets=**STREAMING_ASSETS**
 | 
					unityStreamingAssets=**STREAMING_ASSETS**
 | 
				
			||||||
# Android Resolver Properties Start
 | 
					# Android Resolver Properties Start
 | 
				
			||||||
android.useAndroidX=true
 | 
					android.useAndroidX=true
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,8 @@ dependencies {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
android {
 | 
					android {
 | 
				
			||||||
    compileSdkVersion **APIVERSION**
 | 
					    namespace "**NAMESPACE**"
 | 
				
			||||||
 | 
					    compileSdkVersion **TARGETSDKVERSION**
 | 
				
			||||||
    buildToolsVersion '**BUILDTOOLS**'
 | 
					    buildToolsVersion '**BUILDTOOLS**'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    compileOptions {
 | 
					    compileOptions {
 | 
				
			||||||
| 
						 | 
					@ -22,6 +23,7 @@ android {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        versionCode **VERSIONCODE**
 | 
					        versionCode **VERSIONCODE**
 | 
				
			||||||
        versionName '**VERSIONNAME**'
 | 
					        versionName '**VERSIONNAME**'
 | 
				
			||||||
 | 
					        multiDexEnabled true
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    aaptOptions {
 | 
					    aaptOptions {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					apply plugin: 'com.android.library'
 | 
				
			||||||
 | 
					**APPLY_PLUGINS**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dependencies {
 | 
				
			||||||
 | 
					    implementation fileTree(dir: 'libs', include: ['*.jar'])
 | 
				
			||||||
 | 
					**DEPS**}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					android {
 | 
				
			||||||
 | 
					    namespace "com.unity3d.player"
 | 
				
			||||||
 | 
					    ndkPath "**NDKPATH**"
 | 
				
			||||||
 | 
					    compileSdkVersion **APIVERSION**
 | 
				
			||||||
 | 
					    buildToolsVersion '**BUILDTOOLS**'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    compileOptions {
 | 
				
			||||||
 | 
					        sourceCompatibility JavaVersion.VERSION_11
 | 
				
			||||||
 | 
					        targetCompatibility JavaVersion.VERSION_11
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    defaultConfig {
 | 
				
			||||||
 | 
					        minSdkVersion **MINSDKVERSION**
 | 
				
			||||||
 | 
					        targetSdkVersion **TARGETSDKVERSION**
 | 
				
			||||||
 | 
					        ndk {
 | 
				
			||||||
 | 
					            abiFilters **ABIFILTERS**
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        versionCode **VERSIONCODE**
 | 
				
			||||||
 | 
					        versionName '**VERSIONNAME**'
 | 
				
			||||||
 | 
					        consumerProguardFiles 'proguard-unity.txt'**USER_PROGUARD**
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lintOptions {
 | 
				
			||||||
 | 
					        abortOnError false
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    aaptOptions {
 | 
				
			||||||
 | 
					        noCompress = **BUILTIN_NOCOMPRESS** + unityStreamingAssets.tokenize(', ')
 | 
				
			||||||
 | 
					        ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~"
 | 
				
			||||||
 | 
					    }**PACKAGING_OPTIONS**
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					**IL_CPP_BUILD_SETUP**
 | 
				
			||||||
 | 
					**SOURCE_BUILD_SETUP**
 | 
				
			||||||
 | 
					**EXTERNAL_SOURCES**
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,134 @@
 | 
				
			||||||
 | 
					-keep class com.unity3d.plugin.* { *; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#proguard-adjust.pro
 | 
				
			||||||
 | 
					-keep public class com.adjust.sdk.** { *; }
 | 
				
			||||||
 | 
					-keep class com.amazon.device.ads.** { *; } 
 | 
				
			||||||
 | 
					-keep class com.amazon.aps.** { *; } 
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient {
 | 
				
			||||||
 | 
					    com.google.android.gms.ads.identifier.AdvertisingIdClient$Info getAdvertisingIdInfo(android.content.Context);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient$Info {
 | 
				
			||||||
 | 
					    java.lang.String getId();
 | 
				
			||||||
 | 
					    boolean isLimitAdTrackingEnabled();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep public class com.android.installreferrer.** { *; }
 | 
				
			||||||
 | 
					-keepclassmembers class com.ironsource.sdk.controller.IronSourceWebView$JSInterface {
 | 
				
			||||||
 | 
					    public *;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keepclassmembers class * implements android.os.Parcelable {
 | 
				
			||||||
 | 
					    public static final android.os.Parcelable$Creator *;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep public class com.google.android.gms.ads.** {
 | 
				
			||||||
 | 
					    public *;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep class com.ironsource.adapters.** { *; }
 | 
				
			||||||
 | 
					-dontwarn com.ironsource.mediationsdk.**
 | 
				
			||||||
 | 
					-dontwarn com.ironsource.adapters.**
 | 
				
			||||||
 | 
					-keepattributes JavascriptInterface
 | 
				
			||||||
 | 
					-keepclassmembers class * {
 | 
				
			||||||
 | 
					    @android.webkit.JavascriptInterface <methods>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-keep class dalvik.system.VMRuntime {
 | 
				
			||||||
 | 
					    java.lang.String getRuntime();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep class android.os.Build {
 | 
				
			||||||
 | 
					    java.lang.String[] SUPPORTED_ABIS;
 | 
				
			||||||
 | 
					    java.lang.String CPU_ABI;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep class android.content.res.Configuration {
 | 
				
			||||||
 | 
					    android.os.LocaleList getLocales();
 | 
				
			||||||
 | 
					    java.util.Locale locale;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep class android.os.LocaledList {
 | 
				
			||||||
 | 
					    java.util.Locale get(int);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#proguard-facebook.pro
 | 
				
			||||||
 | 
					-keep class com.facebook.** { *; }
 | 
				
			||||||
 | 
					-keepattributes Signature
 | 
				
			||||||
 | 
					-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
 | 
				
			||||||
 | 
					-keep @com.facebook.common.internal.DoNotStrip class *
 | 
				
			||||||
 | 
					-keep class com.facebook.stetho.** { *; }
 | 
				
			||||||
 | 
					-keepclassmembers class * {
 | 
				
			||||||
 | 
					    @com.facebook.common.internal.DoNotStrip *;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keepclassmembers class * {
 | 
				
			||||||
 | 
					    native <methods>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-dontwarn okio.**
 | 
				
			||||||
 | 
					-dontwarn javax.annotation.**
 | 
				
			||||||
 | 
					-dontwarn com.android.volley.toolbox.**
 | 
				
			||||||
 | 
					-keep class com.google.firebase.** { *; }
 | 
				
			||||||
 | 
					-dontwarn com.google.firebase.**
 | 
				
			||||||
 | 
					-keep class com.bytedance.sdk.** { *; }
 | 
				
			||||||
 | 
					-keep class com.pgl.sys.ces.* { *; }
 | 
				
			||||||
 | 
					-keep class com.facebook.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.play.core.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.games.bridge.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.games.leaderboard.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.games.snapshot.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.games.achievement.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.games.event.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.games.stats.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.games.video.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.games.* { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.common.api.ResultCallback { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.signin.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.dynamic.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.dynamite.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.tasks.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.security.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.base.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.actions.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.common.ConnectionResult { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.common.GooglePlayServicesUtil { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.common.api.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.common.data.DataBufferUtils { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.games.quest.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.nearby.** { *; }
 | 
				
			||||||
 | 
					-keep class com.google.android.gms.ads.** { *; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-keep class com.pubmatic.sdk.** { *; }
 | 
				
			||||||
 | 
					-keep class com.applovin.** { *; }
 | 
				
			||||||
 | 
					-keep class com.chartboost.** { *; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-keep class com.guru.** { *; }
 | 
				
			||||||
 | 
					-keep class guru.core.** { *; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-keep class com.onevcat.uniwebview.* { *; }
 | 
				
			||||||
 | 
					-keep class com.iab.omid.* { *; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-keep public class com.tradplus.** { *; }
 | 
				
			||||||
 | 
					-keep class com.tradplus.ads.** { *; }
 | 
				
			||||||
 | 
					-keep class com.applovin.mediation.adapters.** { *; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-keep public class com.applovin.sdk.AppLovinSdk{ *; }
 | 
				
			||||||
 | 
					-keep public class com.applovin.sdk.AppLovin* {
 | 
				
			||||||
 | 
					    public protected *;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep public class com.applovin.nativeAds.AppLovin* {
 | 
				
			||||||
 | 
					    public protected *;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep public class com.applovin.adview.* {
 | 
				
			||||||
 | 
					    public protected *;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep public class com.applovin.mediation.* {
 | 
				
			||||||
 | 
					    public protected *;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep public class com.applovin.mediation.ads.* {
 | 
				
			||||||
 | 
					    public protected *;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep public class com.applovin.impl.*.AppLovin {
 | 
				
			||||||
 | 
					    public protected *;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep public class com.applovin.impl.**.*Impl {
 | 
				
			||||||
 | 
					    public protected *;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keepclassmembers class com.applovin.sdk.AppLovinSdkSettings {
 | 
				
			||||||
 | 
					    private java.util.Map localSettings;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					-keep class com.applovin.mediation.adapters.** { *; }
 | 
				
			||||||
 | 
					-keep class com.applovin.mediation.adapter.** { *; }
 | 
				
			||||||
 | 
					-keep class com.applovin.mediation.unity.** { *; }
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					fileFormatVersion: 2
 | 
				
			||||||
 | 
					guid: a08608d11bf7483fa4c49df80ebab657
 | 
				
			||||||
 | 
					timeCreated: 1722245439
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,60 @@
 | 
				
			||||||
 | 
					pluginManagement {
 | 
				
			||||||
 | 
					    repositories {
 | 
				
			||||||
 | 
					        **ARTIFACTORYREPOSITORY**
 | 
				
			||||||
 | 
					        gradlePluginPortal()
 | 
				
			||||||
 | 
					        google()
 | 
				
			||||||
 | 
					        mavenCentral()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include ':launcher', ':unityLibrary'
 | 
				
			||||||
 | 
					**INCLUDES**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dependencyResolutionManagement {
 | 
				
			||||||
 | 
					    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
 | 
				
			||||||
 | 
					    repositories {
 | 
				
			||||||
 | 
					        **ARTIFACTORYREPOSITORY**
 | 
				
			||||||
 | 
					        google()
 | 
				
			||||||
 | 
					        mavenCentral()
 | 
				
			||||||
 | 
					// Android Resolver Repos Start
 | 
				
			||||||
 | 
					        def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/")
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url "https://verve.jfrog.io/artifactory/verve-gradle-release" // Packages/com.guru.unity.max/Mediation/Verve/Editor/Dependencies.xml:7
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url (unityProjectPath + "/Assets/GeneratedLocalRepo/Firebase/m2repository") // Packages/com.google.firebase.firestore/Firebase/Editor/FirestoreDependencies.xml:20, Packages/com.google.firebase.app/Firebase/Editor/AppDependencies.xml:22, Packages/com.google.firebase.auth/Firebase/Editor/AuthDependencies.xml:20, Packages/com.google.firebase.messaging/Firebase/Editor/MessagingDependencies.xml:24, Packages/com.google.firebase.crashlytics/Firebase/Editor/CrashlyticsDependencies.xml:20, Packages/com.google.firebase.dynamic-links/Firebase/Editor/DynamicLinksDependencies.xml:20, Packages/com.google.firebase.installations/Firebase/Editor/InstallationsDependencies.xml:20, Packages/com.google.firebase.remote-config/Firebase/Editor/RemoteConfigDependencies.xml:20, Packages/com.google.firebase.analytics/Firebase/Editor/AnalyticsDependencies.xml:18
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url "https://aws.oss.sonatype.org/content/repositories/releases/" // Packages/com.guru.unity.max/Amazon/Scripts/Editor/AmazonDependencies.xml:10
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url "https://artifactory.bidmachine.io/bidmachine" // Packages/com.guru.unity.max/Mediation/BidMachine/Editor/Dependencies.xml:8
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url "https://artifact.bytedance.com/repository/pangle" // Packages/com.guru.unity.max/Mediation/ByteDance/Editor/Dependencies.xml:8
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url "https://cboost.jfrog.io/artifactory/chartboost-ads/" // Packages/com.guru.unity.max/Mediation/Chartboost/Editor/Dependencies.xml:8
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url "https://android-sdk.is.com/" // Packages/com.guru.unity.max/Mediation/IronSource/Editor/Dependencies.xml:8
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" // Packages/com.guru.unity.max/Mediation/Mintegral/Editor/Dependencies.xml:8
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url "https://maven.ogury.co" // Packages/com.guru.unity.max/Mediation/OguryPresage/Editor/Dependencies.xml:8
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url "https://s3.amazonaws.com/smaato-sdk-releases/" // Packages/com.guru.unity.max/Mediation/Smaato/Editor/Dependencies.xml:8
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        maven {
 | 
				
			||||||
 | 
					            url "https://repo.pubmatic.com/artifactory/public-repos" // Packages/com.guru.unity.max/OpenWrapSDK/Editor/OpenWrapSDKDependencies.xml:18, Packages/com.guru.unity.max/OpenWrapSDK/Mediation/AppLovinMAX/Editor/ALOpenWrapMediationDependencies.xml:7
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        mavenLocal()
 | 
				
			||||||
 | 
					// Android Resolver Repos End
 | 
				
			||||||
 | 
					        flatDir {
 | 
				
			||||||
 | 
					            dirs "${project(':unityLibrary').projectDir}/libs"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					fileFormatVersion: 2
 | 
				
			||||||
 | 
					guid: 4f7213bbbc8741bd89b3bd17a7bea43e
 | 
				
			||||||
 | 
					timeCreated: 1722240718
 | 
				
			||||||
| 
						 | 
					@ -10,27 +10,42 @@ namespace Guru.Editor
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    public class AndroidProjectMod
 | 
					    public class AndroidProjectMod
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private static readonly int TargetSDKVersion = 33;
 | 
					        private const int TargetSDKVersion = 34;
 | 
				
			||||||
 | 
					        private const string K_ANDROID_PLUGINS_NAME = "Plugins/Android";
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private static readonly string LauncherName = "launcherTemplate";
 | 
					        private const string LauncherName = "launcherTemplate";
 | 
				
			||||||
        private static string LauncherFullPath = Path.Combine(Application.dataPath, $"Plugins/Android/{LauncherName}.gradle");
 | 
					        private static readonly string LauncherFullPath = Path.Combine(Application.dataPath, $"{K_ANDROID_PLUGINS_NAME}/{LauncherName}.gradle");
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private static readonly string MainName = "mainTemplate";
 | 
					        private const string MainName = "mainTemplate";
 | 
				
			||||||
        private static string MainFullPath = Path.Combine(Application.dataPath,  $"Plugins/Android/{MainName}.gradle");
 | 
					        private static readonly string MainFullPath = Path.Combine(Application.dataPath,  $"{K_ANDROID_PLUGINS_NAME}/{MainName}.gradle");
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private static readonly string PropertiesName = "gradleTemplate";
 | 
					        private const string BaseProjectName = "baseProjectTemplate";
 | 
				
			||||||
        private static string PropertiesFullPath = Path.Combine(Application.dataPath,  $"Plugins/Android/{PropertiesName}.properties");
 | 
					        private static readonly string BaseProjectFullPath = Path.Combine(Application.dataPath,  $"{K_ANDROID_PLUGINS_NAME}/{BaseProjectName}.gradle");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        private const string PropertiesName = "gradleTemplate";
 | 
				
			||||||
 | 
					        private const string K_ENABLE_R8 = "android.enableR8";
 | 
				
			||||||
 | 
					        private static readonly string PropertiesFullPath = Path.Combine(Application.dataPath,  $"{K_ANDROID_PLUGINS_NAME}/{PropertiesName}.properties");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        private const string SettingsName = "settingsTemplate";
 | 
				
			||||||
 | 
					        private static readonly string SettingsFullPath = Path.Combine(Application.dataPath,  $"Plugins/Android/{SettingsName}.gradle");
 | 
				
			||||||
 | 
					        private const string K_LINE_UNITY_PROJECT = "def unityProjectPath";
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        private const string ProguardUserName = "proguard-user";
 | 
				
			||||||
 | 
					        private static readonly string ProguardUserFullPath = Path.Combine(Application.dataPath,  $"{K_ANDROID_PLUGINS_NAME}/{ProguardUserName}.txt");
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        public static void Apply()
 | 
					        public static void Apply()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            FixLauncher();
 | 
					            ApplyLauncher();
 | 
				
			||||||
            FixMain();
 | 
					            ApplyBaseProjectTemplates();
 | 
				
			||||||
            FixProperties();
 | 
					            ApplyMainTemplates();
 | 
				
			||||||
            CheckTargetSDKVersion();
 | 
					            ApplyGradleTemplate();
 | 
				
			||||||
 | 
					            ApplySettings();
 | 
				
			||||||
 | 
					            ApplyProguardUser();
 | 
				
			||||||
 | 
					            CheckTargetSDKVersion();  // 强制修复构建版本号
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        private static void ApplyLauncher()
 | 
				
			||||||
        private static void FixLauncher()
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!File.Exists(LauncherFullPath))
 | 
					            if (!File.Exists(LauncherFullPath))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -43,10 +58,9 @@ namespace Guru.Editor
 | 
				
			||||||
            var ptn2 = "abortOnError false";
 | 
					            var ptn2 = "abortOnError false";
 | 
				
			||||||
            var lines = File.ReadAllLines(LauncherFullPath);
 | 
					            var lines = File.ReadAllLines(LauncherFullPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            string line = "";
 | 
					 | 
				
			||||||
            for (int i = 0; i < lines.Length; i++)
 | 
					            for (int i = 0; i < lines.Length; i++)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                line = lines[i];
 | 
					                var line = lines[i];
 | 
				
			||||||
                if (line.Contains(ptn1))
 | 
					                if (line.Contains(ptn1))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    lines[i] = line.Replace(ptn1, "\n\n\tpackagingOptions {\n\t\texclude(\"META-INF/*.kotlin_module\")\n\t}\n\n");
 | 
					                    lines[i] = line.Replace(ptn1, "\n\n\tpackagingOptions {\n\t\texclude(\"META-INF/*.kotlin_module\")\n\t}\n\n");
 | 
				
			||||||
| 
						 | 
					@ -64,7 +78,7 @@ namespace Guru.Editor
 | 
				
			||||||
            File.WriteAllLines(LauncherFullPath, lines);
 | 
					            File.WriteAllLines(LauncherFullPath, lines);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        private static void FixMain()
 | 
					        private static void ApplyMainTemplates()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!File.Exists(MainFullPath))
 | 
					            if (!File.Exists(MainFullPath))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -72,13 +86,100 @@ namespace Guru.Editor
 | 
				
			||||||
                CopyFile($"{MainName}.txt", MainFullPath);
 | 
					                CopyFile($"{MainName}.txt", MainFullPath);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        private static void FixProperties()
 | 
					        
 | 
				
			||||||
 | 
					        private static void ApplyBaseProjectTemplates()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (!File.Exists(BaseProjectFullPath))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Debug.Log($"[MOD] --- Copy file to: {BaseProjectFullPath}");
 | 
				
			||||||
 | 
					                CopyFile($"{BaseProjectName}.txt", BaseProjectFullPath);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        private static void ApplyGradleTemplate()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!File.Exists(PropertiesFullPath))
 | 
					            if (!File.Exists(PropertiesFullPath))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Debug.Log($"[MOD] --- Copy file to: {PropertiesFullPath}");
 | 
					                Debug.Log($"[MOD] --- Copy file to: {PropertiesFullPath}");
 | 
				
			||||||
                CopyFile($"{PropertiesName}.txt", PropertiesFullPath);
 | 
					                CopyFile($"{PropertiesName}.txt", PropertiesFullPath);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (TargetSDKVersion > 33)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                FixGradleTemplate(PropertiesFullPath);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 该版本中不再使用 R8
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="filePath"></param>
 | 
				
			||||||
 | 
					        private static void FixGradleTemplate(string filePath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (File.Exists(filePath))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                bool isDirty = false;
 | 
				
			||||||
 | 
					                var lines = File.ReadAllLines(filePath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for (int i = 0; i < lines.Length; i++)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (lines[i].Contains(K_ENABLE_R8))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        lines[i] = $"# {lines[i]}"; // 禁用R8
 | 
				
			||||||
 | 
					                        isDirty = true;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (isDirty) File.WriteAllLines(filePath, lines);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 写入 settings.gradle 配置文件
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private static void ApplySettings()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (!File.Exists(SettingsFullPath))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CopyFile($"{SettingsName}.txt", SettingsFullPath);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            FixProjectPathInSettings(SettingsFullPath);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        private static void FixProjectPathInSettings(string settingsPath)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            bool isDirty = false;
 | 
				
			||||||
 | 
					            if (File.Exists(settingsPath))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                string projectPath = Path.GetFullPath($"{Application.dataPath}/../").Replace("\\", "/");
 | 
				
			||||||
 | 
					                var lines = File.ReadAllLines(settingsPath);
 | 
				
			||||||
 | 
					                for (int i = 0; i < lines.Length; i++)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (lines[i].Contains(K_LINE_UNITY_PROJECT))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        lines[i] = $"        def unityProjectPath = $/file:////{projectPath}/$.replace(\"\\\\\", \"/\")";
 | 
				
			||||||
 | 
					                        isDirty = true;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if(isDirty)
 | 
				
			||||||
 | 
					                    File.WriteAllLines(settingsPath, lines);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 写入所有的配置文件
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private static void ApplyProguardUser()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (!File.Exists(ProguardUserFullPath))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CopyFile($"{ProguardUserName}.txt", ProguardUserFullPath);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static void CheckTargetSDKVersion()
 | 
					        private static void CheckTargetSDKVersion()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -497,6 +497,7 @@ namespace Guru.Editor
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    ReadServiceConfig(); // Read file again
 | 
					                    ReadServiceConfig(); // Read file again
 | 
				
			||||||
                    CheckAllComponents();
 | 
					                    CheckAllComponents();
 | 
				
			||||||
 | 
					                    ExecuteAdditionalCommands();
 | 
				
			||||||
                }, null, GUILayout.Height(btnH));
 | 
					                }, null, GUILayout.Height(btnH));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
| 
						 | 
					@ -504,7 +505,14 @@ namespace Guru.Editor
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 执行其他的命令
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private void ExecuteAdditionalCommands()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // 部署 Adjust Signature V3
 | 
				
			||||||
 | 
					            DeployAdjustSignatureV3Files(); 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
| 
						 | 
					@ -1245,6 +1253,18 @@ namespace Guru.Editor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region OtherCommands
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 使用 Adjust 签名 V3 导入项目
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private void DeployAdjustSignatureV3Files()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            AdjustSignatureHelper.DeployFiles();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,8 @@
 | 
				
			||||||
        "Guru.LitJson",
 | 
					        "Guru.LitJson",
 | 
				
			||||||
        "Guru.Runtime",
 | 
					        "Guru.Runtime",
 | 
				
			||||||
        "MaxSdk.Scripts.IntegrationManager.Editor",
 | 
					        "MaxSdk.Scripts.IntegrationManager.Editor",
 | 
				
			||||||
        "Guru.Editor"
 | 
					        "Guru.Editor",
 | 
				
			||||||
 | 
					        "GuruAdjust.Editor"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "includePlatforms": [
 | 
					    "includePlatforms": [
 | 
				
			||||||
        "Editor"
 | 
					        "Editor"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,17 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Guru
 | 
					namespace Guru
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using System.Collections.Generic;
 | 
					    using System.Collections.Generic;
 | 
				
			||||||
    using System.Text;
 | 
					    using System.Text;
 | 
				
			||||||
 | 
					    using System;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
    /// 启动参数配置
 | 
					    /// 启动参数配置
 | 
				
			||||||
    /// </summary>
 | 
					    /// </summary>
 | 
				
			||||||
    public partial class GuruSDKInitConfig
 | 
					    public class GuruSDKInitConfig
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        #region Properties
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 使用自定义的ConsentFlow启动流程
 | 
					        /// 使用自定义的ConsentFlow启动流程
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
| 
						 | 
					@ -20,9 +25,14 @@ namespace Guru
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        public bool IAPEnabled = true;
 | 
					        public bool IAPEnabled = true;
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 自动申请推送授权信息
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public bool AutoNotificationPermission = true;
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
        /// 自动记录完成的关卡
 | 
					        /// 自动记录完成的关卡
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        public bool AutoRecordFinishedLevels = true;
 | 
					        [Obsolete("Will be removed from InitConfig in next version. Use the <b_level> and <b_play> data from the GameUserData from game itself instead!")]
 | 
				
			||||||
 | 
					        public bool AutoRecordFinishedLevels = false;
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 自定义 Service 云控 Key
 | 
					        /// 自定义 Service 云控 Key
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
| 
						 | 
					@ -30,7 +40,7 @@ namespace Guru
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Banner 背景颜色 Hex 值
 | 
					        /// Banner 背景颜色 Hex 值
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        public string BannerBackgroundColor = "#00000000";
 | 
					        public string BannerBackgroundColor = "#00000040";
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 已购买去广告道具
 | 
					        /// 已购买去广告道具
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
| 
						 | 
					@ -40,10 +50,31 @@ namespace Guru
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        public bool DebugMode = false;
 | 
					        public bool DebugMode = false;
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Debug模式下开启打点(默认关闭)
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public bool EnableDebugLogEvent = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private Dictionary<string, object> _defaultRemoteData = new Dictionary<string, object>();
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
        /// 云控参数的默认配置
 | 
					        /// 云控参数的默认配置
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <returns></returns>
 | 
					        /// <returns></returns>
 | 
				
			||||||
        public Dictionary<string, object> DefaultRemoteData = new Dictionary<string, object>();
 | 
					        public Dictionary<string, object> DefaultRemoteData
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            set
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (value != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _defaultRemoteData = value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            get => _defaultRemoteData;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 启用 AdjustDeeplink
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public Action<string> OnAdjustDeeplinkCallback = null;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 支付初始化Keys
 | 
					        /// 支付初始化Keys
 | 
				
			||||||
| 
						 | 
					@ -51,45 +82,6 @@ namespace Guru
 | 
				
			||||||
        public byte[] GoogleKeys;       // 数据取自 GooglePlayTangle.Data();
 | 
					        public byte[] GoogleKeys;       // 数据取自 GooglePlayTangle.Data();
 | 
				
			||||||
        public byte[] AppleRootCerts;   // 数据取自 AppleTangle.Data();
 | 
					        public byte[] AppleRootCerts;   // 数据取自 AppleTangle.Data();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #region Initialization
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// 构建启动配置
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <returns></returns>
 | 
					 | 
				
			||||||
        public static GuruSDKInitConfig Build(
 | 
					 | 
				
			||||||
            bool useCustomConsent = false, 
 | 
					 | 
				
			||||||
            bool autoLoadAds = true, 
 | 
					 | 
				
			||||||
            bool iapEnabled = true, 
 | 
					 | 
				
			||||||
            bool autoRecordFinishedLevels = true, 
 | 
					 | 
				
			||||||
            bool isBuyNoAds = false,
 | 
					 | 
				
			||||||
            string bannerBackgroundColor = "#00000000",
 | 
					 | 
				
			||||||
            bool debugMode = false,
 | 
					 | 
				
			||||||
            Dictionary<string, object> defaultRemoteData = null,
 | 
					 | 
				
			||||||
            byte[] googleKeys = null,
 | 
					 | 
				
			||||||
            byte[] appleRootCerts = null)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // 创建启动用参数
 | 
					 | 
				
			||||||
            GuruSDKInitConfig config = new GuruSDKInitConfig()
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                UseCustomConsent = useCustomConsent,
 | 
					 | 
				
			||||||
                AutoLoadWhenAdsReady = autoLoadAds,
 | 
					 | 
				
			||||||
                IAPEnabled = iapEnabled,
 | 
					 | 
				
			||||||
                AutoRecordFinishedLevels = autoRecordFinishedLevels,
 | 
					 | 
				
			||||||
                IsBuyNoAds = isBuyNoAds,
 | 
					 | 
				
			||||||
                BannerBackgroundColor = bannerBackgroundColor,
 | 
					 | 
				
			||||||
                DebugMode = debugMode,
 | 
					 | 
				
			||||||
                GoogleKeys = googleKeys,
 | 
					 | 
				
			||||||
                AppleRootCerts = appleRootCerts,
 | 
					 | 
				
			||||||
                DefaultRemoteData = defaultRemoteData ?? new Dictionary<string, object>(),
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
#if UNITY_EDITOR
 | 
					 | 
				
			||||||
            config.DebugMode = true;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            return config;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #region Print
 | 
					        #region Print
 | 
				
			||||||
| 
						 | 
					@ -97,17 +89,125 @@ namespace Guru
 | 
				
			||||||
        public override string ToString()
 | 
					        public override string ToString()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            StringBuilder sb = new StringBuilder();
 | 
					            StringBuilder sb = new StringBuilder();
 | 
				
			||||||
            sb.AppendLine($"------- Custom init Config -------");
 | 
					            sb.AppendLine($"------- Custom InitConfig -------");
 | 
				
			||||||
            sb.AppendLine($"\tUseCustomConsent: {UseCustomConsent}");
 | 
					            sb.AppendLine($"\t  UseCustomConsent: {UseCustomConsent}");
 | 
				
			||||||
            sb.AppendLine($"\tAutoLoadWhenAdsReady: {AutoLoadWhenAdsReady}");
 | 
					            sb.AppendLine($"\t  AutoLoadWhenAdsReady: {AutoLoadWhenAdsReady}");
 | 
				
			||||||
            sb.AppendLine($"\tIAPEnabled: {IAPEnabled}");
 | 
					            sb.AppendLine($"\t  IAPEnabled: {IAPEnabled}");
 | 
				
			||||||
            sb.AppendLine($"\tShowDebugLog: {DebugMode}");
 | 
					            sb.AppendLine($"\t  AutoNotificationPermission: {AutoNotificationPermission}");
 | 
				
			||||||
            sb.AppendLine($"------- Custom init Config -------");
 | 
					            sb.AppendLine($"\t  AutoRecordFinishedLevels: {AutoRecordFinishedLevels}");
 | 
				
			||||||
 | 
					            sb.AppendLine($"\t  CustomServiceKey: {CustomServiceKey}");
 | 
				
			||||||
 | 
					            sb.AppendLine($"\t  BannerBackgroundColor: {BannerBackgroundColor}");
 | 
				
			||||||
 | 
					            sb.AppendLine($"\t  IsBuyNoAds: {IsBuyNoAds}");
 | 
				
			||||||
 | 
					            sb.AppendLine($"\t  DebugMode: {DebugMode}");
 | 
				
			||||||
 | 
					            sb.AppendLine($"\t  DefaultRemote: Count: {DefaultRemoteData.Count}");
 | 
				
			||||||
 | 
					            sb.AppendLine($"------- Custom InitConfig -------");
 | 
				
			||||||
            return sb.ToString();
 | 
					            return sb.ToString();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region Builder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 构造器
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        public static GuruSDKInitConfigBuilder Builder() => new GuruSDKInitConfigBuilder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// 构建器
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    public class GuruSDKInitConfigBuilder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private GuruSDKInitConfig _config = new GuruSDKInitConfig();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 构建配置
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        public GuruSDKInitConfig Build()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _config;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetUseCustomConsent(bool value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.UseCustomConsent = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetAutoLoadWhenAdsReady(bool value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.AutoLoadWhenAdsReady = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetIAPEnabled(bool value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.IAPEnabled = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetAutoRecordFinishedLevels(bool value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.AutoRecordFinishedLevels = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetIsBuyNoAds(bool value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.IsBuyNoAds = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetBannerBackgroundColor(string value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.BannerBackgroundColor = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetDebugMode(bool value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.DebugMode = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetOnAdjustDeeplinkCallback(Action<string> callback)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.OnAdjustDeeplinkCallback = callback;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetGoogleKeys(byte[] value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.GoogleKeys = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetAppleRootCerts(byte[]  value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.AppleRootCerts = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetDefaultRemoteData(Dictionary<string, object> value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.DefaultRemoteData = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetEnableDebugLogEvent(bool value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.EnableDebugLogEvent = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetCustomServiceKey(string value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.CustomServiceKey = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        public GuruSDKInitConfigBuilder SetAutoNotificationPermission(bool value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _config.AutoNotificationPermission = value;
 | 
				
			||||||
 | 
					            return this;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,9 @@
 | 
				
			||||||
using System;
 | 
					
 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Guru
 | 
					namespace Guru
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    using System;
 | 
				
			||||||
 | 
					    using UnityEngine.Serialization;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    [Serializable]
 | 
					    [Serializable]
 | 
				
			||||||
    public class GuruServicesConfig
 | 
					    public class GuruServicesConfig
 | 
				
			||||||
| 
						 | 
					@ -61,7 +62,7 @@ namespace Guru
 | 
				
			||||||
        public string DMAMapRule() => parameters?.dma_map_rule ?? "";
 | 
					        public string DMAMapRule() => parameters?.dma_map_rule ?? "";
 | 
				
			||||||
        public bool UseUUID() => parameters?.using_uuid ?? false;
 | 
					        public bool UseUUID() => parameters?.using_uuid ?? false;
 | 
				
			||||||
        public bool KeywordsEnabled() => parameters?.enable_keywords ?? false; 
 | 
					        public bool KeywordsEnabled() => parameters?.enable_keywords ?? false; 
 | 
				
			||||||
        public int TokenValidTime() => parameters?.token_vaild_time ?? 604800;
 | 
					        public int TokenValidTime() => parameters?.token_valid_time ?? 604800;
 | 
				
			||||||
        public int LevelEndSuccessNum() => parameters?.level_end_success_num ?? 50;
 | 
					        public int LevelEndSuccessNum() => parameters?.level_end_success_num ?? 50;
 | 
				
			||||||
        public string CdnHost() => parameters?.cdn_host ?? "";
 | 
					        public string CdnHost() => parameters?.cdn_host ?? "";
 | 
				
			||||||
        public bool UsingUUID() => parameters?.using_uuid ?? true;
 | 
					        public bool UsingUUID() => parameters?.using_uuid ?? true;
 | 
				
			||||||
| 
						 | 
					@ -91,7 +92,7 @@ namespace Guru
 | 
				
			||||||
    [Serializable]
 | 
					    [Serializable]
 | 
				
			||||||
    public class GuruParameters
 | 
					    public class GuruParameters
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public int token_vaild_time = 604800;
 | 
					        public int token_valid_time = 604800;
 | 
				
			||||||
        public int level_end_success_num = 50;
 | 
					        public int level_end_success_num = 50;
 | 
				
			||||||
        public bool enable_keywords = false;
 | 
					        public bool enable_keywords = false;
 | 
				
			||||||
        public double tch_020 = 0;
 | 
					        public double tch_020 = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,14 +7,17 @@ namespace Guru
 | 
				
			||||||
        /// 获取BLevel
 | 
					        /// 获取BLevel
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <returns></returns>
 | 
					        /// <returns></returns>
 | 
				
			||||||
        protected override int GetBLevel() => GuruSDKModel.Instance.SuccessLevelId; // BLevel
 | 
					        protected override int GetBLevel() => Model.BLevel; // BLevel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private GuruSDKModel Model => GuruSDKModel.Instance;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        protected override void OnPurchaseOver(bool success, string productName)
 | 
					        protected override void OnPurchaseOver(bool success, string productName)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (success)
 | 
					        }
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					        public void ClearData()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _model.ClearData();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -12,27 +12,17 @@ namespace Guru
 | 
				
			||||||
            get => _value;
 | 
					            get => _value;
 | 
				
			||||||
            set
 | 
					            set
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
					                if (_value.Equals(value)) return;
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                _value = value;
 | 
					                _value = value;
 | 
				
			||||||
                OnValueChanged?.Invoke(value);
 | 
					                OnValueChanged?.Invoke(value);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public event Action<T> OnValueChanged;
 | 
					        public event Action<T> OnValueChanged;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					        public BindableProperty(T initValue)
 | 
				
			||||||
        public BindableProperty() 
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public BindableProperty(Action<T> onChanged)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            OnValueChanged = onChanged;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public BindableProperty(T initValue, Action<T> onChanged)
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _value = initValue;
 | 
					            _value = initValue;
 | 
				
			||||||
            OnValueChanged = onChanged;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,3 @@
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Guru
 | 
					namespace Guru
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using System;
 | 
					    using System;
 | 
				
			||||||
| 
						 | 
					@ -8,11 +5,42 @@ namespace Guru
 | 
				
			||||||
    using System.Collections.Generic;
 | 
					    using System.Collections.Generic;
 | 
				
			||||||
    using System.Linq;
 | 
					    using System.Linq;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    [Serializable]
 | 
				
			||||||
 | 
					    class PurchasedProduct
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public string productName;
 | 
				
			||||||
 | 
					        public string productId;
 | 
				
			||||||
 | 
					        public string receipt;
 | 
				
			||||||
 | 
					        public bool appleProductIsRestored;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Serializable]
 | 
				
			||||||
 | 
					    class GuruSDKSerializedModel
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        //-------------- data ---------------
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public string uid = "";
 | 
				
			||||||
 | 
					        public int b_level = 0;
 | 
				
			||||||
 | 
					        public int b_play = 0;
 | 
				
			||||||
 | 
					        public bool no_ads = false;
 | 
				
			||||||
 | 
					        public List<PurchasedProduct> purchased = new List<PurchasedProduct>(10);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        //-------------- data ---------------
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    [Serializable]
 | 
					    [Serializable]
 | 
				
			||||||
    internal class GuruSDKModel
 | 
					    internal class GuruSDKModel
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private const float SaveInterval = 3;
 | 
					        private const float SaveInterval = 3;
 | 
				
			||||||
        private const string SaveKey = "com.guru.sdk.model.save";
 | 
					        private const string SaveKey = "com.guru.sdk.model.save";
 | 
				
			||||||
 | 
					        private DateTime _lastSavedTime = new DateTime(1970,1,1);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        private bool _noAds = false;
 | 
				
			||||||
 | 
					        private int _bLevel;
 | 
				
			||||||
 | 
					        private int _bPlay;
 | 
				
			||||||
 | 
					        private string _uid;
 | 
				
			||||||
 | 
					        private List<PurchasedProduct> _purchased;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private static GuruSDKModel _instance;
 | 
					        private static GuruSDKModel _instance;
 | 
				
			||||||
| 
						 | 
					@ -20,111 +48,77 @@ namespace Guru
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            get
 | 
					            get
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (null == _instance) _instance = Load();
 | 
					                if (null == _instance) _instance = new GuruSDKModel();
 | 
				
			||||||
                return _instance;
 | 
					                return _instance;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //-------------- data ---------------
 | 
					        public GuruSDKModel()
 | 
				
			||||||
        public string uid = "";
 | 
					 | 
				
			||||||
        public int b_level = 0;
 | 
					 | 
				
			||||||
        public int b_play = 0;
 | 
					 | 
				
			||||||
        public int buy_count = 0;
 | 
					 | 
				
			||||||
        public bool no_ads = false;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public List<PurchasedProduct> purchased;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public Dictionary<string, int> event_priorities;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        //-------------- data ---------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private float _lastSavedTime = 0;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public int SuccessLevelId
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            get
 | 
					            // 读取内存值
 | 
				
			||||||
            {
 | 
					            GuruSDKSerializedModel model = LoadModel();
 | 
				
			||||||
                if(_successLevel == null) InitProperties();
 | 
					            _uid = model.uid;
 | 
				
			||||||
                return _successLevel.Value;
 | 
					            _noAds = model.no_ads;
 | 
				
			||||||
            }
 | 
					            _bLevel = model.b_level;
 | 
				
			||||||
 | 
					            _bPlay = model.b_play;
 | 
				
			||||||
 | 
					            _purchased = model.purchased;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public int BLevel
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get => _bLevel;
 | 
				
			||||||
            set
 | 
					            set
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if(_successLevel == null) InitProperties();
 | 
					                if (value < _bLevel)
 | 
				
			||||||
                _successLevel.Value = value;
 | 
					                {
 | 
				
			||||||
 | 
					                    // b_level 必须比上一次的值大
 | 
				
			||||||
 | 
					                    Debug.LogWarning($"[SDK] :: Set b_level [{value}] should not be less than original value [{_bLevel}]");
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                _bLevel = value;
 | 
				
			||||||
 | 
					                Save();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public int TotalPlayedCount
 | 
					        public int BPlay
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            get
 | 
					            get => _bPlay;
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if(_totalPlayed == null) InitProperties();
 | 
					 | 
				
			||||||
                return _totalPlayed.Value;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            set
 | 
					            set
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if(_totalPlayed == null) InitProperties();
 | 
					                _bPlay = value;
 | 
				
			||||||
                _totalPlayed.Value = value;
 | 
					                Save();
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public int PurchasedCount
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            get
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if(_purchasedCount == null) InitProperties();
 | 
					 | 
				
			||||||
                return _purchasedCount.Value;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            set
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if(_purchasedCount == null) InitProperties();
 | 
					 | 
				
			||||||
                _purchasedCount.Value = value;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string UserId
 | 
					        public string UserId
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            get
 | 
					            get => _uid;
 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if(_uid == null) InitProperties();
 | 
					 | 
				
			||||||
                return _uid.Value;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            set
 | 
					            set
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if(_uid == null) InitProperties();
 | 
					                _uid = value;
 | 
				
			||||||
                _uid.Value = value;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public bool IsIapUser => PurchasedCount > 0;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public bool IsNoAds
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            get => no_ads;
 | 
					 | 
				
			||||||
            set
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                no_ads = value;
 | 
					 | 
				
			||||||
                Save();
 | 
					                Save();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private BindableProperty<int> _successLevel;
 | 
					 | 
				
			||||||
        private BindableProperty<int> _totalPlayed;
 | 
					 | 
				
			||||||
        private BindableProperty<int> _purchasedCount;
 | 
					 | 
				
			||||||
        private BindableProperty<string> _uid;
 | 
					 | 
				
			||||||
        private BindableProperty<bool> _isIapUser;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public BindableProperty<int> PropBLevel => _successLevel;
 | 
					        public bool IsIapUser => _purchased.Count > 0;
 | 
				
			||||||
        public BindableProperty<int> PropBPlay => _totalPlayed;
 | 
					        
 | 
				
			||||||
        public BindableProperty<int> PropBuyCount => _purchasedCount;
 | 
					        public bool IsNoAds
 | 
				
			||||||
        public BindableProperty<string> Uid => _uid;
 | 
					        {
 | 
				
			||||||
 | 
					            get => _noAds;
 | 
				
			||||||
 | 
					            set
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _noAds = value;
 | 
				
			||||||
 | 
					                Save();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #region 初始化
 | 
					        #region 初始化
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static GuruSDKModel Load()
 | 
					        private GuruSDKSerializedModel LoadModel()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            GuruSDKModel model = null;
 | 
					            GuruSDKSerializedModel model = null;
 | 
				
			||||||
            if (PlayerPrefs.HasKey(SaveKey))
 | 
					            if (PlayerPrefs.HasKey(SaveKey))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var json = PlayerPrefs.GetString(SaveKey, "");
 | 
					                var json = PlayerPrefs.GetString(SaveKey, "");
 | 
				
			||||||
| 
						 | 
					@ -132,113 +126,62 @@ namespace Guru
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    try
 | 
					                    try
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        model =  JsonUtility.FromJson<GuruSDKModel>(json);
 | 
					                        model =  JsonUtility.FromJson<GuruSDKSerializedModel>(json);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    catch (Exception e)
 | 
					                    catch (Exception e)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        UnityEngine.Debug.LogError(e);
 | 
					                        Debug.LogError(e);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if(model == null) model = new GuruSDKModel();
 | 
					            if(model == null) model = new GuruSDKSerializedModel();
 | 
				
			||||||
            model.InitProperties();
 | 
					 | 
				
			||||||
            return model;
 | 
					            return model;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 保存至数据
 | 
					        /// 保存至 PlayerPrefs 数据
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        private void SaveToPlayerPrefs()
 | 
					        private void SetToMemory()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var json = JsonUtility.ToJson(this);
 | 
					            var model = new GuruSDKSerializedModel()
 | 
				
			||||||
            PlayerPrefs.SetString(SaveKey, json);
 | 
					            {
 | 
				
			||||||
        }
 | 
					                uid = _uid,
 | 
				
			||||||
 | 
					                b_level = _bLevel,
 | 
				
			||||||
 | 
					                b_play = _bPlay,
 | 
				
			||||||
 | 
					                no_ads = _noAds,
 | 
				
			||||||
 | 
					                purchased = _purchased,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        public void InitProperties()
 | 
					            var json = JsonUtility.ToJson(model);
 | 
				
			||||||
        {
 | 
					            if (!string.IsNullOrEmpty(json))
 | 
				
			||||||
            if (_successLevel == null) _successLevel = new BindableProperty<int>(b_level, OnLevelChanged);
 | 
					            {
 | 
				
			||||||
            if (_totalPlayed == null) _totalPlayed = new BindableProperty<int>(b_play, OnPlayedChanged);
 | 
					                PlayerPrefs.SetString(SaveKey, json);
 | 
				
			||||||
            if (_purchasedCount == null) _purchasedCount = new BindableProperty<int>(buy_count, OnPurchasedNumChanged);
 | 
					            }
 | 
				
			||||||
            if (_uid == null) _uid = new BindableProperty<string>(uid, OnUidChanged);
 | 
					 | 
				
			||||||
            if (purchased == null) purchased = new List<PurchasedProduct>(20);
 | 
					 | 
				
			||||||
            if (event_priorities == null) event_priorities = new Dictionary<string, int>(10);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 保存数据
 | 
					        /// 保存数据
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="force"></param>
 | 
					        /// <param name="forceSave"></param>
 | 
				
			||||||
        public void Save(bool force = false)
 | 
					        public void Save(bool forceSave = false)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            bool save = force || (Time.realtimeSinceStartup - _lastSavedTime>= SaveInterval);
 | 
					            SetToMemory(); // 每次保存都要设置到 PlayerPrefs 内
 | 
				
			||||||
            if (save)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                _lastSavedTime = Time.realtimeSinceStartup;
 | 
					 | 
				
			||||||
                SaveToPlayerPrefs();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal void SetBLevelValue(int value) => OnLevelChanged(value);
 | 
					            bool shouldWriteToDisk = forceSave || (DateTime.Now - _lastSavedTime)>= TimeSpan.FromSeconds(SaveInterval);
 | 
				
			||||||
        internal void SetBPlayValue(int value) => OnPlayedChanged(value);
 | 
					            if (!shouldWriteToDisk) return;
 | 
				
			||||||
 | 
					            _lastSavedTime = DateTime.Now; // 更新最后保存时间
 | 
				
			||||||
 | 
					            PlayerPrefs.Save(); // 写入到磁盘
 | 
				
			||||||
        #endregion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #region 数据绑定变化
 | 
					 | 
				
			||||||
        private void OnLevelChanged(int value)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            b_level = value;
 | 
					 | 
				
			||||||
            Save();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        private void OnPlayedChanged(int value)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            b_play = value;
 | 
					 | 
				
			||||||
            Save();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private void OnPurchasedNumChanged(int value)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            buy_count = value;
 | 
					 | 
				
			||||||
            Save();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        private void OnUidChanged(string value)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            uid = value;
 | 
					 | 
				
			||||||
            Save();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #region 启动配置
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// 从 Streaming 加载 AppServices 配置
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <returns></returns>
 | 
					 | 
				
			||||||
        public string LoadDefaltServicesConfigJson()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            try
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                var txt = Resources.Load<TextAsset>(GuruSDK.ServicesConfigKey);
 | 
					 | 
				
			||||||
                return txt?.text ?? "";
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            catch (Exception e)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Log.Exception(e);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return "";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #endregion
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #region 订单记录
 | 
					        #region 订单记录
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					 | 
				
			||||||
        public bool HasPurchasedProduct(string receipt)
 | 
					        public bool HasPurchasedProduct(string receipt)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if(purchased == null || purchased.Count == 0) return false;
 | 
					            if(_purchased.Count == 0) return false;
 | 
				
			||||||
            return purchased.Exists(p => p.receipt == receipt);
 | 
					            return _purchased.Exists(p => p.receipt == receipt);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -247,12 +190,12 @@ namespace Guru
 | 
				
			||||||
        /// <param name="receipt"></param>
 | 
					        /// <param name="receipt"></param>
 | 
				
			||||||
        /// <param name="productName"></param>
 | 
					        /// <param name="productName"></param>
 | 
				
			||||||
        /// <param name="productId"></param>
 | 
					        /// <param name="productId"></param>
 | 
				
			||||||
 | 
					        /// <param name="appleProductIsRestored"></param>
 | 
				
			||||||
        public void AddReceipt(string receipt, string productName, string productId, bool appleProductIsRestored = false)
 | 
					        public void AddReceipt(string receipt, string productName, string productId, bool appleProductIsRestored = false)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (purchased == null) purchased = new List<PurchasedProduct>(20);
 | 
					 | 
				
			||||||
            if (!HasPurchasedProduct(receipt))
 | 
					            if (!HasPurchasedProduct(receipt))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                purchased.Add(new PurchasedProduct()
 | 
					                _purchased.Add(new PurchasedProduct()
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    receipt = receipt,
 | 
					                    receipt = receipt,
 | 
				
			||||||
                    productName = productName,
 | 
					                    productName = productName,
 | 
				
			||||||
| 
						 | 
					@ -265,22 +208,16 @@ namespace Guru
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string[] GetReceipts(string productName)
 | 
					        public string[] GetReceipts(string productName)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int count = purchased?.Count ?? 0;
 | 
					            var receipts = new List<string>();
 | 
				
			||||||
            if (count == 0) count = 20;
 | 
					            receipts.AddRange(from purchasedProduct in _purchased where purchasedProduct.productName == productName select purchasedProduct.receipt);
 | 
				
			||||||
            if (purchased == null) purchased = new List<PurchasedProduct>(count);
 | 
					 | 
				
			||||||
            var receipts = new List<string>(count);
 | 
					 | 
				
			||||||
            receipts.AddRange(from purchasedProduct in purchased where purchasedProduct.productName == productName select purchasedProduct.receipt);
 | 
					 | 
				
			||||||
            return receipts.ToArray();
 | 
					            return receipts.ToArray();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string[] GetReceiptsById(string productId)
 | 
					        public string[] GetReceiptsById(string productId)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int count = purchased?.Count ?? 0;
 | 
					            var receipts = new List<string>();
 | 
				
			||||||
            if (count == 0) count = 20;
 | 
					            receipts.AddRange(from purchasedProduct in _purchased where purchasedProduct.productId == productId select purchasedProduct.receipt);
 | 
				
			||||||
            if (purchased  == null) purchased = new List<PurchasedProduct>(count);
 | 
					 | 
				
			||||||
            var receipts = new List<string>(count);
 | 
					 | 
				
			||||||
            receipts.AddRange(from purchasedProduct in purchased where purchasedProduct.productId == productId select purchasedProduct.receipt);
 | 
					 | 
				
			||||||
            return receipts.ToArray();
 | 
					            return receipts.ToArray();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					@ -288,16 +225,17 @@ namespace Guru
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region 清除数据
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void ClearData()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            PlayerPrefs.DeleteKey(SaveKey);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Serializable]
 | 
					 | 
				
			||||||
    internal class PurchasedProduct
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public string productName;
 | 
					 | 
				
			||||||
        public string productId;
 | 
					 | 
				
			||||||
        public string receipt;
 | 
					 | 
				
			||||||
        public bool appleProductIsRestored;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,14 +1,13 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Guru
 | 
					namespace Guru
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using UnityEngine;
 | 
					    using UnityEngine;
 | 
				
			||||||
    using System;
 | 
					    using System;
 | 
				
			||||||
    
 | 
					    using Guru.Notification;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    public partial class GuruSDK
 | 
					    public partial class GuruSDK
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        
 | 
					        private const float CONSENT_FLOW_TIMEOUT = 10; // Consent Flow 超时时间(秒)   
 | 
				
			||||||
        private static AdsInitSpec _adInitSpec;
 | 
					        private static AdsInitSpec _adInitSpec;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -19,7 +18,7 @@ namespace Guru
 | 
				
			||||||
            _adInitSpec = spec;
 | 
					            _adInitSpec = spec;
 | 
				
			||||||
            if (InitConfig.UseCustomConsent)
 | 
					            if (InitConfig.UseCustomConsent)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UnityEngine.Debug.Log($"{Tag} --- Call <color=orange>StartAdsWithCustomConsent</color> when you use custom consent, and pass the result (boolean) to the method.");
 | 
					                Debug.Log($"{Tag} --- Call <color=orange>StartAdsWithCustomConsent</color> when you use custom consent, and pass the result (boolean) to the method.");
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
| 
						 | 
					@ -53,14 +52,14 @@ namespace Guru
 | 
				
			||||||
            if (userAllow)
 | 
					            if (userAllow)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
#if UNITY_IOS
 | 
					#if UNITY_IOS
 | 
				
			||||||
                CheckAttStatus();
 | 
					                Instance.CheckAttStatus();
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
                StartAdService(spec);
 | 
					                StartAdService(spec);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UnityEngine.Debug.Log($"{Tag} --- User refuse to provide ads Id, Ads Service will be cancelled");
 | 
					                Debug.Log($"{Tag} --- User refuse to provide ads Id, Ads Service will be cancelled");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,6 +80,8 @@ namespace Guru
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private bool _hasConsentCalled = false;
 | 
					        private bool _hasConsentCalled = false;
 | 
				
			||||||
        private bool _adServiceHasStarted = false;
 | 
					        private bool _adServiceHasStarted = false;
 | 
				
			||||||
 | 
					        private string _notiStatue = "";
 | 
				
			||||||
 | 
					        private bool _hasNotiGranted = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 启动Consent流程
 | 
					        /// 启动Consent流程
 | 
				
			||||||
| 
						 | 
					@ -88,10 +89,12 @@ namespace Guru
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        private void StartConsentFlow()
 | 
					        private void StartConsentFlow()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            LogI($"#4.5 ---  StartConsentFlow ---");
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            float time = 1;
 | 
					            float time = 1;
 | 
				
			||||||
            if (!_adServiceHasStarted && _appServicesConfig != null)
 | 
					            if (!_adServiceHasStarted && _appServicesConfig != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                time = _appServicesConfig.IsAdsCompliance() ? 10 : 1f; // 启动合规判定后, 延迟最多 10 秒后启动广告
 | 
					                time = _appServicesConfig.IsAdsCompliance() ? CONSENT_FLOW_TIMEOUT : 1f; // 启动合规判定后, 延迟最多 10 秒后启动广告
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Delay(time, AdServiceHandler); // 广告延迟启动
 | 
					            Delay(time, AdServiceHandler); // 广告延迟启动
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
| 
						 | 
					@ -125,12 +128,12 @@ namespace Guru
 | 
				
			||||||
            AdServiceHandler();
 | 
					            AdServiceHandler();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // 调用回调
 | 
					            // 调用回调
 | 
				
			||||||
            Callbacks.ConsentFlow._onConsentResult?.Invoke(code);
 | 
					            Callbacks.ConsentFlow.InvokeOnConsentResult(code);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
#if UNITY_IOS
 | 
					#if UNITY_IOS
 | 
				
			||||||
            CheckAttStatus();  // [iOS] Consent 启动后检查 ATT 初始值
 | 
					            CheckAttStatus();  // [iOS] Consent 启动后检查 ATT 初始值
 | 
				
			||||||
#elif UNITY_ANDROID
 | 
					#elif UNITY_ANDROID
 | 
				
			||||||
            CheckPermission(); // [Android] Consent 回调后检查 Push 推送权限
 | 
					            CheckNotiPermission(); // Consent 回调后检查 Notification 权限
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // 内部处理后继逻辑
 | 
					            // 内部处理后继逻辑
 | 
				
			||||||
| 
						 | 
					@ -154,6 +157,8 @@ namespace Guru
 | 
				
			||||||
            StartAdService(_adInitSpec);
 | 
					            StartAdService(_adInitSpec);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #region IOS ATT 广告授权流程
 | 
					        #region IOS ATT 广告授权流程
 | 
				
			||||||
| 
						 | 
					@ -167,7 +172,7 @@ namespace Guru
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 显示系统的 ATT 弹窗
 | 
					        /// 显示系统的 ATT 弹窗
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        public static void RequestAttDialog()
 | 
					        public void RequestAttDialog()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogI($"RequestATTDialog");
 | 
					            LogI($"RequestATTDialog");
 | 
				
			||||||
            ATTManager.RequestATTDailog(ReportAttStatus);
 | 
					            ATTManager.RequestATTDailog(ReportAttStatus);
 | 
				
			||||||
| 
						 | 
					@ -180,13 +185,13 @@ namespace Guru
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _attType = InitConfig.UseCustomConsent ? ATTManager.GUIDE_TYPE_CUSTOM : ATTManager.GUIDE_TYPE_ADMOB; // 点位属性确定
 | 
					            _attType = InitConfig.UseCustomConsent ? ATTManager.GUIDE_TYPE_CUSTOM : ATTManager.GUIDE_TYPE_ADMOB; // 点位属性确定
 | 
				
			||||||
            _initialAttStatus = ATTManager.GetStatus();
 | 
					            _initialAttStatus = ATTManager.GetStatus();
 | 
				
			||||||
            SetUserProperty(Analytics.ParameterATTStatus, _initialAttStatus); // 上报一个初始的状态
 | 
					            SetATTStatus(_initialAttStatus); // 上报一个初始的状态
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// iOS 平台检查 ATT 状态
 | 
					        /// iOS 平台检查 ATT 状态
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        private static void CheckAttStatus(bool autoReCall = false)
 | 
					        private void CheckAttStatus(bool autoReCall = false)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _autoReCallAtt = autoReCall;
 | 
					            _autoReCallAtt = autoReCall;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
| 
						 | 
					@ -194,17 +199,18 @@ namespace Guru
 | 
				
			||||||
            Delay(1, () => ATTManager.CheckStatus(ReportAttStatus));
 | 
					            Delay(1, () => ATTManager.CheckStatus(ReportAttStatus));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static void ReportAttStatus(string status)
 | 
					        private void ReportAttStatus(string status)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogI($"{Tag} --- Get Att status:{status}  att Type:{_attType}  recall:{_autoReCallAtt}");
 | 
					            LogI($"{Tag} --- Get Att status:{status}  att Type:{_attType}  recall:{_autoReCallAtt}");
 | 
				
			||||||
            SetUserProperty(Analytics.ParameterATTStatus, status); // 当前的状态
 | 
					            SetATTStatus(_initialAttStatus); // 上报一个初始的状态
 | 
				
			||||||
 | 
					            // SetUserProperty(Analytics.ParameterATTStatus, status); // 当前的状态
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if (!string.IsNullOrEmpty(status) 
 | 
					            if (!string.IsNullOrEmpty(status) 
 | 
				
			||||||
                && status != _initialAttStatus 
 | 
					                && status != _initialAttStatus 
 | 
				
			||||||
                && status !=  ATTManager.ATT_STATUS_NOT_DETERMINED)
 | 
					                && status !=  ATTManager.ATT_STATUS_NOT_DETERMINED)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // 上报点位:
 | 
					                // 上报点位:
 | 
				
			||||||
                Analytics.AttResult(status, _attType);
 | 
					                SetATTStatus(_initialAttStatus);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            switch(status)
 | 
					            switch(status)
 | 
				
			||||||
| 
						 | 
					@ -221,52 +227,93 @@ namespace Guru
 | 
				
			||||||
                    // ATT 状态已授权
 | 
					                    // ATT 状态已授权
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            CheckNotiPermission(); // Consent 回调后检查 Notification 权限
 | 
				
			||||||
        } 
 | 
					        } 
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #region Android 13 PushNotification Permission 
 | 
					        #region Notification Permission Check
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private const string PERMISSION_POST_NOTIFICATION = "android.permission.POST_NOTIFICATIONS";
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 初始化 Noti Service
 | 
				
			||||||
        private void CheckPermission()
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private void InitNotiPermission()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            float delay = 1;
 | 
					            // bool hasNotiGranted = false;
 | 
				
			||||||
            UnityEngine.Debug.Log($"---- Check PushPermission ---");
 | 
					            _notiStatue = "no_determined";
 | 
				
			||||||
#if UNITY_ANDROID
 | 
					            NotificationService.Initialize(); // 初始化 Noti 服务
 | 
				
			||||||
            // 如果已经请求过权限的话, 则不做动作
 | 
					            Analytics.SetNotiPerm(NotificationService.GetStatus());
 | 
				
			||||||
            if (UnityEngine.Android.Permission.HasUserAuthorizedPermission(PERMISSION_POST_NOTIFICATION))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                UnityEngine.Debug.Log($"--- PushPermission has passed ---");
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
            Invoke(nameof(RequestNotification), delay);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 请求Notification
 | 
					        /// 检查 Noti 状态
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        private void RequestNotification()
 | 
					        private void CheckNotiPermission()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
#if UNITY_ANDROID
 | 
					            var status = NotificationService.GetStatus();
 | 
				
			||||||
            UnityEngine.Debug.Log("--- Target 33 Request Notification ---");
 | 
					            
 | 
				
			||||||
            // Android直接申请授权
 | 
					            // 如果未启用自动 Noti 授权,则直接上报状态
 | 
				
			||||||
            if (!UnityEngine.Android.Permission.HasUserAuthorizedPermission(PERMISSION_POST_NOTIFICATION))
 | 
					            if (!_initConfig.AutoNotificationPermission)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UnityEngine.Android.Permission.RequestUserPermission(PERMISSION_POST_NOTIFICATION);
 | 
					                Debug.LogWarning($"[SDK] ---- AutoNotificationPermission is OFF, Project should request permission own.");
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
#endif
 | 
					
 | 
				
			||||||
 | 
					            bool isGranted = NotificationService.IsPermissionGranted();
 | 
				
			||||||
 | 
					            Debug.Log($"[SDK] ---- Check Noti Permission: {isGranted}");
 | 
				
			||||||
 | 
					            if (isGranted)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Debug.Log($"[SDK] ---- Set Notification Permission: {status}");
 | 
				
			||||||
 | 
					                Analytics.SetNotiPerm(status);
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            RequestNotificationPermission(); // 请求授权
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 请求推送授权
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="callback"></param>
 | 
				
			||||||
 | 
					        public static void RequestNotificationPermission(Action<string> callback = null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            FirebaseUtil.StartFetchFcmToken();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            Debug.Log($"[SDK] ---- RequestNotificationPermission");
 | 
				
			||||||
 | 
					            NotificationService.RequestPermission(status =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Debug.Log($"[SDK] ---- Set Notification Permission: {status}");
 | 
				
			||||||
 | 
					                if(!string.IsNullOrEmpty(status)) Analytics.SetNotiPerm(status);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                callback?.Invoke(status);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 获取 Notification 状态值
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        public static string GetNotificationStatus()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return NotificationService.GetStatus();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 用户是否已经获取了 Notification 授权了
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        public static bool IsNotificationPermissionGranted()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return NotificationService.IsPermissionGranted();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #region Ad Services
 | 
					        #region Ad Services
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static bool _initAdsCompleted = false;
 | 
					        private static bool _initAdsCompleted = false;
 | 
				
			||||||
        private static bool _isBannerVisible = false;
 | 
					 | 
				
			||||||
        public static bool IsAdsReady => _initAdsCompleted;
 | 
					        public static bool IsAdsReady => _initAdsCompleted;
 | 
				
			||||||
        private static int _preBannerAction = 0;
 | 
					        private static int _preBannerAction = 0;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					@ -279,7 +326,7 @@ namespace Guru
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 启动广告服务
 | 
					        /// 启动广告服务
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        internal static void StartAdService(AdsInitSpec spec = null)
 | 
					        private static void StartAdService(AdsInitSpec spec = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            //---------- Using InitConfig ----------
 | 
					            //---------- Using InitConfig ----------
 | 
				
			||||||
| 
						 | 
					@ -300,16 +347,18 @@ namespace Guru
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            //--------- Add Callbacks -----------
 | 
					            //--------- Add Callbacks -----------
 | 
				
			||||||
            // BADS
 | 
					            // BADS
 | 
				
			||||||
            ADService.OnBannerStartLoad = OnBannerStartLoad;
 | 
					            ADService.Instance.OnBannerStartLoad = OnBannerStartLoad;
 | 
				
			||||||
            ADService.OnBannerLoaded = OnBannerLoaded;
 | 
					            ADService.Instance.OnBannerLoaded = OnBannerLoaded;
 | 
				
			||||||
            // IADS
 | 
					            // IADS
 | 
				
			||||||
            ADService.OnInterstitialStartLoad = OnInterstitialStartLoad;
 | 
					            ADService.Instance.OnInterstitialStartLoad = OnInterstitialStartLoad;
 | 
				
			||||||
            ADService.OnInterstitialLoaded = OnInterstitialLoaded;
 | 
					            ADService.Instance.OnInterstitialLoaded = OnInterstitialLoaded;
 | 
				
			||||||
            ADService.OnInterstitialFailed = OnInterstitialFailed;
 | 
					            ADService.Instance.OnInterstitialFailed = OnInterstitialFailed;
 | 
				
			||||||
 | 
					            ADService.Instance.OnInterstitialClosed = OnInterstitialClosed;
 | 
				
			||||||
            // RADS
 | 
					            // RADS
 | 
				
			||||||
            ADService.OnRewardedStartLoad = OnRewardedStartLoad;
 | 
					            ADService.Instance.OnRewardedStartLoad = OnRewardStartLoad;
 | 
				
			||||||
            ADService.OnRewardLoaded = OnRewardedLoaded;
 | 
					            ADService.Instance.OnRewardLoaded = OnRewardLoaded;
 | 
				
			||||||
            ADService.OnRewardFailed = OnRewardedFailed;
 | 
					            ADService.Instance.OnRewardFailed = OnRewardFailed;
 | 
				
			||||||
 | 
					            ADService.Instance.OnRewardClosed = OnRewardClosed;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // ---------- Start Services ----------
 | 
					            // ---------- Start Services ----------
 | 
				
			||||||
            ADService.Instance.StartService(OnAdsInitComplete, spec);
 | 
					            ADService.Instance.StartService(OnAdsInitComplete, spec);
 | 
				
			||||||
| 
						 | 
					@ -329,21 +378,25 @@ namespace Guru
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static void OnBannerStartLoad(string adUnitId)
 | 
					        private static void OnBannerStartLoad(string adUnitId)
 | 
				
			||||||
            => Callbacks.Ads._onBannerADStartLoad?.Invoke(adUnitId);
 | 
					            => Callbacks.Ads.InvokeOnBannerADStartLoad(adUnitId);
 | 
				
			||||||
        private static void OnBannerLoaded() 
 | 
					        private static void OnBannerLoaded() 
 | 
				
			||||||
            => Callbacks.Ads._onBannerADLoaded?.Invoke();
 | 
					            => Callbacks.Ads.InvokeOnBannerADLoaded();
 | 
				
			||||||
        private static void OnInterstitialStartLoad(string adUnitId) 
 | 
					        private static void OnInterstitialStartLoad(string adUnitId) 
 | 
				
			||||||
            => Callbacks.Ads._onInterstitialADStartLoad?.Invoke(adUnitId);
 | 
					            => Callbacks.Ads.InvokeOnInterstitialADStartLoad(adUnitId);
 | 
				
			||||||
        private static void OnInterstitialLoaded() 
 | 
					        private static void OnInterstitialLoaded() 
 | 
				
			||||||
            => Callbacks.Ads._onInterstitialADLoaded?.Invoke();
 | 
					            => Callbacks.Ads.InvokeOnInterstitialADLoaded();
 | 
				
			||||||
        private static void OnInterstitialFailed()
 | 
					        private static void OnInterstitialFailed()
 | 
				
			||||||
            => Callbacks.Ads._onInterstitialADFailed?.Invoke();
 | 
					            => Callbacks.Ads.InvokeOnInterstitialADFailed();
 | 
				
			||||||
        private static void OnRewardedStartLoad(string adUnitId)
 | 
					        private static void OnInterstitialClosed()
 | 
				
			||||||
            => Callbacks.Ads._onRewardedADStartLoad?.Invoke(adUnitId); 
 | 
					            => Callbacks.Ads.InvokeOnInterstitialADClosed();
 | 
				
			||||||
        private static void OnRewardedLoaded()
 | 
					        private static void OnRewardStartLoad(string adUnitId)
 | 
				
			||||||
            => Callbacks.Ads._onRewardedADLoaded?.Invoke(); 
 | 
					            => Callbacks.Ads.InvokeOnRewardedADStartLoad(adUnitId); 
 | 
				
			||||||
        private static void OnRewardedFailed()
 | 
					        private static void OnRewardLoaded()
 | 
				
			||||||
            => Callbacks.Ads._onRewardADFailed?.Invoke();
 | 
					            => Callbacks.Ads.InvokeOnRewardedADLoaded(); 
 | 
				
			||||||
 | 
					        private static void OnRewardFailed()
 | 
				
			||||||
 | 
					            => Callbacks.Ads.InvokeOnRewardADFailed();
 | 
				
			||||||
 | 
					        private static void OnRewardClosed()
 | 
				
			||||||
 | 
					            => Callbacks.Ads.InvokeOnRewardADClosed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static void OnAdsInitComplete()
 | 
					        private static void OnAdsInitComplete()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -363,7 +416,7 @@ namespace Guru
 | 
				
			||||||
                    HideBanner();
 | 
					                    HideBanner();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Callbacks.Ads._onAdsInitComplete?.Invoke();
 | 
					            Callbacks.Ads.InvokeOnAdsInitComplete();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static bool CheckAdsReady()
 | 
					        private static bool CheckAdsReady()
 | 
				
			||||||
| 
						 | 
					@ -494,6 +547,7 @@ namespace Guru
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,4 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Guru
 | 
					namespace Guru
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using System;
 | 
					    using System;
 | 
				
			||||||
| 
						 | 
					@ -12,24 +10,9 @@ namespace Guru
 | 
				
			||||||
    /// </summary>
 | 
					    /// </summary>
 | 
				
			||||||
    public partial class GuruSDK
 | 
					    public partial class GuruSDK
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// 主线关卡类型
 | 
					 | 
				
			||||||
        /// 只有传入此类型时才会进行 Blevel 的累加
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        public const string LevelTypeMain = "main";
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        //----------------- 关卡开始类型 ---------------------
 | 
					 | 
				
			||||||
        public const string EventLevelStartModePlay = "play";
 | 
					 | 
				
			||||||
        public const string EventLevelStartModeReplay = "replay";
 | 
					 | 
				
			||||||
        public const string EventLevelStartModeContinue= "continue";
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        //----------------- 关卡结束类型 ---------------------
 | 
					 | 
				
			||||||
        public const string EventLevelEndSuccess = "success";
 | 
					 | 
				
			||||||
        public const string EventLevelEndFail = "fail";
 | 
					 | 
				
			||||||
        public const string EventLevelEndExit = "exit";
 | 
					 | 
				
			||||||
        public const string EventLevelEndTimeout = "timeout";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #region 通用接口
 | 
					        #region 通用接口
 | 
				
			||||||
 | 
					        //TODO: 需要有一个通用的 IEventData 的接口, 需要实现 getName, getData, getSetting, getPriority 等方法
 | 
				
			||||||
 | 
					        //TODO: Analytics.Track 的参数改为 IEventData
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 自定义事件打点
 | 
					        /// 自定义事件打点
 | 
				
			||||||
| 
						 | 
					@ -39,14 +22,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="priority"></param>
 | 
					        /// <param name="priority"></param>
 | 
				
			||||||
        public static void LogEvent(string eventName, Dictionary<string, dynamic> data = null, int priority = -1)
 | 
					        public static void LogEvent(string eventName, Dictionary<string, dynamic> data = null, int priority = -1)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!IsInitialSuccess)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                UnityEngine.Debug.LogError($"{Tag} :: LogEvent {eventName} :: Please call <GuruSDK.Start()> first, before you call <LogEvent>.");
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if(priority < 0) priority = GetEventPriorityInt(eventName);
 | 
					            if(priority < 0) priority = GetEventPriorityInt(eventName);
 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            Analytics.Track(eventName, data, null, priority);
 | 
					            Analytics.Track(eventName, data, null, priority);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,12 +30,96 @@ namespace Guru
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!IsInitialSuccess)
 | 
					            if (!IsInitialSuccess)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UnityEngine.Debug.LogError($"{Tag} :: SetScreen {screen} :: Please call <GuruSDK.Start()> first, before you call <SetScreen>.");
 | 
					                UnityEngine.Debug.LogWarning($"{Tag} :: SetScreen {screen} can not be set before SDK init!");
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Analytics.SetCurrentScreen(screen, extra);
 | 
					            Analytics.SetCurrentScreen(screen, extra);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        #region 设置用户属性
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 设置用户属性
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="key"></param>
 | 
				
			||||||
 | 
					        /// <param name="value"></param>
 | 
				
			||||||
 | 
					        public static void SetUserProperty(string key, string value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Analytics.SetUserProperty(key, value);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void SetUID(string uid)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Analytics.SetUid(uid);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void SetUserBLevel(int bLevel)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Analytics.SetBLevel(bLevel);
 | 
				
			||||||
 | 
					            Model.BLevel = bLevel;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public static void SetUserBPlay(int bPlay)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Analytics.SetBPlay(bPlay);
 | 
				
			||||||
 | 
					            Model.BPlay = bPlay;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 上报用户全部的 Coin (当前值)
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="coins"></param>
 | 
				
			||||||
 | 
					        public static void SetUserCoin(int coins)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SetUserProperty(Consts.PropertyCoin, $"{coins}");        
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 上报用户免费金币的 数量 (累加值)
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="freeCoins"></param>
 | 
				
			||||||
 | 
					        public static void SetUserNonIapCoin(int freeCoins)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SetUserProperty(Consts.PropertyNonIAPCoin, $"{freeCoins}");        
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 上报用户付费金币的 数量 (累加值)
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="paidCoins"></param>
 | 
				
			||||||
 | 
					        public static void SetUserIapCoin(int paidCoins)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SetUserProperty(Consts.PropertyIAPCoin, $"{paidCoins}");        
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public static void SetUserExp(int exp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SetUserProperty(Consts.PropertyExp, $"{exp}");        
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        public static void SetUserHp(int hp)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SetUserProperty(Consts.PropertyHp, $"{hp}");        
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void SetUserGrade(int grade)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SetUserProperty(Consts.PropertyGrade, $"{grade}");        
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void SetUserIsIAP(bool isIapUser)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Analytics.SetIsIapUser(isIapUser);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void SetATTStatus(string status)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Analytics.SetAttStatus(status);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #region 游戏打点
 | 
					        #region 游戏打点
 | 
				
			||||||
| 
						 | 
					@ -74,13 +134,13 @@ namespace Guru
 | 
				
			||||||
        /// <param name="startType">关卡开始类型: play:开始游戏;replay:重玩;continue:继续游戏</param>
 | 
					        /// <param name="startType">关卡开始类型: play:开始游戏;replay:重玩;continue:继续游戏</param>
 | 
				
			||||||
        /// <param name="isReplay">是否重新开始: true/false</param>
 | 
					        /// <param name="isReplay">是否重新开始: true/false</param>
 | 
				
			||||||
        /// <param name="extra">扩展数据</param>
 | 
					        /// <param name="extra">扩展数据</param>
 | 
				
			||||||
        public static void LogLevelStart(int levelId, string startType = EventLevelStartModePlay, 
 | 
					        public static void LogLevelStart(int levelId, string startType = Consts.EventLevelStartModePlay, 
 | 
				
			||||||
            string levelType = LevelTypeMain, string levelName = "", string itemId = "",
 | 
					            string levelType = Consts.LevelTypeMain, string levelName = "", string itemId = "",
 | 
				
			||||||
            bool isReplay = false, Dictionary<string, object> extra = null)
 | 
					            bool isReplay = false, Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!IsInitialSuccess)
 | 
					            if (!IsInitialSuccess)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UnityEngine.Debug.LogError($"{Tag} :: LogLevelStart {levelId} :: Please call <GuruSDK.Start()> first, before you call <LogLevelStart>.");
 | 
					                Debug.LogError($"{Tag} :: LogLevelStart {levelId} :: Please call <GuruSDK.Start()> first, before you call <LogLevelStart>.");
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,10 +155,10 @@ namespace Guru
 | 
				
			||||||
        /// <param name="levelName"></param>
 | 
					        /// <param name="levelName"></param>
 | 
				
			||||||
        /// <param name="itemId"></param>
 | 
					        /// <param name="itemId"></param>
 | 
				
			||||||
        /// <param name="extra"></param>
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogLevelContinue(int levelId, string levelType = LevelTypeMain,
 | 
					        public static void LogLevelContinue(int levelId, string levelType = Consts.LevelTypeMain,
 | 
				
			||||||
            string levelName = "", string itemId = "", Dictionary<string, object> extra = null)
 | 
					            string levelName = "", string itemId = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogLevelStart(levelId, EventLevelStartModeContinue, levelType, levelName, itemId,  true, extra:extra);
 | 
					            LogLevelStart(levelId, Consts.EventLevelStartModeContinue, levelType, levelName, itemId,  true, extra:extra);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -108,10 +168,10 @@ namespace Guru
 | 
				
			||||||
        /// <param name="levelType"></param>
 | 
					        /// <param name="levelType"></param>
 | 
				
			||||||
        /// <param name="levelName"></param>
 | 
					        /// <param name="levelName"></param>
 | 
				
			||||||
        /// <param name="itemId"></param>
 | 
					        /// <param name="itemId"></param>
 | 
				
			||||||
        public static void LogLevelReplay(int levelId, string levelType = LevelTypeMain,
 | 
					        public static void LogLevelReplay(int levelId, string levelType = Consts.LevelTypeMain,
 | 
				
			||||||
            string levelName = "", string itemId = "", Dictionary<string, object> extra = null)
 | 
					            string levelName = "", string itemId = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogLevelStart(levelId, EventLevelStartModeReplay,levelType, levelName, itemId,  true, extra:extra);
 | 
					            LogLevelStart(levelId, Consts.EventLevelStartModeReplay,levelType, levelName, itemId,  true, extra:extra);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -126,36 +186,37 @@ namespace Guru
 | 
				
			||||||
        /// <param name="step">步数(有则上报)</param>
 | 
					        /// <param name="step">步数(有则上报)</param>
 | 
				
			||||||
        /// <param name="score">分数(有则上报)</param>
 | 
					        /// <param name="score">分数(有则上报)</param>
 | 
				
			||||||
        /// <param name="extra">扩展数据</param>
 | 
					        /// <param name="extra">扩展数据</param>
 | 
				
			||||||
        public static void LogLevelEnd(int levelId, string result = EventLevelEndSuccess,
 | 
					        public static void LogLevelEnd(int levelId, string result = Consts.EventLevelEndSuccess,
 | 
				
			||||||
            string levelType = LevelTypeMain, string levelName = "", string itemId = "",
 | 
					            string levelType = Consts.LevelTypeMain, string levelName = "", string itemId = "",
 | 
				
			||||||
            int duration = 0, int? step = null, int? score = null, Dictionary<string, object> extra = null)
 | 
					            int duration = 0, int? step = null, int? score = null, Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!IsInitialSuccess)
 | 
					            if (!IsInitialSuccess)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UnityEngine.Debug.LogError(
 | 
					                Debug.LogError(
 | 
				
			||||||
                    $"{Tag} :: LogLevelEnd {levelId} :: Please call <GuruSDK.Start()> first, before you call <LogLevelEnd>.");
 | 
					                    $"{Tag} :: LogLevelEnd {levelId} :: Please call <GuruSDK.Start()> first, before you call <LogLevelEnd>.");
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (extra == null) extra = new Dictionary<string, object>();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            // 优先打 level_end 事件
 | 
					            // 优先打 level_end 事件
 | 
				
			||||||
            Analytics.LogLevelEnd(levelId, result, levelName, levelType, itemId, duration, step, score, extra);
 | 
					            Analytics.LogLevelEnd(levelId, result, levelName, levelType, itemId, duration, step, score, extra);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // 自动记录关卡属性
 | 
					            // 自动记录关卡属性
 | 
				
			||||||
            if (InitConfig.AutoRecordFinishedLevels)
 | 
					            if (InitConfig.AutoRecordFinishedLevels)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (result == EventLevelEndSuccess)
 | 
					                if (result == Consts.EventLevelEndSuccess)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (levelType == LevelTypeMain)
 | 
					                    if (levelType.ToLower() == Consts.LevelTypeMain)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (levelId > Model.SuccessLevelId) Model.SuccessLevelId = levelId; // 自动记录关卡完成次数
 | 
					                        Model.BLevel = levelId; // 自动记录 [主线] 关卡完成次数
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    Model.TotalPlayedCount++; // 自动记录关卡总次数
 | 
					                    Model.BPlay++; // 自动记录关卡总次数
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    Analytics.LevelEndSuccess(Model.TotalPlayedCount); // 自动 level_end_success
 | 
					                    var eventData = new LevelEndSuccessEventData(Model.BPlay, extra);
 | 
				
			||||||
 | 
					                    Analytics.TrackLevelEndSuccessEvent(eventData); // 自动 level_end_success
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                Analytics.BLevel = Model.SuccessLevelId; // 记录 BLevel
 | 
					 | 
				
			||||||
                Analytics.BPlay = Model.TotalPlayedCount; // 记录 BPlay
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
           
 | 
					           
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -170,7 +231,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="duration"></param>
 | 
					        /// <param name="duration"></param>
 | 
				
			||||||
        /// <param name="extra"></param>
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogLevelFirstEnd(string levelType, string levelName, int level,
 | 
					        public static void LogLevelFirstEnd(string levelType, string levelName, int level,
 | 
				
			||||||
            string result = EventLevelEndSuccess, int duration = 0, Dictionary<string, object> extra = null)
 | 
					            string result = Consts.EventLevelEndSuccess, int duration = 0, Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Analytics.LevelFirstEnd(levelType, levelName, level, result, duration, extra);
 | 
					            Analytics.LevelFirstEnd(levelType, levelName, level, result, duration, extra);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -182,8 +243,8 @@ namespace Guru
 | 
				
			||||||
        /// /// <param name="extra">扩展参数</param>
 | 
					        /// /// <param name="extra">扩展参数</param>
 | 
				
			||||||
        public static void LogLevelEndSuccess(int bPlay, Dictionary<string, object> extra = null)
 | 
					        public static void LogLevelEndSuccess(int bPlay, Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (InitConfig.AutoRecordFinishedLevels) return;
 | 
					            var eventData = new LevelEndSuccessEventData(bPlay, extra);
 | 
				
			||||||
            Analytics.LevelEndSuccess(bPlay, extra);
 | 
					            Analytics.TrackLevelEndSuccessEvent(eventData);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -198,10 +259,10 @@ namespace Guru
 | 
				
			||||||
        /// <param name="score"></param>
 | 
					        /// <param name="score"></param>
 | 
				
			||||||
        /// <param name="extra"></param>
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogLevelFail(int levelId,
 | 
					        public static void LogLevelFail(int levelId,
 | 
				
			||||||
            string levelType = LevelTypeMain, string levelName = "", string itemId = "",
 | 
					            string levelType = Consts.LevelTypeMain, string levelName = "", string itemId = "",
 | 
				
			||||||
            int duration = 0, int? step = null, int? score = null , Dictionary<string, object> extra = null)
 | 
					            int duration = 0, int? step = null, int? score = null , Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogLevelEnd(levelId, EventLevelEndFail, levelType, levelName, itemId, duration, step, score, extra);
 | 
					            LogLevelEnd(levelId, Consts.EventLevelEndFail, levelType, levelName, itemId, duration, step, score, extra);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -216,10 +277,10 @@ namespace Guru
 | 
				
			||||||
        /// <param name="score"></param>
 | 
					        /// <param name="score"></param>
 | 
				
			||||||
        /// <param name="extra"></param>
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogLevelFailExit(int levelId,
 | 
					        public static void LogLevelFailExit(int levelId,
 | 
				
			||||||
            string levelType = LevelTypeMain, string levelName = "", string itemId = "",
 | 
					            string levelType = Consts.LevelTypeMain, string levelName = "", string itemId = "",
 | 
				
			||||||
            int duration = 0, int? step = null, int? score = null, Dictionary<string, object> extra = null)
 | 
					            int duration = 0, int? step = null, int? score = null, Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogLevelEnd(levelId, EventLevelEndExit, levelType, levelName, itemId, duration, step, score, extra);
 | 
					            LogLevelEnd(levelId, Consts.EventLevelEndExit, levelType, levelName, itemId, duration, step, score, extra);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -234,10 +295,10 @@ namespace Guru
 | 
				
			||||||
        /// <param name="score"></param>
 | 
					        /// <param name="score"></param>
 | 
				
			||||||
        /// <param name="extra"></param>
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogLevelFailTimeout(int levelId,
 | 
					        public static void LogLevelFailTimeout(int levelId,
 | 
				
			||||||
            string levelType = LevelTypeMain, string levelName = "", string itemId = "",
 | 
					            string levelType = Consts.LevelTypeMain, string levelName = "", string itemId = "",
 | 
				
			||||||
            int duration = 0, int? step = null, int? score = null, Dictionary<string, object> extra = null)
 | 
					            int duration = 0, int? step = null, int? score = null, Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogLevelEnd(levelId, EventLevelEndTimeout, levelType, levelName, itemId, duration, step, score, extra);
 | 
					            LogLevelEnd(levelId, Consts.EventLevelEndTimeout, levelType, levelName, itemId, duration, step, score, extra);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -251,7 +312,7 @@ namespace Guru
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!IsInitialSuccess)
 | 
					            if (!IsInitialSuccess)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UnityEngine.Debug.LogError($"{Tag} :: LogLevelUp {playerLevel} :: Please call <GuruSDK.Start()> first, before you call <LogLevelUp>.");
 | 
					                Debug.LogError($"{Tag} :: LogLevelUp {playerLevel} :: Please call <GuruSDK.Start()> first, before you call <LogLevelUp>.");
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Analytics.LevelUp(playerLevel, characterName, extra);
 | 
					            Analytics.LevelUp(playerLevel, characterName, extra);
 | 
				
			||||||
| 
						 | 
					@ -266,7 +327,7 @@ namespace Guru
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!IsInitialSuccess)
 | 
					            if (!IsInitialSuccess)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UnityEngine.Debug.LogError($"{Tag} :: LogAchievement {achievementId} :: Please call <GuruSDK.Start()> first, before you call <LogAchievement>.");
 | 
					                Debug.LogError($"{Tag} :: LogAchievement {achievementId} :: Please call <GuruSDK.Start()> first, before you call <LogAchievement>.");
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Analytics.UnlockAchievement(achievementId, extra);
 | 
					            Analytics.UnlockAchievement(achievementId, extra);
 | 
				
			||||||
| 
						 | 
					@ -309,205 +370,6 @@ namespace Guru
 | 
				
			||||||
            LogEvent(Consts.EventHpPoints, dict);
 | 
					            LogEvent(Consts.EventHpPoints, dict);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
        #endregion
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #region 用户属性
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// 提前调用用户属性
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        private static void InitUserProperties()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (!IsInitialSuccess)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                UnityEngine.Debug.LogError($"{Tag} :: InitUserProperties :: Please call <GuruSDK.Start()> first, before you call <InitUserProperties>.");
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            Debug.Log($"[SDK] --- PurchasedCount:{Model.PurchasedCount}");
 | 
					 | 
				
			||||||
            Debug.Log($"[SDK] --- IsIapUser:{Model.IsIapUser}");
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            SetUserIsIAP(Model.IsIapUser); // 预先设置用户的 IAP User 属性
 | 
					 | 
				
			||||||
            SetUserBLevel(Model.SuccessLevelId); // 预先设置用户的 BLevel 属性
 | 
					 | 
				
			||||||
            SetUserBPlay(Model.TotalPlayedCount);  // 预先设置用户的 BPlay 属性
 | 
					 | 
				
			||||||
            if (Model.IsNoAds) SetBuyNoAds(true); // 设置用户已经购买了去广告
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private static HashSet<string> _userPropertyExistKeys = new HashSet<string>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private static void RecordUserPropertyKey(string key)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if(_userPropertyExistKeys == null)
 | 
					 | 
				
			||||||
                _userPropertyExistKeys = new HashSet<string>();
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(key)) _userPropertyExistKeys.Add(key);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        private static bool HasUserPropertyKey(string key)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return _userPropertyExistKeys?.Contains(key) ?? false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// 设置用户属性
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="key"></param>
 | 
					 | 
				
			||||||
        /// <param name="value"></param>
 | 
					 | 
				
			||||||
        public static void SetUserProperty(string key, string value)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (!IsInitialSuccess)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                UnityEngine.Debug.LogError($"{Tag} :: SetUserProperty {key}:{value} ::Please call <GuruSDK.Start()> first, before you call <SetUserProperty>.");
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            RecordUserPropertyKey(key);
 | 
					 | 
				
			||||||
            Analytics.SetUserProperty(key, value);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static void SetUID(string uid)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyUserID, uid);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static void SetUserBLevel(int blevel)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (!InitConfig.AutoRecordFinishedLevels)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Model.SetBLevelValue(blevel);
 | 
					 | 
				
			||||||
                Analytics.BLevel = blevel;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyLevel, $"{blevel}");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public static void SetUserBPlay(int bplay)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (!InitConfig.AutoRecordFinishedLevels)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Model.SetBPlayValue(bplay);
 | 
					 | 
				
			||||||
                Analytics.BPlay = bplay;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyPlay, $"{bplay}");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// 上报用户全部的 Coin (当前值)
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="coins"></param>
 | 
					 | 
				
			||||||
        public static void SetUserCoin(int coins)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyCoin, $"{coins}");        
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// 上报用户免费金币的 数量 (累加值)
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="freeCoins"></param>
 | 
					 | 
				
			||||||
        public static void SetUserNonIapCoin(int freeCoins)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyNonIAPCoin, $"{freeCoins}");        
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// 上报用户付费金币的 数量 (累加值)
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        /// <param name="freeCoins"></param>
 | 
					 | 
				
			||||||
        public static void SetUserIapCoin(int paidCoins)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyIAPCoin, $"{paidCoins}");        
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public static void SetUserExp(int exp)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyExp, $"{exp}");        
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public static void SetUserHp(int hp)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyHp, $"{hp}");        
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static void SetUserGrade(int grade)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyGrade, $"{grade}");        
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static void SetUserIsIAP(bool isIapUser)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyIsIAPUser, isIapUser? "true" : "false");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static void SetFirstOpenTime(string timestamp)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserProperty(Analytics.PropertyFirstOpenTime, timestamp);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public static void SetNotiPerm(string status)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyNotiPerm, status);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        public static void SetATTStatus(string status)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserProperty(Consts.PropertyATTStatus, status);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// 初始化时调用一下所有的属性打点 </br>
 | 
					 | 
				
			||||||
        /// <a href="https://docs.google.com/spreadsheets/d/1N47rXgjatRHFvzWWx0Hqv5C1D9NHHGbggi6pQ65c-zQ/edit#gid=1858695240">用户属性文档</a>
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        private static void UpdateAllUserProperties()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(Consts.PropertyFirstOpenTime)) 
 | 
					 | 
				
			||||||
                SetFirstOpenTime(TimeUtil.GetCurrentTimeStamp().ToString());    //  first_open_time 
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(Consts.PropertyIsIAPUser)) 
 | 
					 | 
				
			||||||
                SetUserIsIAP(Model?.IsIapUser ?? false);    // is_iap_user
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!HasUserPropertyKey(Consts.PropertyLevel))
 | 
					 | 
				
			||||||
                SetUserBLevel(Model?.SuccessLevelId ?? 0);  // b_level
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if (!HasUserPropertyKey(Consts.PropertyPlay))
 | 
					 | 
				
			||||||
                SetUserBLevel(Model?.TotalPlayedCount ?? 0); // b_play
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(Consts.PropertyUserID)) 
 | 
					 | 
				
			||||||
                SetUserProperty(Consts.PropertyUserID, UID); // user_id
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(Consts.PropertyDeviceID)) 
 | 
					 | 
				
			||||||
                SetUserProperty(Consts.PropertyDeviceID, DeviceId); // device_id
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(Consts.PropertyIAPCoin)) 
 | 
					 | 
				
			||||||
                SetUserIapCoin(0); // iap_coin
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(Consts.PropertyNonIAPCoin)) 
 | 
					 | 
				
			||||||
                SetUserNonIapCoin(0); // non_iap_coin
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(Consts.PropertyCoin)) 
 | 
					 | 
				
			||||||
                SetUserCoin(0);// coin
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!HasUserPropertyKey(Consts.PropertyGrade))
 | 
					 | 
				
			||||||
                SetUserGrade(0); // grade
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(Consts.PropertyExp))
 | 
					 | 
				
			||||||
                SetUserExp(0); // exp
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(Consts.PropertyHp))
 | 
					 | 
				
			||||||
                SetUserHp(0); // hp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if UNITY_IOS
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(Consts.PropertyATTStatus))
 | 
					 | 
				
			||||||
                SetATTStatus("notDetermined"); // att_status
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(!HasUserPropertyKey(Consts.PropertyNotiPerm))
 | 
					 | 
				
			||||||
                SetNotiPerm("not_determined"); // noti_perm
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #region SDK 打点
 | 
					        #region SDK 打点
 | 
				
			||||||
| 
						 | 
					@ -516,19 +378,28 @@ namespace Guru
 | 
				
			||||||
        /// Log SDK boost time
 | 
					        /// Log SDK boost time
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="time"></param>
 | 
					        /// <param name="time"></param>
 | 
				
			||||||
        private static void LogSDKInitTime(double time)
 | 
					        private static void LogSDKInfo(double time)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Analytics.Track(Consts.EventSDKInfo, new Dictionary<string, dynamic>()
 | 
					            Analytics.Track(Consts.EventSDKInfo, new Dictionary<string, dynamic>()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                { "boost_time", time.ToString("F6") },
 | 
					                { "boost_time", time.ToString("F6") },
 | 
				
			||||||
                { Consts.PropertyDeviceID, DeviceId },
 | 
					                { Consts.PropertyDeviceID, DeviceId },
 | 
				
			||||||
                { "version", Version}
 | 
					                { "version", Version},
 | 
				
			||||||
 | 
					                { "network", Instance.GetNetworkStatus()},
 | 
				
			||||||
            }, new Analytics.EventSetting()
 | 
					            }, new Analytics.EventSetting()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                EnableFirebaseAnalytics = true,
 | 
					                EnableFirebaseAnalytics = true,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            SetUserProperty("sdk_version", Version);
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 获取 GuruSDK 实验分组
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        public static string GetGuruExperimentGroupId()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (!GuruAnalytics.IsReady) return "not_set";
 | 
				
			||||||
 | 
					            return GuruAnalytics.Instance.ExperimentGroupId;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
| 
						 | 
					@ -560,7 +431,7 @@ namespace Guru
 | 
				
			||||||
        /// 当付费页面打开时调用 (iap_imp)
 | 
					        /// 当付费页面打开时调用 (iap_imp)
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="scene">付费页场景名称</param>
 | 
					        /// <param name="scene">付费页场景名称</param>
 | 
				
			||||||
        /// <param name="productId">列表中首个商品的 ProductId </param>
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogIAPImp(string scene, Dictionary<string, object> extra = null)
 | 
					        public static void LogIAPImp(string scene, Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Analytics.IAPImp(scene, extra);
 | 
					            Analytics.IAPImp(scene, extra);
 | 
				
			||||||
| 
						 | 
					@ -570,7 +441,7 @@ namespace Guru
 | 
				
			||||||
        /// 当付费页面关闭时调用 (iap_close)
 | 
					        /// 当付费页面关闭时调用 (iap_close)
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="scene"></param>
 | 
					        /// <param name="scene"></param>
 | 
				
			||||||
        /// <param name="productId"></param>
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogIAPClose(string scene, Dictionary<string, object> extra = null)
 | 
					        public static void LogIAPClose(string scene, Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Analytics.IAPClose(scene, extra);
 | 
					            Analytics.IAPClose(scene, extra);
 | 
				
			||||||
| 
						 | 
					@ -581,7 +452,9 @@ namespace Guru
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="scene"></param>
 | 
					        /// <param name="scene"></param>
 | 
				
			||||||
        /// <param name="productId"></param>
 | 
					        /// <param name="productId"></param>
 | 
				
			||||||
 | 
					        /// <param name="basePlan"></param>
 | 
				
			||||||
        /// <param name="offerId"></param>
 | 
					        /// <param name="offerId"></param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogIAPClick(string scene, string productId, string basePlan = "", string offerId = "", Dictionary<string, object> extra = null)
 | 
					        public static void LogIAPClick(string scene, string productId, string basePlan = "", string offerId = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Analytics.IAPClick(scene, productId, basePlan, offerId, extra);
 | 
					            Analytics.IAPClick(scene, productId, basePlan, offerId, extra);
 | 
				
			||||||
| 
						 | 
					@ -613,6 +486,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="levelName">当前关卡或者人物等级名称</param>
 | 
					        /// <param name="levelName">当前关卡或者人物等级名称</param>
 | 
				
			||||||
        /// <param name="itemName">购买道具名称</param>
 | 
					        /// <param name="itemName">购买道具名称</param>
 | 
				
			||||||
        /// <param name="scene">购买场景如 Store, Workbench, Sign, Ads....</param>
 | 
					        /// <param name="scene">购买场景如 Store, Workbench, Sign, Ads....</param>
 | 
				
			||||||
 | 
					        /// <param name="extra">自定义数据</param>
 | 
				
			||||||
        public static void LogEarnVirtualCurrency(string currencyName, 
 | 
					        public static void LogEarnVirtualCurrency(string currencyName, 
 | 
				
			||||||
            int value, int balance, 
 | 
					            int value, int balance, 
 | 
				
			||||||
            string category = "", string itemName = "",
 | 
					            string category = "", string itemName = "",
 | 
				
			||||||
| 
						 | 
					@ -621,19 +495,55 @@ namespace Guru
 | 
				
			||||||
            Analytics.EarnVirtualCurrency(currencyName, value, balance, category, itemName,levelName, scene, extra);
 | 
					            Analytics.EarnVirtualCurrency(currencyName, value, balance, category, itemName,levelName, scene, extra);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 游戏初次启动/用户获得初始道具
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="currencyName">货币名称</param>
 | 
				
			||||||
 | 
					        /// <param name="value">货币增加值 10</param>
 | 
				
			||||||
 | 
					        /// <param name="balance">结算后货币总量 20 -> 30</param>
 | 
				
			||||||
 | 
					        /// <param name="levelName">购入道具 ID / 道具名称</param>
 | 
				
			||||||
 | 
					        /// <param name="scene">购买场景如 Store, Workbench, Sign, Ads....</param>
 | 
				
			||||||
 | 
					        /// <param name="extra">自定义数据</param>
 | 
				
			||||||
 | 
					        public static void LogEarnVirtualCurrencyByFirstOpen(string currencyName, 
 | 
				
			||||||
 | 
					            int value, int balance, 
 | 
				
			||||||
 | 
					            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string item_category = Consts.CurrencyCategoryReward;
 | 
				
			||||||
 | 
					            string item_name = "first_open";
 | 
				
			||||||
 | 
					            Analytics.EarnVirtualCurrency(currencyName, value, balance, item_category, item_name,levelName, scene, extra);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 出售道具后获取货币
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="currencyName">货币名称</param>
 | 
				
			||||||
 | 
					        /// <param name="value">货币增加值 10</param>
 | 
				
			||||||
 | 
					        /// <param name="balance">结算后货币总量 20 -> 30</param>
 | 
				
			||||||
 | 
					        /// <param name="itemName">购买道具名称</param>
 | 
				
			||||||
 | 
					        /// <param name="levelName">当前关卡或者人物等级名称</param>
 | 
				
			||||||
 | 
					        /// <param name="scene">购买场景如 Store, Workbench, Sign, Ads....</param>
 | 
				
			||||||
 | 
					        /// <param name="extra">自定义数据</param>
 | 
				
			||||||
 | 
					        public static void LogEarnVirtualCurrencyBySellItem(string currencyName, 
 | 
				
			||||||
 | 
					            int value, int balance, string itemName,
 | 
				
			||||||
 | 
					            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string item_category = Consts.CurrencyCategoryIGC;
 | 
				
			||||||
 | 
					            Analytics.EarnVirtualCurrency(currencyName, value, balance, item_category, itemName,levelName, scene, extra);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 赚取组合: 货币+道具 (earn_virtual_currency) (props)
 | 
					        /// 赚取组合: 货币+道具 (earn_virtual_currency) (props)
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="currencyName"></param>
 | 
					        /// <param name="currencyName">货币名称</param>
 | 
				
			||||||
        /// <param name="value"></param>
 | 
					        /// <param name="value">货币增加值 10</param>
 | 
				
			||||||
        /// <param name="balance"></param>
 | 
					        /// <param name="balance">结算后货币总量 20 -> 30</param>
 | 
				
			||||||
        /// <param name="category"></param>
 | 
					        /// <param name="category">消耗类型, 默认值请赋 reward</param>
 | 
				
			||||||
        /// <param name="itemName"></param>
 | 
					        /// <param name="itemName">购买道具名称</param>
 | 
				
			||||||
        /// <param name="props"></param>
 | 
					        /// <param name="props">获取的道具组合</param>
 | 
				
			||||||
        /// <param name="levelName"></param>
 | 
					        /// <param name="levelName">当前关卡或者人物等级名称</param>
 | 
				
			||||||
        /// <param name="scene"></param>
 | 
					        /// <param name="scene">购买场景如 Store, Workbench, Sign, Ads....</param>
 | 
				
			||||||
 | 
					        /// <param name="extra">自定义数据</param>
 | 
				
			||||||
        private static void LogEarnVirtualCurrencyAndProps(string currencyName, 
 | 
					        private static void LogEarnVirtualCurrencyAndProps(string currencyName, 
 | 
				
			||||||
            int value = 0, int balance = 0,
 | 
					            int value = 0, int balance = 0,
 | 
				
			||||||
            string category = "", string itemName = "",
 | 
					            string category = "", string itemName = "",
 | 
				
			||||||
| 
						 | 
					@ -669,6 +579,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="levelName">当前关卡名称</param>
 | 
					        /// <param name="levelName">当前关卡名称</param>
 | 
				
			||||||
        /// <param name="scene">应用场景</param>
 | 
					        /// <param name="scene">应用场景</param>
 | 
				
			||||||
        /// <param name="props">获取的道具名称列表</param>
 | 
					        /// <param name="props">获取的道具名称列表</param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogEarnVirtualCurrencyBySign(string currencyName, 
 | 
					        public static void LogEarnVirtualCurrencyBySign(string currencyName, 
 | 
				
			||||||
            int value = 0, int balance = 0, string levelName = "", 
 | 
					            int value = 0, int balance = 0, string levelName = "", 
 | 
				
			||||||
            string scene = "home_page", string[] props = null, Dictionary<string, object> extra = null)
 | 
					            string scene = "home_page", string[] props = null, Dictionary<string, object> extra = null)
 | 
				
			||||||
| 
						 | 
					@ -692,6 +603,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="levelName">当前关卡名称</param>
 | 
					        /// <param name="levelName">当前关卡名称</param>
 | 
				
			||||||
        /// <param name="scene">应用场景</param>
 | 
					        /// <param name="scene">应用场景</param>
 | 
				
			||||||
        /// <param name="props">获取的道具名称列表</param>
 | 
					        /// <param name="props">获取的道具名称列表</param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogEarnVirtualCurrencyByIAP(string currencyName,
 | 
					        public static void LogEarnVirtualCurrencyByIAP(string currencyName,
 | 
				
			||||||
            int value = 0, int balance = 0, string levelName = "", 
 | 
					            int value = 0, int balance = 0, string levelName = "", 
 | 
				
			||||||
            string scene = "store", string[] props = null, Dictionary<string, object> extra = null)
 | 
					            string scene = "store", string[] props = null, Dictionary<string, object> extra = null)
 | 
				
			||||||
| 
						 | 
					@ -714,6 +626,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="levelName">当前关卡名称</param>
 | 
					        /// <param name="levelName">当前关卡名称</param>
 | 
				
			||||||
        /// <param name="scene">应用场景</param>
 | 
					        /// <param name="scene">应用场景</param>
 | 
				
			||||||
        /// <param name="props">获取的道具名称列表</param>
 | 
					        /// <param name="props">获取的道具名称列表</param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogEarnVirtualCurrencyByAds(string currencyName, 
 | 
					        public static void LogEarnVirtualCurrencyByAds(string currencyName, 
 | 
				
			||||||
            int value = 0, int balance = 0, string levelName = "", 
 | 
					            int value = 0, int balance = 0, string levelName = "", 
 | 
				
			||||||
            string scene = "store", string[] props = null, Dictionary<string, object> extra = null)
 | 
					            string scene = "store", string[] props = null, Dictionary<string, object> extra = null)
 | 
				
			||||||
| 
						 | 
					@ -735,6 +648,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="levelName">当前关卡名称</param>
 | 
					        /// <param name="levelName">当前关卡名称</param>
 | 
				
			||||||
        /// <param name="scene">应用场景</param>
 | 
					        /// <param name="scene">应用场景</param>
 | 
				
			||||||
        /// <param name="props">获取的道具名称列表</param>
 | 
					        /// <param name="props">获取的道具名称列表</param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogEarnVirtualCurrencyByPaidAds(string currencyName, 
 | 
					        public static void LogEarnVirtualCurrencyByPaidAds(string currencyName, 
 | 
				
			||||||
            int value = 0, int balance = 0, string levelName = "", 
 | 
					            int value = 0, int balance = 0, string levelName = "", 
 | 
				
			||||||
            string scene = Consts.ParameterDefaultScene, string[] props = null, Dictionary<string, object> extra = null)
 | 
					            string scene = Consts.ParameterDefaultScene, string[] props = null, Dictionary<string, object> extra = null)
 | 
				
			||||||
| 
						 | 
					@ -756,6 +670,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="levelName">当前关卡名称</param>
 | 
					        /// <param name="levelName">当前关卡名称</param>
 | 
				
			||||||
        /// <param name="scene">应用场景</param>
 | 
					        /// <param name="scene">应用场景</param>
 | 
				
			||||||
        /// <param name="props">获取的道具名称列表</param>
 | 
					        /// <param name="props">获取的道具名称列表</param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogEarnVirtualCurrencyByLevelComplete(string currencyName, 
 | 
					        public static void LogEarnVirtualCurrencyByLevelComplete(string currencyName, 
 | 
				
			||||||
            int value = 0, int balance = 0, string levelName = "", 
 | 
					            int value = 0, int balance = 0, string levelName = "", 
 | 
				
			||||||
            string scene = "store", string[] props = null, Dictionary<string, object> extra = null)
 | 
					            string scene = "store", string[] props = null, Dictionary<string, object> extra = null)
 | 
				
			||||||
| 
						 | 
					@ -767,22 +682,23 @@ namespace Guru
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 通过使用 Currency 购买获得 Prop (earn_virtual_currency) (reward:level) 
 | 
					        /// 购买获得 Prop (earn_virtual_currency) (reward:level) 
 | 
				
			||||||
        /// 记录 Prop 增加的打点, 消费游戏内货币
 | 
					        /// 记录 Prop 增加的打点, 消费游戏内货币
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="currencyName">货币名称</param>
 | 
					        /// <param name="currencyName">购买的道具名称</param>
 | 
				
			||||||
        /// <param name="props">获取的道具名称列表</param>
 | 
					        /// <param name="spendCurrencyName">消费货币名称</param>
 | 
				
			||||||
        /// <param name="scene">应用场景</param>
 | 
					        /// <param name="scene">应用场景</param>
 | 
				
			||||||
        /// <param name="value">赚取金额</param>
 | 
					        /// <param name="value">购入数量</param>
 | 
				
			||||||
        /// <param name="balance">货币总量(累加后)</param>
 | 
					        /// <param name="balance">道具总量(累加后)</param>
 | 
				
			||||||
        /// <param name="levelName">当前关卡名称</param>
 | 
					        /// <param name="levelName">当前关卡名称</param>
 | 
				
			||||||
        public static void LogEarnPropsByVirtualCurrency(string currencyName, string[] props,
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
            string scene = Consts.ParameterDefaultScene,
 | 
					        public static void LogEarnVirtualCurrencyByIGC(string currencyName, string spendCurrencyName, int value = 0, int balance = 0, 
 | 
				
			||||||
            int value = 1, int balance = 0, string levelName = "", Dictionary<string, object> extra = null)
 | 
					            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            string category = Consts.CurrencyCategoryIGC;
 | 
					            string category = Consts.CurrencyCategoryIGC;
 | 
				
			||||||
            string itemName = currencyName;
 | 
					            string itemName = spendCurrencyName;
 | 
				
			||||||
            LogEarnVirtualCurrencyAndProps(currencyName, value, balance, category, itemName, levelName, scene, props, extra);
 | 
					            if (string.IsNullOrEmpty(scene)) scene = Consts.ParameterDefaultScene;
 | 
				
			||||||
 | 
					            LogEarnVirtualCurrencyAndProps(currencyName, value, balance, category, itemName, levelName, scene, null, extra); // TODO 这里的打点不对
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -794,6 +710,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="value"></param>
 | 
					        /// <param name="value"></param>
 | 
				
			||||||
        /// <param name="balance"></param>
 | 
					        /// <param name="balance"></param>
 | 
				
			||||||
        /// <param name="levelName"></param>
 | 
					        /// <param name="levelName"></param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogEarnPropByProp(string propName, string otherName,
 | 
					        public static void LogEarnPropByProp(string propName, string otherName,
 | 
				
			||||||
            string scene = Consts.ParameterDefaultScene,
 | 
					            string scene = Consts.ParameterDefaultScene,
 | 
				
			||||||
            int value = 1, int balance = 0, string levelName = "", Dictionary<string, object> extra = null)
 | 
					            int value = 1, int balance = 0, string levelName = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
| 
						 | 
					@ -815,6 +732,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="levelName">当前关卡名称</param>
 | 
					        /// <param name="levelName">当前关卡名称</param>
 | 
				
			||||||
        /// <param name="scene">应用场景</param>
 | 
					        /// <param name="scene">应用场景</param>
 | 
				
			||||||
        /// <param name="props">获取的道具名称列表</param>
 | 
					        /// <param name="props">获取的道具名称列表</param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogEarnVirtualCurrencyByLottery(string currencyName, 
 | 
					        public static void LogEarnVirtualCurrencyByLottery(string currencyName, 
 | 
				
			||||||
            int value = 0, int balance = 0, string levelName = "", 
 | 
					            int value = 0, int balance = 0, string levelName = "", 
 | 
				
			||||||
            string scene = "store", string[] props = null, Dictionary<string, object> extra = null)
 | 
					            string scene = "store", string[] props = null, Dictionary<string, object> extra = null)
 | 
				
			||||||
| 
						 | 
					@ -840,12 +758,29 @@ namespace Guru
 | 
				
			||||||
        /// <param name="levelName">当前关卡或者人物等级名称</param>
 | 
					        /// <param name="levelName">当前关卡或者人物等级名称</param>
 | 
				
			||||||
        /// <param name="itemName">购买道具名称</param>
 | 
					        /// <param name="itemName">购买道具名称</param>
 | 
				
			||||||
        /// <param name="scene">购买场景如 Store, Workbench, Sign, Ads....</param>
 | 
					        /// <param name="scene">购买场景如 Store, Workbench, Sign, Ads....</param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogSpendVirtualCurrency(string currencyName, int value, int balance, string category = "", string itemName = "",
 | 
					        public static void LogSpendVirtualCurrency(string currencyName, int value, int balance, string category = "", string itemName = "",
 | 
				
			||||||
            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
					            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Analytics.SpendVirtualCurrency(currencyName, value, balance, category, itemName, levelName, scene, extra);
 | 
					            Analytics.SpendVirtualCurrency(currencyName, value, balance, category, itemName, levelName, scene, extra);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 消耗 Boost 道具
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="currencyName">货币/道具名称</param>
 | 
				
			||||||
 | 
					        /// <param name="value">货币消耗值 10</param>
 | 
				
			||||||
 | 
					        /// <param name="balance">结算后货币总量 30 -> 20</param>
 | 
				
			||||||
 | 
					        /// <param name="itemName"></param>
 | 
				
			||||||
 | 
					        /// <param name="levelName"></param>
 | 
				
			||||||
 | 
					        /// <param name="scene"></param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
 | 
					        public static void LogSpendVirtualCurrencyAsBoost(string currencyName, int value, int balance, string itemName = "",
 | 
				
			||||||
 | 
					            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            string category = Consts.CurrencyCategoryBoost;
 | 
				
			||||||
 | 
					            Analytics.SpendVirtualCurrency(currencyName, value, balance, category, itemName, levelName, scene, extra);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 消耗货币购买道具 (spend_virtual_currency) (props)
 | 
					        /// 消耗货币购买道具 (spend_virtual_currency) (props)
 | 
				
			||||||
| 
						 | 
					@ -856,11 +791,13 @@ namespace Guru
 | 
				
			||||||
        /// <param name="balance"></param>
 | 
					        /// <param name="balance"></param>
 | 
				
			||||||
        /// <param name="levelName"></param>
 | 
					        /// <param name="levelName"></param>
 | 
				
			||||||
        /// <param name="scene"></param>
 | 
					        /// <param name="scene"></param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogSpendVirtualCurrencyWithProp(string currencyName, string prop,
 | 
					        public static void LogSpendVirtualCurrencyWithProp(string currencyName, string prop,
 | 
				
			||||||
            int value, int balance,
 | 
					            int value, int balance,
 | 
				
			||||||
            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
					            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogSpendVirtualCurrencyWithProps(currencyName, new string[] {prop}, value, balance, levelName, scene, extra);
 | 
					            string category = Consts.CurrencyCategoryProp;
 | 
				
			||||||
 | 
					            LogSpendVirtualCurrency(currencyName, value, balance, category, prop, levelName, scene, extra); 
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -872,6 +809,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="balance"></param>
 | 
					        /// <param name="balance"></param>
 | 
				
			||||||
        /// <param name="levelName"></param>
 | 
					        /// <param name="levelName"></param>
 | 
				
			||||||
        /// <param name="scene"></param>
 | 
					        /// <param name="scene"></param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogSpendVirtualCurrencyWithProps(string currencyName, string[] props,
 | 
					        public static void LogSpendVirtualCurrencyWithProps(string currencyName, string[] props,
 | 
				
			||||||
            int value, int balance, 
 | 
					            int value, int balance, 
 | 
				
			||||||
            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
					            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
| 
						 | 
					@ -897,6 +835,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="balance"></param>
 | 
					        /// <param name="balance"></param>
 | 
				
			||||||
        /// <param name="levelName"></param>
 | 
					        /// <param name="levelName"></param>
 | 
				
			||||||
        /// <param name="scene"></param>
 | 
					        /// <param name="scene"></param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogSpendVirtualCurrencyWithBundle(string currencyName, string bundle,
 | 
					        public static void LogSpendVirtualCurrencyWithBundle(string currencyName, string bundle,
 | 
				
			||||||
            int value, int balance,
 | 
					            int value, int balance,
 | 
				
			||||||
            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
					            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
| 
						 | 
					@ -913,6 +852,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="balance"></param>
 | 
					        /// <param name="balance"></param>
 | 
				
			||||||
        /// <param name="levelName"></param>
 | 
					        /// <param name="levelName"></param>
 | 
				
			||||||
        /// <param name="scene"></param>
 | 
					        /// <param name="scene"></param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogSpendVirtualCurrencyWithBundles(string currencyName, string[] bundles,
 | 
					        public static void LogSpendVirtualCurrencyWithBundles(string currencyName, string[] bundles,
 | 
				
			||||||
            int value, int balance, 
 | 
					            int value, int balance, 
 | 
				
			||||||
            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
					            string levelName = "", string scene = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
| 
						 | 
					@ -932,12 +872,14 @@ namespace Guru
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 消耗物品, 交换其他物品 (spend_virtual_currency) (prop)
 | 
					        /// 消耗物品, 交换其他物品 (spend_virtual_currency) (prop)
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="currencyName"></param>
 | 
					        /// <param name="propName"></param>
 | 
				
			||||||
        /// <param name="bundles"></param>
 | 
					        /// <param name="otherName"></param>
 | 
				
			||||||
        /// <param name="value"></param>
 | 
					        /// <param name="value"></param>
 | 
				
			||||||
        /// <param name="balance"></param>
 | 
					        /// <param name="balance"></param>
 | 
				
			||||||
        /// <param name="levelName"></param>
 | 
					        /// <param name="levelName"></param>
 | 
				
			||||||
        /// <param name="scene"></param>
 | 
					        /// <param name="scene"></param>
 | 
				
			||||||
 | 
					        /// <param name="extraCategory"></param>
 | 
				
			||||||
 | 
					        /// <param name="extra"></param>
 | 
				
			||||||
        public static void LogSpendPropWithProp(string propName, string otherName,
 | 
					        public static void LogSpendPropWithProp(string propName, string otherName,
 | 
				
			||||||
            int value, int balance, 
 | 
					            int value, int balance, 
 | 
				
			||||||
            string levelName = "", string scene = "", string extraCategory = "", Dictionary<string, object> extra = null)
 | 
					            string levelName = "", string scene = "", string extraCategory = "", Dictionary<string, object> extra = null)
 | 
				
			||||||
| 
						 | 
					@ -1212,7 +1154,7 @@ namespace Guru
 | 
				
			||||||
            CrashlyticsAgent.Log(message);
 | 
					            CrashlyticsAgent.Log(message);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        public static void CrashException(string message)
 | 
					        public static void CrashLogException(string message)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!IsFirebaseReady) return;
 | 
					            if (!IsFirebaseReady) return;
 | 
				
			||||||
            CrashlyticsAgent.LogException(message);
 | 
					            CrashlyticsAgent.LogException(message);
 | 
				
			||||||
| 
						 | 
					@ -1224,7 +1166,7 @@ namespace Guru
 | 
				
			||||||
            CrashlyticsAgent.LogException(ex);
 | 
					            CrashlyticsAgent.LogException(ex);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static void CrashCustomKeys(string key, string value)
 | 
					        public static void CrashSetCustomKeys(string key, string value)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!IsFirebaseReady) return;
 | 
					            if (!IsFirebaseReady) return;
 | 
				
			||||||
            CrashlyticsAgent.SetCustomKey(key, value);
 | 
					            CrashlyticsAgent.SetCustomKey(key, value);
 | 
				
			||||||
| 
						 | 
					@ -1233,6 +1175,7 @@ namespace Guru
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #region 优先级设置
 | 
					        #region 优先级设置
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        private static readonly Dictionary<string, int> _eventPriorities = new Dictionary<string, int>(10);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 设置
 | 
					        /// 设置
 | 
				
			||||||
| 
						 | 
					@ -1241,22 +1184,13 @@ namespace Guru
 | 
				
			||||||
        /// <param name="eventNames"></param>
 | 
					        /// <param name="eventNames"></param>
 | 
				
			||||||
        public static void SetEventPriority(EventPriority priority, string[] eventNames)
 | 
					        public static void SetEventPriority(EventPriority priority, string[] eventNames)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!IsInitialSuccess)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                UnityEngine.Debug.LogError($"{Tag} :: LogEvent {priority} :: Please call <GuruSDK.Start()> first, before you call <LogEvent>.");
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (Model.event_priorities == null) Model.event_priorities = new Dictionary<string, int>(10);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            int i = 0;
 | 
					            int i = 0;
 | 
				
			||||||
            string evt = "";
 | 
					 | 
				
			||||||
            while (i < eventNames.Length)
 | 
					            while (i < eventNames.Length)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                evt = eventNames[i];
 | 
					                var evt = eventNames[i];
 | 
				
			||||||
                if (!string.IsNullOrEmpty(evt))
 | 
					                if (!string.IsNullOrEmpty(evt))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    Model.event_priorities[evt] = (int)priority;
 | 
					                    _eventPriorities[evt] = (int)priority;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                i++;
 | 
					                i++;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -1264,26 +1198,19 @@ namespace Guru
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static void SetEventPriority(EventPriority priority, string eventName)
 | 
					        public static void SetEventPriority(EventPriority priority, string eventName)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (!IsInitialSuccess)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                UnityEngine.Debug.LogError($"{Tag} :: LogEvent {priority} :: Please call <GuruSDK.Start()> first, before you call <LogEvent>.");
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            SetEventPriority(priority, new string[]{eventName});
 | 
					            SetEventPriority(priority, new string[]{eventName});
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static EventPriority GetEventPriority(string eventName)
 | 
					        public static EventPriority GetEventPriority(string eventName)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (Model.event_priorities != null 
 | 
					            if (_eventPriorities.TryGetValue(eventName, out int p))
 | 
				
			||||||
                && Model.event_priorities.TryGetValue(eventName, out int p))
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                return (EventPriority)p;
 | 
					                return (EventPriority)p;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return EventPriority.Default;
 | 
					            return EventPriority.Default;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal static int GetEventPriorityInt(string eventName)
 | 
					        public static int GetEventPriorityInt(string eventName)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return (int)GetEventPriority(eventName);
 | 
					            return (int)GetEventPriority(eventName);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -1291,7 +1218,7 @@ namespace Guru
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// set all events as 'Emergence' event, which will be triggered immediately
 | 
					        /// set all events as 'Emergence' event, which will be triggered immediately
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        internal void SetSDKEventPriority()
 | 
					        private void SetSDKEventPriority()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            SetEventPriority(EventPriority.Emergence, new []
 | 
					            SetEventPriority(EventPriority.Emergence, new []
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -1299,9 +1226,13 @@ namespace Guru
 | 
				
			||||||
                Consts.EventTchAdRev02Impression,
 | 
					                Consts.EventTchAdRev02Impression,
 | 
				
			||||||
                Consts.EventLevelStart,
 | 
					                Consts.EventLevelStart,
 | 
				
			||||||
                Consts.EventLevelEnd,
 | 
					                Consts.EventLevelEnd,
 | 
				
			||||||
 | 
					                Consts.EventIAPReturnTrue,
 | 
				
			||||||
 | 
					                Consts.EventIAPPurchase,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,241 +0,0 @@
 | 
				
			||||||
namespace Guru
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    using System;
 | 
					 | 
				
			||||||
    using UnityEngine;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    public partial class GuruSDK
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// 回调参数类
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        public class Callbacks
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            /// <summary>
 | 
					 | 
				
			||||||
            /// APP 事件
 | 
					 | 
				
			||||||
            /// </summary>
 | 
					 | 
				
			||||||
            public static class App
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                internal static Action<bool> _onAppPaused;
 | 
					 | 
				
			||||||
                public static event Action<bool> OnAppPaused
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onAppPaused += value;
 | 
					 | 
				
			||||||
                    remove => _onAppPaused -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action _onAppQuit;
 | 
					 | 
				
			||||||
                public static event Action OnAppQuit
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onAppQuit += value;
 | 
					 | 
				
			||||||
                    remove => _onAppQuit -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /// <summary>
 | 
					 | 
				
			||||||
            /// GDPR Consent
 | 
					 | 
				
			||||||
            /// </summary>
 | 
					 | 
				
			||||||
            public static class ConsentFlow
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                /// <summary>
 | 
					 | 
				
			||||||
                /// 当Consent启动结束后返回状态码
 | 
					 | 
				
			||||||
                /// </summary>
 | 
					 | 
				
			||||||
                public static event Action<int> OnConsentResult
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onConsentResult += value;
 | 
					 | 
				
			||||||
                    remove => _onConsentResult -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                internal static Action<int> _onConsentResult;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                /// <summary>
 | 
					 | 
				
			||||||
                /// ATT 状态返回
 | 
					 | 
				
			||||||
                /// </summary>
 | 
					 | 
				
			||||||
                public static event Action<int> OnAttResult
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onAttResult += value;
 | 
					 | 
				
			||||||
                    remove => _onAttResult -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                internal static Action<int> _onAttResult;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /// <summary>
 | 
					 | 
				
			||||||
            /// 广告回调
 | 
					 | 
				
			||||||
            /// </summary>
 | 
					 | 
				
			||||||
            public static class Ads
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                internal static Action _onAdsInitComplete;
 | 
					 | 
				
			||||||
                public static event Action OnAdsInitComplete
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onAdsInitComplete += value;
 | 
					 | 
				
			||||||
                    remove => _onAdsInitComplete -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action<string> _onBannerADStartLoad;
 | 
					 | 
				
			||||||
                public static event Action<string> OnBannerADStartLoad
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onBannerADStartLoad += value;
 | 
					 | 
				
			||||||
                    remove => _onBannerADStartLoad -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action _onBannerADLoaded;
 | 
					 | 
				
			||||||
                public static event Action OnBannerADLoaded
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onBannerADLoaded += value;
 | 
					 | 
				
			||||||
                    remove => _onBannerADLoaded -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action<string> _onInterstitialADStartLoad;
 | 
					 | 
				
			||||||
                public static event Action<string> OnInterstitialADStartLoad
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onInterstitialADStartLoad += value;
 | 
					 | 
				
			||||||
                    remove => _onInterstitialADStartLoad -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action _onInterstitialADLoaded;
 | 
					 | 
				
			||||||
                public static event Action OnInterstitialADLoaded
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onInterstitialADLoaded += value;
 | 
					 | 
				
			||||||
                    remove => _onInterstitialADLoaded -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                internal static Action _onInterstitialADFailed;
 | 
					 | 
				
			||||||
                public static event Action OnInterstitialADFailed
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onInterstitialADFailed += value;
 | 
					 | 
				
			||||||
                    remove => _onInterstitialADFailed -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                internal static Action<string> _onRewardedADStartLoad;
 | 
					 | 
				
			||||||
                public static event Action<string> OnRewardedADStartLoad
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onRewardedADStartLoad += value;
 | 
					 | 
				
			||||||
                    remove => _onRewardedADStartLoad -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action _onRewardedADLoaded;
 | 
					 | 
				
			||||||
                public static event Action OnRewardedADLoaded
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onRewardedADLoaded += value;
 | 
					 | 
				
			||||||
                    remove => _onRewardedADLoaded -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                internal static Action _onRewardADFailed;
 | 
					 | 
				
			||||||
                public static event Action OnRewardADFailed
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onRewardADFailed += value;
 | 
					 | 
				
			||||||
                    remove => _onRewardADFailed -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /// <summary>
 | 
					 | 
				
			||||||
            /// 云控参数
 | 
					 | 
				
			||||||
            /// </summary>
 | 
					 | 
				
			||||||
            public static class Remote
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                internal static Action<bool> _onRemoteFetchComplete;
 | 
					 | 
				
			||||||
                public static event Action<bool> OnRemoteFetchComplete
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onRemoteFetchComplete += value;
 | 
					 | 
				
			||||||
                    remove => _onRemoteFetchComplete -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /// <summary>
 | 
					 | 
				
			||||||
            /// 支付回调
 | 
					 | 
				
			||||||
            /// </summary>
 | 
					 | 
				
			||||||
            public static class IAP
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                internal static Action _onIAPInitStart;
 | 
					 | 
				
			||||||
                public static event Action OnIAPInitStart
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onIAPInitStart += value;
 | 
					 | 
				
			||||||
                    remove => _onIAPInitStart -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action<bool> _onIAPInitComplete;
 | 
					 | 
				
			||||||
                public static event Action<bool> OnIAPInitComplete
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onIAPInitComplete += value;
 | 
					 | 
				
			||||||
                    remove => _onIAPInitComplete -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action<string> _onPurchaseStart;
 | 
					 | 
				
			||||||
                public static event Action<string> OnPurchaseStart
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onPurchaseStart += value;
 | 
					 | 
				
			||||||
                    remove => _onPurchaseStart -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action<string, bool> _onPurchaseEnd;
 | 
					 | 
				
			||||||
                public static event Action<string, bool> OnPurchaseEnd
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onPurchaseEnd += value;
 | 
					 | 
				
			||||||
                    remove => _onPurchaseEnd -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action<string, string> _onPurchaseFailed;
 | 
					 | 
				
			||||||
                public static event Action<string, string> OnPurchaseFailed
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onPurchaseFailed += value;
 | 
					 | 
				
			||||||
                    remove => _onPurchaseFailed -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action<bool, string> _onIAPRestored;
 | 
					 | 
				
			||||||
                public static event Action<bool, string> OnIAPRestored
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onIAPRestored += value;
 | 
					 | 
				
			||||||
                    remove => _onIAPRestored -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            public static class SDK
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                internal static Action<bool> _onFirebaseReady;
 | 
					 | 
				
			||||||
                public static event Action<bool> OnFirebaseReady
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onFirebaseReady += value;
 | 
					 | 
				
			||||||
                    remove => _onFirebaseReady -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action _onGuruServiceReady;
 | 
					 | 
				
			||||||
                public static event Action OnGuruServiceReady
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onGuruServiceReady += value;
 | 
					 | 
				
			||||||
                    remove => _onGuruServiceReady -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                internal static Action<bool> _onDebuggerDisplayed;
 | 
					 | 
				
			||||||
                public static event Action<bool> OnDisplayDebugger
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onDebuggerDisplayed += value;
 | 
					 | 
				
			||||||
                    remove => _onDebuggerDisplayed -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                internal static Action<bool> _onUserAuthResult;
 | 
					 | 
				
			||||||
                public static event Action<bool> OnUserAuthResult
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onUserAuthResult += value;
 | 
					 | 
				
			||||||
                    remove => _onUserAuthResult -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                internal static Action<bool> _onFirebaseAuthResult;
 | 
					 | 
				
			||||||
                public static event Action<bool> OnFirebaseAuthResult
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    add => _onFirebaseAuthResult += value;
 | 
					 | 
				
			||||||
                    remove => _onFirebaseAuthResult -= value;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,378 @@
 | 
				
			||||||
 | 
					namespace Guru
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    using System;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    public partial class GuruSDK
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 回调参数类
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public class Callbacks
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /// <summary>
 | 
				
			||||||
 | 
					            /// APP 事件
 | 
				
			||||||
 | 
					            /// </summary>
 | 
				
			||||||
 | 
					            public static class App
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                private static Action<bool> _onAppPaused;
 | 
				
			||||||
 | 
					                public static event Action<bool> OnAppPaused
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onAppPaused += value;
 | 
				
			||||||
 | 
					                    remove => _onAppPaused -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnAppPaused(bool isPaused)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onAppPaused?.Invoke(isPaused);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action _onAppQuit;
 | 
				
			||||||
 | 
					                public static event Action OnAppQuit
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onAppQuit += value;
 | 
				
			||||||
 | 
					                    remove => _onAppQuit -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnAppQuit()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onAppQuit?.Invoke();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            /// <summary>
 | 
				
			||||||
 | 
					            /// GDPR Consent
 | 
				
			||||||
 | 
					            /// </summary>
 | 
				
			||||||
 | 
					            public static class ConsentFlow
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                /// <summary>
 | 
				
			||||||
 | 
					                /// 当Consent启动结束后返回状态码
 | 
				
			||||||
 | 
					                /// </summary>
 | 
				
			||||||
 | 
					                public static event Action<int> OnConsentResult
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onConsentResult += value;
 | 
				
			||||||
 | 
					                    remove => _onConsentResult -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                private static Action<int> _onConsentResult;
 | 
				
			||||||
 | 
					                internal static void InvokeOnConsentResult(int code)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onConsentResult?.Invoke(code);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                /// <summary>
 | 
				
			||||||
 | 
					                /// ATT 状态返回
 | 
				
			||||||
 | 
					                /// </summary>
 | 
				
			||||||
 | 
					                public static event Action<int> OnAttResult
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onAttResult += value;
 | 
				
			||||||
 | 
					                    remove => _onAttResult -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                private static Action<int> _onAttResult;
 | 
				
			||||||
 | 
					                internal static void InvokeOnAttResultCallback(int code)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onAttResult?.Invoke(code);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// <summary>
 | 
				
			||||||
 | 
					            /// 广告回调
 | 
				
			||||||
 | 
					            /// </summary>
 | 
				
			||||||
 | 
					            public static class Ads
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                private static Action _onAdsInitComplete;
 | 
				
			||||||
 | 
					                public static event Action OnAdsInitComplete
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onAdsInitComplete += value;
 | 
				
			||||||
 | 
					                    remove => _onAdsInitComplete -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnAdsInitComplete()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onAdsInitComplete?.Invoke();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                //------------ BANNER -----------------
 | 
				
			||||||
 | 
					                private static Action<string> _onBannerADStartLoad;
 | 
				
			||||||
 | 
					                public static event Action<string> OnBannerADStartLoad
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onBannerADStartLoad += value;
 | 
				
			||||||
 | 
					                    remove => _onBannerADStartLoad -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnBannerADStartLoad(string adUnitId)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onBannerADStartLoad?.Invoke(adUnitId);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                private static Action _onBannerADLoaded;
 | 
				
			||||||
 | 
					                public static event Action OnBannerADLoaded
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onBannerADLoaded += value;
 | 
				
			||||||
 | 
					                    remove => _onBannerADLoaded -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnBannerADLoaded()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onBannerADLoaded?.Invoke();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                //------------ INTER -----------------
 | 
				
			||||||
 | 
					                private static Action<string> _onInterstitialADStartLoad;
 | 
				
			||||||
 | 
					                public static event Action<string> OnInterstitialADStartLoad
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onInterstitialADStartLoad += value;
 | 
				
			||||||
 | 
					                    remove => _onInterstitialADStartLoad -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnInterstitialADStartLoad(string adUnitId)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onInterstitialADStartLoad?.Invoke(adUnitId);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action _onInterstitialADLoaded;
 | 
				
			||||||
 | 
					                public static event Action OnInterstitialADLoaded
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onInterstitialADLoaded += value;
 | 
				
			||||||
 | 
					                    remove => _onInterstitialADLoaded -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnInterstitialADLoaded()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onInterstitialADLoaded?.Invoke();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action _onInterstitialADFailed;
 | 
				
			||||||
 | 
					                public static event Action OnInterstitialADFailed
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onInterstitialADFailed += value;
 | 
				
			||||||
 | 
					                    remove => _onInterstitialADFailed -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnInterstitialADFailed()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onInterstitialADFailed?.Invoke();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action _onInterstitialADClosed;
 | 
				
			||||||
 | 
					                public static event Action OnInterstitialADClosed
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onInterstitialADClosed += value;
 | 
				
			||||||
 | 
					                    remove => _onInterstitialADClosed -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnInterstitialADClosed()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onInterstitialADClosed?.Invoke();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //------------ REWARD -----------------
 | 
				
			||||||
 | 
					                private static Action<string> _onRewardedADStartLoad;
 | 
				
			||||||
 | 
					                public static event Action<string> OnRewardedADStartLoad
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onRewardedADStartLoad += value;
 | 
				
			||||||
 | 
					                    remove => _onRewardedADStartLoad -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnRewardedADStartLoad(string adUnitId)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onRewardedADStartLoad?.Invoke(adUnitId);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action _onRewardedADLoaded;
 | 
				
			||||||
 | 
					                public static event Action OnRewardedADLoaded
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onRewardedADLoaded += value;
 | 
				
			||||||
 | 
					                    remove => _onRewardedADLoaded -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnRewardedADLoaded()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onRewardedADLoaded?.Invoke();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action _onRewardADClosed;
 | 
				
			||||||
 | 
					                public static event Action OnRewardedADClosed
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onRewardADClosed += value;
 | 
				
			||||||
 | 
					                    remove => _onRewardADClosed -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnRewardADClosed()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onRewardADClosed?.Invoke();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action _onRewardADFailed;
 | 
				
			||||||
 | 
					                public static event Action OnRewardADFailed
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onRewardADFailed += value;
 | 
				
			||||||
 | 
					                    remove => _onRewardADFailed -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnRewardADFailed()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onRewardADFailed?.Invoke();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// <summary>
 | 
				
			||||||
 | 
					            /// 云控参数
 | 
				
			||||||
 | 
					            /// </summary>
 | 
				
			||||||
 | 
					            public static class Remote
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                private static Action<bool> _onRemoteFetchComplete;
 | 
				
			||||||
 | 
					                public static event Action<bool> OnRemoteFetchComplete
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onRemoteFetchComplete += value;
 | 
				
			||||||
 | 
					                    remove => _onRemoteFetchComplete -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnRemoteFetchComplete(bool success)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onRemoteFetchComplete?.Invoke(success);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// <summary>
 | 
				
			||||||
 | 
					            /// 支付回调
 | 
				
			||||||
 | 
					            /// </summary>
 | 
				
			||||||
 | 
					            public static class IAP
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                private static Action _onIAPInitStart;
 | 
				
			||||||
 | 
					                public static event Action OnIAPInitStart
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onIAPInitStart += value;
 | 
				
			||||||
 | 
					                    remove => _onIAPInitStart -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnIAPInitStart()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onIAPInitStart?.Invoke();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action<bool> _onIAPInitComplete;
 | 
				
			||||||
 | 
					                public static event Action<bool> OnIAPInitComplete
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onIAPInitComplete += value;
 | 
				
			||||||
 | 
					                    remove => _onIAPInitComplete -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnIAPInitComplete(bool success)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onIAPInitComplete?.Invoke(success);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action<string> _onPurchaseStart;
 | 
				
			||||||
 | 
					                public static event Action<string> OnPurchaseStart
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onPurchaseStart += value;
 | 
				
			||||||
 | 
					                    remove => _onPurchaseStart -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnPurchaseStart(string productId)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onPurchaseStart?.Invoke(productId);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action<string, bool> _onPurchaseEnd;
 | 
				
			||||||
 | 
					                public static event Action<string, bool> OnPurchaseEnd
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onPurchaseEnd += value;
 | 
				
			||||||
 | 
					                    remove => _onPurchaseEnd -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnPurchaseEnd(string productId, bool success)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onPurchaseEnd?.Invoke(productId, success);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action<string, string> _onPurchaseFailed;
 | 
				
			||||||
 | 
					                public static event Action<string, string> OnPurchaseFailed
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onPurchaseFailed += value;
 | 
				
			||||||
 | 
					                    remove => _onPurchaseFailed -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnPurchaseFailed(string productId, string error)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onPurchaseFailed?.Invoke(productId, error);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					       
 | 
				
			||||||
 | 
					                private static Action<bool, string> _onIAPRestored;
 | 
				
			||||||
 | 
					                public static event Action<bool, string> OnIAPRestored
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onIAPRestored += value;
 | 
				
			||||||
 | 
					                    remove => _onIAPRestored -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnIAPRestored(bool success, string productId)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onIAPRestored?.Invoke(success, productId);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public static class SDK
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                private static Action<bool> _onFirebaseReady;
 | 
				
			||||||
 | 
					                public static event Action<bool> OnFirebaseReady
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onFirebaseReady += value;
 | 
				
			||||||
 | 
					                    remove => _onFirebaseReady -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnFirebaseReady(bool success)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onFirebaseReady?.Invoke(success);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action _onGuruServiceReady;
 | 
				
			||||||
 | 
					                public static event Action OnGuruServiceReady
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onGuruServiceReady += value;
 | 
				
			||||||
 | 
					                    remove => _onGuruServiceReady -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnGuruServiceReady()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onGuruServiceReady?.Invoke();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                private static Action<bool> _onDebuggerDisplayed;
 | 
				
			||||||
 | 
					                public static event Action<bool> OnDisplayDebugger
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onDebuggerDisplayed += value;
 | 
				
			||||||
 | 
					                    remove => _onDebuggerDisplayed -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnDebuggerDisplayed(bool success)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onDebuggerDisplayed?.Invoke(success);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                private static Action<bool> _onUserAuthResult;
 | 
				
			||||||
 | 
					                public static event Action<bool> OnGuruUserAuthResult
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onUserAuthResult += value;
 | 
				
			||||||
 | 
					                    remove => _onUserAuthResult -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnGuruUserAuthResult(bool success)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onUserAuthResult?.Invoke(success);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                // DeepLink 回调 
 | 
				
			||||||
 | 
					                private static Action<string> _onDeeplinkCallback;
 | 
				
			||||||
 | 
					                public static event Action<string> OnDeeplinkCallback
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onDeeplinkCallback += value;
 | 
				
			||||||
 | 
					                    remove => _onDeeplinkCallback -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeDeeplinkCallback(string deeplink)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onDeeplinkCallback?.Invoke(deeplink);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                // TODO: 之后需要添加 define 宏来控制是否可用
 | 
				
			||||||
 | 
					                // Firebase Auth 回调
 | 
				
			||||||
 | 
					                private static Action<bool, Firebase.Auth.FirebaseUser> _onFirebaseUserAuthResult;
 | 
				
			||||||
 | 
					                public static event Action<bool, Firebase.Auth.FirebaseUser> OnFirebaseUserAuthResult
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    add => _onFirebaseUserAuthResult += value;
 | 
				
			||||||
 | 
					                    remove => _onFirebaseUserAuthResult -= value;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                internal static void InvokeOnFirebaseAuthResult(bool success, Firebase.Auth.FirebaseUser firebaseUser = null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _onFirebaseUserAuthResult?.Invoke(success, firebaseUser);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2,16 +2,7 @@ namespace Guru
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public partial class GuruSDK
 | 
					    public partial class GuruSDK
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
	    /// <summary>
 | 
						    
 | 
				
			||||||
	    /// 打点优先级
 | 
					 | 
				
			||||||
	    /// </summary>
 | 
					 | 
				
			||||||
		public enum EventPriority
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Emergence = 0,
 | 
					 | 
				
			||||||
			High = 5,
 | 
					 | 
				
			||||||
			Default = 10,
 | 
					 | 
				
			||||||
			Low = 15
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Consts values
 | 
					        /// Consts values
 | 
				
			||||||
| 
						 | 
					@ -219,7 +210,7 @@ namespace Guru
 | 
				
			||||||
			public const string ATTOptIn = "att_opt_in";
 | 
								public const string ATTOptIn = "att_opt_in";
 | 
				
			||||||
			public const string ATTOpOut = "att_opt_out";
 | 
								public const string ATTOpOut = "att_opt_out";
 | 
				
			||||||
			public const string ParameterATTStatus = "att_status";
 | 
								public const string ParameterATTStatus = "att_status";
 | 
				
			||||||
			public const string EventATTResult = "att_result";
 | 
								public const string EventAttResult = "att_result";
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			// 用户属性
 | 
								// 用户属性
 | 
				
			||||||
			public const string PropertyFirstOpenTime = "first_open_time"; 		//用户第一次first_open的时间
 | 
								public const string PropertyFirstOpenTime = "first_open_time"; 		//用户第一次first_open的时间
 | 
				
			||||||
| 
						 | 
					@ -235,17 +226,19 @@ namespace Guru
 | 
				
			||||||
			public const string PropertyCoin = "coin"; //当前金币数
 | 
								public const string PropertyCoin = "coin"; //当前金币数
 | 
				
			||||||
			public const string PropertyExp = "exp"; // 经验值
 | 
								public const string PropertyExp = "exp"; // 经验值
 | 
				
			||||||
			public const string PropertyHp = "hp"; // 生命值/体力
 | 
								public const string PropertyHp = "hp"; // 生命值/体力
 | 
				
			||||||
 | 
								public const string PropertyNetwork = "network"; // 网络状态
 | 
				
			||||||
			public const string PropertyAndroidID = "android_id"; // Android 平台 AndroidID
 | 
								public const string PropertyAndroidID = "android_id"; // Android 平台 AndroidID
 | 
				
			||||||
			public const string PropertyIDFV = "idfv"; // iOS  平台 IDFV
 | 
								public const string PropertyIDFV = "idfv"; // iOS  平台 IDFV
 | 
				
			||||||
			public const string PropertyPicture = "picture"; // 玩家在主线的mapid
 | 
								public const string PropertyPicture = "picture"; // 玩家在主线的mapid
 | 
				
			||||||
			public const string PropertyNoAds = "no_ads"; // 玩家是否去广告
 | 
								public const string PropertyNoAds = "no_ads"; // 玩家是否去广告
 | 
				
			||||||
			public const string PropertyATTStatus = "att_status";  // ATT 状态
 | 
								public const string PropertyATTStatus = "att_status";  // ATT 状态
 | 
				
			||||||
			public const string PropertyNotiPerm = "noti_perm";  // Notification Permission 状态
 | 
								public const string PropertyNotiPerm = "noti_perm";  // Notification Permission 状态
 | 
				
			||||||
 | 
								public const string PropertyAdjustId = "adjust_id";  // AdjustId
 | 
				
			||||||
			public const string PropertyGDPR = "gdpr"; // GDPR状态
 | 
								public const string PropertyGDPR = "gdpr"; // GDPR状态
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			// 经济相关
 | 
								// 经济相关
 | 
				
			||||||
			public const string ParameterBalance = "balance"; // 用于余额
 | 
								public const string ParameterBalance = "balance"; // 用于余额
 | 
				
			||||||
			public const string ParameterDefaultScene = "ingame"; // 货币消费默认场景
 | 
								public const string ParameterDefaultScene = "in_game"; // 货币消费默认场景
 | 
				
			||||||
			public const string ParameterVirtualCurrencyName = "virtual_currency_name"; // 虚拟货币名称
 | 
								public const string ParameterVirtualCurrencyName = "virtual_currency_name"; // 虚拟货币名称
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
| 
						 | 
					@ -259,11 +252,28 @@ namespace Guru
 | 
				
			||||||
			public const string CurrencyCategoryProp = "prop"; // prop
 | 
								public const string CurrencyCategoryProp = "prop"; // prop
 | 
				
			||||||
			public const string CurrencyCategoryProps = "props"; // props
 | 
								public const string CurrencyCategoryProps = "props"; // props
 | 
				
			||||||
			public const string CurrencyCategoryBundle = "bundle"; // prop groups
 | 
								public const string CurrencyCategoryBundle = "bundle"; // prop groups
 | 
				
			||||||
			
 | 
								public const string CurrencyCategoryBoost = "boost"; // boost
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			// SDK 
 | 
								// SDK 
 | 
				
			||||||
			public const string EventSDKInfo = "sdk_info";
 | 
								public const string EventSDKInfo = "sdk_info";
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
 | 
								//----------------- 关卡开始类型 ---------------------
 | 
				
			||||||
 | 
								public const string EventLevelStartModePlay = "play";
 | 
				
			||||||
 | 
								public const string EventLevelStartModeReplay = "replay";
 | 
				
			||||||
 | 
								public const string EventLevelStartModeContinue= "continue";
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
								//----------------- 关卡结束类型 ---------------------
 | 
				
			||||||
 | 
								public const string EventLevelEndSuccess = "success";
 | 
				
			||||||
 | 
								public const string EventLevelEndFail = "fail";
 | 
				
			||||||
 | 
								public const string EventLevelEndExit = "exit";
 | 
				
			||||||
 | 
								public const string EventLevelEndTimeout = "timeout";
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								/// <summary>
 | 
				
			||||||
 | 
								/// 主线关卡类型
 | 
				
			||||||
 | 
								/// 只有传入此类型时才会进行 Blevel 的累加
 | 
				
			||||||
 | 
								/// </summary>
 | 
				
			||||||
 | 
								public const string LevelTypeMain = "main";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			#endregion
 | 
								#endregion
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,8 +7,6 @@ namespace Guru
 | 
				
			||||||
        private const string K_CMD_NAME_WATERMARK = "gurusdk.unity.wm";
 | 
					        private const string K_CMD_NAME_WATERMARK = "gurusdk.unity.wm";
 | 
				
			||||||
        private const string K_CMD_NAME_CONSOLE = "gurusdk.unity.con";
 | 
					        private const string K_CMD_NAME_CONSOLE = "gurusdk.unity.con";
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        #region Android 测试入口
 | 
					        #region Android 测试入口
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,8 +6,7 @@ namespace Guru
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    public partial class GuruSDK
 | 
					    public partial class GuruSDK
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private static bool _isDebuggerInited = false;
 | 
					        private static readonly bool _useBaseOptions = true;
 | 
				
			||||||
        private static bool _useBaseOpions = true;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static GuruDebugger _debugger;
 | 
					        private static GuruDebugger _debugger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +17,7 @@ namespace Guru
 | 
				
			||||||
                if (_debugger == null)
 | 
					                if (_debugger == null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    _debugger = GuruDebugger.Instance;
 | 
					                    _debugger = GuruDebugger.Instance;
 | 
				
			||||||
                    if (_useBaseOpions)
 | 
					                    if (_useBaseOptions)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        InitDebuggerLayout();
 | 
					                        InitDebuggerLayout();
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
| 
						 | 
					@ -27,7 +26,6 @@ namespace Guru
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 显示广告状态
 | 
					        /// 显示广告状态
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
| 
						 | 
					@ -39,8 +37,6 @@ namespace Guru
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 显示 Debugger
 | 
					        /// 显示 Debugger
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
| 
						 | 
					@ -98,17 +94,15 @@ namespace Guru
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            GuruDebugger.OnClosed -= OnDebuggerClosed;
 | 
					            GuruDebugger.OnClosed -= OnDebuggerClosed;
 | 
				
			||||||
            GuruDebugger.OnClosed += OnDebuggerClosed;
 | 
					            GuruDebugger.OnClosed += OnDebuggerClosed;
 | 
				
			||||||
            Callbacks.SDK._onDebuggerDisplayed?.Invoke(true);
 | 
					            Callbacks.SDK.InvokeOnDebuggerDisplayed(true);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        private static void OnDebuggerClosed()
 | 
					        private static void OnDebuggerClosed()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            GuruDebugger.OnClosed -= OnDebuggerClosed;
 | 
					            GuruDebugger.OnClosed -= OnDebuggerClosed;
 | 
				
			||||||
            Callbacks.SDK._onDebuggerDisplayed?.Invoke(false);
 | 
					            Callbacks.SDK.InvokeOnDebuggerDisplayed(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 显示 Debugger
 | 
					        /// 显示 Debugger
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
namespace Guru
 | 
					namespace Guru
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using UnityEngine;
 | 
					 | 
				
			||||||
    using System;
 | 
					    using System;
 | 
				
			||||||
    using System.Linq;
 | 
					    using System.Linq;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -32,7 +31,7 @@ namespace Guru
 | 
				
			||||||
            GuruIAP.Instance.OnBuyFailed += OnBuyFailed;
 | 
					            GuruIAP.Instance.OnBuyFailed += OnBuyFailed;
 | 
				
			||||||
            GuruIAP.Instance.OnGetProductReceipt += OnGetReceipt;
 | 
					            GuruIAP.Instance.OnGetProductReceipt += OnGetReceipt;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            Callbacks.IAP._onIAPInitStart?.Invoke(); // 初始化之前进行调用
 | 
					            Callbacks.IAP.InvokeOnIAPInitStart(); // 初始化之前进行调用
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            GuruIAP.Instance.InitWithKeys(uid, googleKey, appleRootCerts, IsDebugMode);
 | 
					            GuruIAP.Instance.InitWithKeys(uid, googleKey, appleRootCerts, IsDebugMode);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -45,7 +44,7 @@ namespace Guru
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogI($"IAP init result: {success}");
 | 
					            LogI($"IAP init result: {success}");
 | 
				
			||||||
            IsIAPReady = success;
 | 
					            IsIAPReady = success;
 | 
				
			||||||
            Callbacks.IAP._onIAPInitComplete?.Invoke(success);
 | 
					            Callbacks.IAP.InvokeOnIAPInitComplete(success);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static bool CheckIAPReady()
 | 
					        private static bool CheckIAPReady()
 | 
				
			||||||
| 
						 | 
					@ -70,7 +69,7 @@ namespace Guru
 | 
				
			||||||
        /// <returns></returns>
 | 
					        /// <returns></returns>
 | 
				
			||||||
        public static ProductInfo GetProductInfo(string productName)
 | 
					        public static ProductInfo GetProductInfo(string productName)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return GuruIAP.Instance?.GetInfo(productName) ?? null;
 | 
					            return GuruIAP.Instance?.GetInfo(productName);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -80,7 +79,7 @@ namespace Guru
 | 
				
			||||||
        /// <returns></returns>
 | 
					        /// <returns></returns>
 | 
				
			||||||
        public static ProductInfo GetProductInfoById(string productId)
 | 
					        public static ProductInfo GetProductInfoById(string productId)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return GuruIAP.Instance?.GetInfoById(productId) ?? null;
 | 
					            return GuruIAP.Instance?.GetInfoById(productId);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					@ -127,7 +126,7 @@ namespace Guru
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #region Purchase
 | 
					        #region Purchase
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private static Action<string, bool> _onPurchaseCallback;
 | 
					        private static Action<string, bool> InvokeOnPurchaseCallback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 老接口, 将会被废弃
 | 
					        /// 老接口, 将会被废弃
 | 
				
			||||||
| 
						 | 
					@ -150,7 +149,7 @@ namespace Guru
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (CheckIAPReady())
 | 
					            if (CheckIAPReady())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                _onPurchaseCallback = purchaseCallback;
 | 
					                InvokeOnPurchaseCallback = purchaseCallback;
 | 
				
			||||||
                GuruIAP.Instance.Buy(productName, category);
 | 
					                GuruIAP.Instance.Buy(productName, category);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -181,9 +180,8 @@ namespace Guru
 | 
				
			||||||
        /// <param name="success"></param>
 | 
					        /// <param name="success"></param>
 | 
				
			||||||
        private static void OnBuyEnd(string productName, bool success)
 | 
					        private static void OnBuyEnd(string productName, bool success)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (success) Model.PurchasedCount++;
 | 
					            InvokeOnPurchaseCallback?.Invoke(productName, success);
 | 
				
			||||||
            _onPurchaseCallback?.Invoke(productName, success);
 | 
					            Callbacks.IAP.InvokeOnPurchaseEnd(productName, success);
 | 
				
			||||||
            Callbacks.IAP._onPurchaseEnd?.Invoke(productName, success);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -192,7 +190,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="productName"></param>
 | 
					        /// <param name="productName"></param>
 | 
				
			||||||
        private static void OnBuyStart(string productName)
 | 
					        private static void OnBuyStart(string productName)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Callbacks.IAP._onPurchaseStart?.Invoke(productName);
 | 
					            Callbacks.IAP.InvokeOnPurchaseStart(productName);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -202,7 +200,7 @@ namespace Guru
 | 
				
			||||||
        /// <param name="reason"></param>
 | 
					        /// <param name="reason"></param>
 | 
				
			||||||
        private static void OnBuyFailed(string productName, string reason)
 | 
					        private static void OnBuyFailed(string productName, string reason)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Callbacks.IAP._onPurchaseFailed?.Invoke(productName, reason);
 | 
					            Callbacks.IAP.InvokeOnPurchaseFailed(productName, reason);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
| 
						 | 
					@ -223,7 +221,7 @@ namespace Guru
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        private static void OnRestored(bool success, string msg)
 | 
					        private static void OnRestored(bool success, string msg)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Callbacks.IAP._onIAPRestored?.Invoke(success, msg); // 更新回复购买回调
 | 
					            Callbacks.IAP.InvokeOnIAPRestored(success, msg); // 更新回复购买回调
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,4 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Guru
 | 
					namespace Guru
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public partial class GuruSDK
 | 
					    public partial class GuruSDK
 | 
				
			||||||
| 
						 | 
					@ -75,29 +76,30 @@ namespace Guru
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Model.IsNoAds = value;
 | 
					            Model.IsNoAds = value;
 | 
				
			||||||
            ADService.Instance.IsBuyNoAds = value;
 | 
					            ADService.Instance.IsBuyNoAds = value;
 | 
				
			||||||
            SetUserProperty(Consts.PropertyNoAds, value? "true" : "false");
 | 
					            if (value)
 | 
				
			||||||
            if(value) SetUserIsIAP(true);
 | 
					            {
 | 
				
			||||||
 | 
					                Analytics.SetIsIapUser(true);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 所有成功的主线关卡数量 (b_level)
 | 
					        /// 所有成功的主线关卡数量 (b_level)
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        public static int SuccessLevelCount
 | 
					        public static int BLevel
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            get => GuruSDKModel.Instance.SuccessLevelId;
 | 
					            get => GuruSDKModel.Instance.BLevel;
 | 
				
			||||||
            set => GuruSDKModel.Instance.SuccessLevelId = value;
 | 
					            set => GuruSDKModel.Instance.BLevel = value;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 成功关卡总计数量 (b_play)
 | 
					        /// 成功关卡总计数量 (b_play)
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        public static int TotalPlayedCount
 | 
					        public static int BPlay
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            get => GuruSDKModel.Instance.TotalPlayedCount;
 | 
					            get => GuruSDKModel.Instance.BPlay;
 | 
				
			||||||
            set => GuruSDKModel.Instance.TotalPlayedCount = value;
 | 
					            set => GuruSDKModel.Instance.BPlay = value;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,19 +38,37 @@ namespace Guru
 | 
				
			||||||
        public static bool GetRemoteBool(string key, bool defaultValue = false) => RemoteConfigManager.GetBool(key, defaultValue);
 | 
					        public static bool GetRemoteBool(string key, bool defaultValue = false) => RemoteConfigManager.GetBool(key, defaultValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 注册监听某个 Key 的变化
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="key"></param>
 | 
				
			||||||
 | 
					        /// <param name="onValueChanged"></param>
 | 
				
			||||||
        public static void RegisterOnValueChanged(string key, Action<string,string> onValueChanged)
 | 
					        public static void RegisterOnValueChanged(string key, Action<string,string> onValueChanged)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            RemoteConfigManager.RegisterOnValueChanged(key, onValueChanged);
 | 
					            RemoteConfigManager.RegisterOnValueChanged(key, onValueChanged);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 注销监听某个 Key 的变化
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="key"></param>
 | 
				
			||||||
 | 
					        /// <param name="onValueChanged"></param>
 | 
				
			||||||
        public static void UnRegisterOnValueChanged(string key, Action<string,string> onValueChanged)
 | 
					        public static void UnRegisterOnValueChanged(string key, Action<string,string> onValueChanged)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            RemoteConfigManager.UnRegisterOnValueChanged(key, onValueChanged);
 | 
					            RemoteConfigManager.UnRegisterOnValueChanged(key, onValueChanged);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 获取所有云控配置
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
        public static Dictionary<string, ConfigValue> GetRemoteAllValues() => RemoteConfigManager.GetAllValues();
 | 
					        public static Dictionary<string, ConfigValue> GetRemoteAllValues() => RemoteConfigManager.GetAllValues();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="key"></param>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
        public static string GetRemoteStaticValue(string key) => RemoteConfigManager.GetStaticValue(key);
 | 
					        public static string GetRemoteStaticValue(string key) => RemoteConfigManager.GetStaticValue(key);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,6 @@
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using UnityEngine;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Guru
 | 
					namespace Guru
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public partial class GuruSDK
 | 
					    public partial class GuruSDK
 | 
				
			||||||
| 
						 | 
					@ -41,5 +44,54 @@ namespace Guru
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        #region Android System
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if UNITY_ANDROID
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 获取 AndroidSDK 的系统版本号
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        public static int GetAndroidSystemVersion()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // sdkInt 是 Android SDK 的整数版本号,例如 Android 10 对应 29。
 | 
				
			||||||
 | 
					                // release 是 Android 版本的字符串表示,例如 "10"。
 | 
				
			||||||
 | 
					                using (AndroidJavaClass jc = new AndroidJavaClass("android.os.Build$VERSION"))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    int sdkInt = jc.GetStatic<int>("SDK_INT");
 | 
				
			||||||
 | 
					                    Debug.LogWarning($"[SDK] --- Android SDK Version:{sdkInt}");
 | 
				
			||||||
 | 
					                    return sdkInt;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Debug.LogError(ex);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region Clear Data Cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 清除数据缓存
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public static void ClearData()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Model.ClearData();
 | 
				
			||||||
 | 
					            GuruIAP.Instance.ClearData();
 | 
				
			||||||
 | 
					            PlayerPrefs.DeleteAll();
 | 
				
			||||||
 | 
					            PlayerPrefs.Save();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4,14 +4,17 @@ namespace Guru
 | 
				
			||||||
    using System;
 | 
					    using System;
 | 
				
			||||||
    using System.Collections;
 | 
					    using System.Collections;
 | 
				
			||||||
    using System.Collections.Generic;
 | 
					    using System.Collections.Generic;
 | 
				
			||||||
    using System.IO;
 | 
					 | 
				
			||||||
    using Debug = UnityEngine.Debug;
 | 
					    using Debug = UnityEngine.Debug;
 | 
				
			||||||
 | 
					    using Guru.Network;
 | 
				
			||||||
 | 
					    using System.Linq;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    public partial class GuruSDK: MonoBehaviour
 | 
					    public partial class GuruSDK: MonoBehaviour
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        // SDK_VERSION
 | 
				
			||||||
 | 
					        public const string Version = "1.1.0"; 
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        public const string Version = "1.0.12"; //SDK_VERSION
 | 
					        // Const
 | 
				
			||||||
        public const string Tag = "[Guru]";
 | 
					        private const string Tag = "[Guru]";
 | 
				
			||||||
        public const string ServicesConfigKey = "guru_services";
 | 
					        public const string ServicesConfigKey = "guru_services";
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private static GuruSDK _instance;
 | 
					        private static GuruSDK _instance;
 | 
				
			||||||
| 
						 | 
					@ -32,10 +35,9 @@ namespace Guru
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private GuruSDKInitConfig _initConfig;
 | 
					        private GuruSDKInitConfig _initConfig;
 | 
				
			||||||
        private Action<bool> _onCompleteCallback;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal static GuruSDKInitConfig InitConfig => Instance._initConfig;
 | 
					        private static GuruSDKInitConfig InitConfig => Instance._initConfig;
 | 
				
			||||||
        internal static GuruSDKModel Model => GuruSDKModel.Instance;
 | 
					        private static GuruSDKModel Model => GuruSDKModel.Instance;
 | 
				
			||||||
        private static GuruServicesConfig _appServicesConfig;
 | 
					        private static GuruServicesConfig _appServicesConfig;
 | 
				
			||||||
        private static GuruSettings _guruSettings;
 | 
					        private static GuruSettings _guruSettings;
 | 
				
			||||||
        private static GuruSettings GuruSettings
 | 
					        private static GuruSettings GuruSettings
 | 
				
			||||||
| 
						 | 
					@ -76,6 +78,12 @@ namespace Guru
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        public static bool IsServiceReady { get; private set; } = false;
 | 
					        public static bool IsServiceReady { get; private set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private Firebase.Auth.FirebaseUser _firebaseUser;
 | 
				
			||||||
 | 
					        [Obsolete("获取 FirebaseUser 的属性接口即将废弃,请改用 <GuruSDK.Callbacks.SDK.OnFirebaseUserAuthResult += OnMyGetFirebaseUserCallback> 来异步获取该属性")]
 | 
				
			||||||
 | 
					        public static Firebase.Auth.FirebaseUser FirebaseUser => Instance?._firebaseUser ?? null; 
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        #region 初始化
 | 
					        #region 初始化
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private static GuruSDK CreateInstance()
 | 
					        private static GuruSDK CreateInstance()
 | 
				
			||||||
| 
						 | 
					@ -86,48 +94,21 @@ namespace Guru
 | 
				
			||||||
            return _instance;
 | 
					            return _instance;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        public static GuruSDKInitConfig BuildConfig(
 | 
					        // TODO : 下个版本需要将 整个 GuruSDK 做功能性的拆分
 | 
				
			||||||
            bool useCustomConsent = false, 
 | 
					 | 
				
			||||||
            bool autoLoadAds = true, 
 | 
					 | 
				
			||||||
            bool iapEnabled = true, 
 | 
					 | 
				
			||||||
            bool autoRecordFinishedLevels = true, 
 | 
					 | 
				
			||||||
            bool debugMode = false,
 | 
					 | 
				
			||||||
            bool isBuyNoAds = false,
 | 
					 | 
				
			||||||
            string bannerColor = "#00000000",
 | 
					 | 
				
			||||||
            Dictionary<string, object> defaultRemoteData = null,
 | 
					 | 
				
			||||||
            byte[] googleKeys = null,
 | 
					 | 
				
			||||||
            byte[] appleRootCerts = null)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            var config = GuruSDKInitConfig.Build(useCustomConsent, autoLoadAds, iapEnabled, 
 | 
					 | 
				
			||||||
                autoRecordFinishedLevels, isBuyNoAds, bannerColor,
 | 
					 | 
				
			||||||
                debugMode, defaultRemoteData, googleKeys, appleRootCerts);
 | 
					 | 
				
			||||||
            return config;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        public static void Init(Action<bool> onComplete)
 | 
					        public static void Init(Action<bool> onComplete)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Init(GuruSDKInitConfig.Build(), onComplete);
 | 
					            Init(GuruSDKInitConfig.Builder().Build(), onComplete);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        public static void Init(GuruSDKInitConfig config, Action<bool> onComplete)
 | 
					        public static void Init(GuruSDKInitConfig config, Action<bool> onComplete)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _initTime = DateTime.Now.ToUniversalTime();
 | 
					            _initTime = DateTime.UtcNow;
 | 
				
			||||||
            // ----- First Open Time -----
 | 
					            // ----- First Open Time -----
 | 
				
			||||||
            // SetFirstOpenTime(GetFirstOpenTime());  // FirstOpenTime 
 | 
					            // SetFirstOpenTime(GetFirstOpenTime());  // FirstOpenTime 
 | 
				
			||||||
            LogI($"#1 ---- Guru SDK [{Version}] ----\n{config.ToString()}");
 | 
					            LogI($"#1 ---- Guru SDK [{Version}] ----\n{config}");
 | 
				
			||||||
            Instance.StartWithConfig(config, onComplete);
 | 
					            Instance.StartWithConfig(config, onComplete);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        private static string GetFirstOpenTime()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            string firstOpenTime = IPMConfig.FirstOpenTime;
 | 
					 | 
				
			||||||
            if (string.IsNullOrEmpty(firstOpenTime))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                firstOpenTime = TimeUtil.GetCurrentTimeStamp().ToString();
 | 
					 | 
				
			||||||
                IPMConfig.FirstOpenTime = firstOpenTime;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return firstOpenTime;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 启动SDK
 | 
					        /// 启动SDK
 | 
				
			||||||
| 
						 | 
					@ -136,116 +117,57 @@ namespace Guru
 | 
				
			||||||
        /// <param name="onComplete"></param>
 | 
					        /// <param name="onComplete"></param>
 | 
				
			||||||
        private void StartWithConfig(GuruSDKInitConfig config, Action<bool> onComplete)
 | 
					        private void StartWithConfig(GuruSDKInitConfig config, Action<bool> onComplete)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Model.PropBLevel.OnValueChanged += OnBLevelChanged;
 | 
					 | 
				
			||||||
            Model.PropBPlay.OnValueChanged += OnBPlayChanged;
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            IsInitialSuccess = false;
 | 
					            IsInitialSuccess = false;
 | 
				
			||||||
            _initConfig = config;
 | 
					            _initConfig = config;
 | 
				
			||||||
            _onCompleteCallback = onComplete;
 | 
					 | 
				
			||||||
            _isDebugEnabled = config.DebugMode;
 | 
					            _isDebugEnabled = config.DebugMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            InitAssets();
 | 
					            if (config.EnableDebugLogEvent) Analytics.EnableDebugAnalytics = true; // 允许 Debug 模式下打点
 | 
				
			||||||
        }
 | 
					            if (!config.AutoNotificationPermission) FirebaseUtil.SetAutoFetchFcmToken(false); // 不允许自动启动获取 FCM Token
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					 | 
				
			||||||
        private void InitAssets()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            InitUpdaters(); // Updaters
 | 
					            InitUpdaters(); // Updaters
 | 
				
			||||||
            InitThreadHandler(); // 初始化线程处理器
 | 
					            InitThreadHandler(); // 初始化线程处理器
 | 
				
			||||||
 | 
					            InitServices(); // 初始化所有的服务
 | 
				
			||||||
 | 
					            InitNetworkMonitor(); // 网络状态
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            onComplete?.Invoke(true);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void InitServices()
 | 
				
			||||||
        void Start()
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            //---------- Start Analytics ------------
 | 
				
			||||||
 | 
					            LogI($"#1.1 ---- Init Analytics ----");
 | 
				
			||||||
 | 
					            // 初始化打点类
 | 
				
			||||||
 | 
					            Analytics.Init(); 
 | 
				
			||||||
 | 
					            // 从 Model 中注入打点属性初始值
 | 
				
			||||||
 | 
					            Analytics.SetFirstOpenTime(IPMConfig.FIRST_OPEN_TIME);
 | 
				
			||||||
 | 
					            Analytics.SetIsIapUser(Model.IsIapUser);
 | 
				
			||||||
 | 
					            // Analytics.SetBLevel(Model.BLevel);
 | 
				
			||||||
 | 
					            // Analytics.SetBPlay(Model.BPlay);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            //---- Start All tools ----
 | 
					            //---- Start All tools ----
 | 
				
			||||||
            LogI($"#2 --- InitFirebase ---");
 | 
					            LogI($"#2 --- InitFirebase ---");
 | 
				
			||||||
            //---------- Start Firebase ------------
 | 
					            //---------- Start Firebase ------------
 | 
				
			||||||
            FirebaseUtil.onInitComplete += OnFirebaseReady;
 | 
					            StartFirebaseService();
 | 
				
			||||||
            FirebaseUtil.OnUserAuthResult += OnUserAuthResult;
 | 
					 | 
				
			||||||
            FirebaseUtil.OnFirebaseAuthResult += OnFirebaseAuthResult;
 | 
					 | 
				
			||||||
            FirebaseUtil.InitFirebase(null); // 确保所有的逻辑提前被调用到
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            LogI($"#2.1 --- InitFacebook ---");
 | 
					            LogI($"#2.1 --- InitFacebook ---");
 | 
				
			||||||
            //---------- Start Facebook ------------
 | 
					            //---------- Start Facebook ------------
 | 
				
			||||||
            FBService.Instance.StartService();
 | 
					            FBService.Instance.StartService(Analytics.OnFBInitComplete);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            LogI($"#2.2 --- Call SDK init complete  ->  callback: { (_onCompleteCallback == null ? "Null" : _onCompleteCallback.ToString()) } ---");
 | 
					 | 
				
			||||||
            IsInitialSuccess = true;
 | 
					            IsInitialSuccess = true;
 | 
				
			||||||
            _onCompleteCallback?.Invoke(true);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private void OnUserAuthResult(bool success)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            if (success && string.IsNullOrEmpty(IPMConfig.IPM_UID))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                success = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Callbacks.SDK._onUserAuthResult?.Invoke(success);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (success)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Model.UserId = IPMConfig.IPM_UID;
 | 
					 | 
				
			||||||
                if (GuruIAP.Instance != null)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    GuruIAP.Instance.SetUID(UID);
 | 
					 | 
				
			||||||
                    GuruIAP.Instance.SetUUID(UUID);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                UpdateAllUserProperties(); // 同步所有用户属性打点
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        private void OnFirebaseAuthResult(bool success)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Callbacks.SDK._onFirebaseAuthResult?.Invoke(success);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					 | 
				
			||||||
        /// 开始各种组件初始化
 | 
					 | 
				
			||||||
        /// </summary>
 | 
					 | 
				
			||||||
        private void OnFirebaseReady(bool success)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            FirebaseUtil.onInitComplete -= OnFirebaseReady;
 | 
					 | 
				
			||||||
            LogI($"#3 --- On FirebaseDeps:{success} ---");
 | 
					 | 
				
			||||||
            IsFirebaseReady = success;
 | 
					 | 
				
			||||||
            Callbacks.SDK._onFirebaseReady?.Invoke(success);
 | 
					 | 
				
			||||||
            // LogFirebaseDeps(success);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            LogI($"#3.5 --- Call InitRemoteConfig ---");
 | 
					 | 
				
			||||||
            // 开始Remote Manager初始化 
 | 
					 | 
				
			||||||
            RemoteConfigManager.Init(BuildDefaultRemoteData(_initConfig.DefaultRemoteData));
 | 
					 | 
				
			||||||
            RemoteConfigManager.OnFetchCompleted += OnFetchRemoteCallback;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            LogI($"#4 --- Apply remote services config ---");
 | 
					 | 
				
			||||||
            // 根据缓存的云控配置来初始化参数
 | 
					 | 
				
			||||||
            InitAllServices();
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            LogI($"#5 --- sync sdk time ---");
 | 
					 | 
				
			||||||
            var sp = DateTime.Now.ToUniversalTime() - _initTime;
 | 
					 | 
				
			||||||
            LogSDKInitTime(sp.TotalSeconds);
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            // 上报所有初始化用户属性
 | 
					 | 
				
			||||||
            UpdateAllUserProperties();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 注入云控参数基础数据
 | 
					        /// 注入云控参数基础数据
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        /// <param name="dict"></param>
 | 
					 | 
				
			||||||
        /// <returns></returns>
 | 
					        /// <returns></returns>
 | 
				
			||||||
        private Dictionary<string, object> BuildDefaultRemoteData(Dictionary<string, object> dict)
 | 
					        private string LoadDefaultGuruServiceJson()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (dict == null) dict = new Dictionary<string, object>(3);
 | 
					            // 加载本地 Services 配置值
 | 
				
			||||||
            
 | 
					            var txtAsset = Resources.Load<TextAsset>(ServicesConfigKey);
 | 
				
			||||||
            // 注入默认的 Services 配置值
 | 
					            if (txtAsset != null)
 | 
				
			||||||
            string json = Model.LoadDefaltServicesConfigJson(); 
 | 
					            {
 | 
				
			||||||
            if (!string.IsNullOrEmpty(json)) dict[ServicesConfigKey] = json;
 | 
					                return txtAsset.text;
 | 
				
			||||||
       
 | 
					            }
 | 
				
			||||||
            return dict;
 | 
					            return "";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -256,11 +178,9 @@ namespace Guru
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogI($"#6 --- Remote fetch complete: {success} ---");
 | 
					            LogI($"#6 --- Remote fetch complete: {success} ---");
 | 
				
			||||||
            ABTestManager.Init(); // 启动AB测试解析器
 | 
					            ABTestManager.Init(); // 启动AB测试解析器
 | 
				
			||||||
            Callbacks.Remote._onRemoteFetchComplete?.Invoke(success);
 | 
					            Callbacks.Remote.InvokeOnRemoteFetchComplete(success);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private void Update()
 | 
					        private void Update()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            UpdateAllUpdates(); // 驱动所有的更新器
 | 
					            UpdateAllUpdates(); // 驱动所有的更新器
 | 
				
			||||||
| 
						 | 
					@ -274,16 +194,17 @@ namespace Guru
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Apply Cloud guru-service configs for sdk assets
 | 
					        /// Apply Cloud guru-service configs for sdk assets
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        private void InitAllServices()
 | 
					        private void InitAllGuruServices()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            //-------- Init Analytics ---------
 | 
					            // -------- Init Analytics ---------
 | 
				
			||||||
            InitUserProperties();
 | 
					 | 
				
			||||||
            SetSDKEventPriority();
 | 
					            SetSDKEventPriority();
 | 
				
			||||||
 | 
					            // -------- Init Notification -----------
 | 
				
			||||||
 | 
					            InitNotiPermission();
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            bool useKeywords = false;
 | 
					            bool useKeywords = false;
 | 
				
			||||||
            bool useIAP = _initConfig.IAPEnabled;
 | 
					            bool useIAP = _initConfig.IAPEnabled;
 | 
				
			||||||
            bool appleReview = false;
 | 
					            bool appleReview = false;
 | 
				
			||||||
            bool enableAnaErrorLog = false;
 | 
					            // bool enableAnaErrorLog = false;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            //----------- Set GuruServices ----------------
 | 
					            //----------- Set GuruServices ----------------
 | 
				
			||||||
            var services = GetRemoteServicesConfig();
 | 
					            var services = GetRemoteServicesConfig();
 | 
				
			||||||
| 
						 | 
					@ -293,7 +214,7 @@ namespace Guru
 | 
				
			||||||
                useKeywords = _appServicesConfig.KeywordsEnabled();
 | 
					                useKeywords = _appServicesConfig.KeywordsEnabled();
 | 
				
			||||||
                // 使用初始化配置中的 IAPEnable来联合限定, 如果本地写死关闭则不走云控开启
 | 
					                // 使用初始化配置中的 IAPEnable来联合限定, 如果本地写死关闭则不走云控开启
 | 
				
			||||||
                useIAP = _initConfig.IAPEnabled && _appServicesConfig.IsIAPEnabled(); 
 | 
					                useIAP = _initConfig.IAPEnabled && _appServicesConfig.IsIAPEnabled(); 
 | 
				
			||||||
                enableAnaErrorLog = _appServicesConfig.EnableAnaErrorLog();
 | 
					                // enableAnaErrorLog = _appServicesConfig.EnableAnaErrorLog();
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                Try(() =>
 | 
					                Try(() =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					@ -301,7 +222,7 @@ namespace Guru
 | 
				
			||||||
                    //----------------------------------------------------------------
 | 
					                    //----------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // 自打点设置错误上报
 | 
					                    // 自打点设置错误上报
 | 
				
			||||||
                    if(enableAnaErrorLog) GuruAnalytics.EnableErrorLog = true;
 | 
					                    // if(enableAnaErrorLog) GuruAnalytics.EnableErrorLog = true;
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    // adjust 事件设置
 | 
					                    // adjust 事件设置
 | 
				
			||||||
                    if (null != _appServicesConfig.adjust_settings && null != GuruSettings)
 | 
					                    if (null != _appServicesConfig.adjust_settings && null != GuruSettings)
 | 
				
			||||||
| 
						 | 
					@ -314,7 +235,7 @@ namespace Guru
 | 
				
			||||||
                        GuruSettings.UpdateAdjustEvents(_appServicesConfig.adjust_settings.events);
 | 
					                        GuruSettings.UpdateAdjustEvents(_appServicesConfig.adjust_settings.events);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                    LogI($"#4.2 --- Start GuruSttings ---");
 | 
					                    LogI($"#4.2 --- Start GuruSettings ---");
 | 
				
			||||||
                    // GuruSettings 设置
 | 
					                    // GuruSettings 设置
 | 
				
			||||||
                    if (null != _appServicesConfig.app_settings)
 | 
					                    if (null != _appServicesConfig.app_settings)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
| 
						 | 
					@ -355,7 +276,7 @@ namespace Guru
 | 
				
			||||||
                    //---------------------------------
 | 
					                    //---------------------------------
 | 
				
			||||||
                }, ex =>
 | 
					                }, ex =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    UnityEngine.Debug.LogError($"--- ERROR on apply services: {ex.Message}");
 | 
					                    Debug.LogError($"--- ERROR on apply services: {ex.Message}");
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
          
 | 
					          
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
| 
						 | 
					@ -369,14 +290,13 @@ namespace Guru
 | 
				
			||||||
                    LogI($"#4.3 --- Start IAP ---");
 | 
					                    LogI($"#4.3 --- Start IAP ---");
 | 
				
			||||||
                    if (_initConfig.GoogleKeys == null || _initConfig.AppleRootCerts == null)
 | 
					                    if (_initConfig.GoogleKeys == null || _initConfig.AppleRootCerts == null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        LogException("[IAP] GoogleKeys is null when using IAPService! Integration failed. App will Exit");
 | 
					                        LogEx("[IAP] GoogleKeys is null when using IAPService! Integration failed. App will Exit");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    InitIAP(UID, _initConfig.GoogleKeys, _initConfig.AppleRootCerts); // 初始化IAP
 | 
					                    InitIAP(UID, _initConfig.GoogleKeys, _initConfig.AppleRootCerts); // 初始化IAP
 | 
				
			||||||
                }, ex =>
 | 
					                }, ex =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    UnityEngine.Debug.LogError($"--- ERROR on useIAP: {ex.Message}");
 | 
					                    Debug.LogError($"--- ERROR on useIAP: {ex.Message}");
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            //----------- Set Keywords ----------------
 | 
					            //----------- Set Keywords ----------------
 | 
				
			||||||
| 
						 | 
					@ -386,10 +306,10 @@ namespace Guru
 | 
				
			||||||
                Try(() =>
 | 
					                Try(() =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    LogI($"#4.4 --- Start Keywords ---");
 | 
					                    LogI($"#4.4 --- Start Keywords ---");
 | 
				
			||||||
                    KeywordsManager.Install(Model.IsIapUser, Model.SuccessLevelId); // 启动Keyword管理器
 | 
					                    KeywordsManager.Install(Model.IsIapUser, Model.BLevel); // 启动Keyword管理器
 | 
				
			||||||
                }, ex =>
 | 
					                }, ex =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    UnityEngine.Debug.LogError($"--- ERROR on Keywords: {ex.Message}");
 | 
					                    Debug.LogError($"--- ERROR on Keywords: {ex.Message}");
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -399,7 +319,7 @@ namespace Guru
 | 
				
			||||||
                // StartAppleReviewFlow(); // 直接显示 ATT 弹窗, 跳过 Consent 流程
 | 
					                // StartAppleReviewFlow(); // 直接显示 ATT 弹窗, 跳过 Consent 流程
 | 
				
			||||||
                Try(() =>
 | 
					                Try(() =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    LogI($"#4.5.0 ---  StartAppleReviewFlow ---");
 | 
					                    LogI($"#4.5 ---  StartAppleReviewFlow ---");
 | 
				
			||||||
                    StartAppleReviewFlow(); // 直接显示 ATT 弹窗, 跳过 Consent 流程
 | 
					                    StartAppleReviewFlow(); // 直接显示 ATT 弹窗, 跳过 Consent 流程
 | 
				
			||||||
                }, ex =>
 | 
					                }, ex =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					@ -411,27 +331,23 @@ namespace Guru
 | 
				
			||||||
            //----------- Set Consent ----------------
 | 
					            //----------- Set Consent ----------------
 | 
				
			||||||
            if (!InitConfig.UseCustomConsent && !appleReview)
 | 
					            if (!InitConfig.UseCustomConsent && !appleReview)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // LogI($"--- #3 Start Consent Flow ---");
 | 
					                LogI($"#4.6 --- Start Consent Flow ---");
 | 
				
			||||||
                // StartConsentFlow();
 | 
					                Try(StartConsentFlow, ex =>
 | 
				
			||||||
                Try(() =>
 | 
					 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    LogI($"#4.5 ---  StartConsentFlow ---");
 | 
					                    Debug.LogError($"--- ERROR on StartConsentFlow: {ex.Message}");
 | 
				
			||||||
                    StartConsentFlow();
 | 
					 | 
				
			||||||
                }, ex =>
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    UnityEngine.Debug.LogError($"--- ERROR on StartConsentFlow: {ex.Message}");
 | 
					 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 | 
					#if UNITY_ANDROID
 | 
				
			||||||
 | 
					            LogI($"#5.1 --- Android StartAndroidDebug Cmd lines---");
 | 
				
			||||||
 | 
					            // Android 命令行调试
 | 
				
			||||||
 | 
					            StartAndroidDebugCmds();           
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            IsServiceReady = true;
 | 
					            IsServiceReady = true;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // 中台服务初始化结束
 | 
					            // 中台服务初始化结束
 | 
				
			||||||
            Callbacks.SDK._onGuruServiceReady?.Invoke();
 | 
					            Callbacks.SDK.InvokeOnGuruServiceReady();
 | 
				
			||||||
            
 | 
					 | 
				
			||||||
#if UNITY_ANDROID
 | 
					 | 
				
			||||||
            // Android 命令行调试
 | 
					 | 
				
			||||||
            StartAndroidDebugCmds();           
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -457,7 +373,7 @@ namespace Guru
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // No remote data fetched from cloud, should use default values
 | 
					                // No remote data fetched from cloud, should use default values
 | 
				
			||||||
                json = defaultJson;
 | 
					                json = defaultJson;
 | 
				
			||||||
                UnityEngine.Debug.Log($"{Tag} --- No remote data found with: {key}  -> Using default key {ServicesConfigKey} and local data!!!");
 | 
					                Debug.Log($"{Tag} --- No remote data found with: {key}  -> Using default key {ServicesConfigKey} and local data!!!");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!string.IsNullOrEmpty(json))
 | 
					            if (!string.IsNullOrEmpty(json))
 | 
				
			||||||
| 
						 | 
					@ -478,7 +394,7 @@ namespace Guru
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (Exception ex)
 | 
					            catch (Exception ex)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                LogException(ex);
 | 
					                LogEx(ex);
 | 
				
			||||||
                // ignored
 | 
					                // ignored
 | 
				
			||||||
                onException?.Invoke(ex);
 | 
					                onException?.Invoke(ex);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -502,46 +418,32 @@ namespace Guru
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        #region 数据
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private void OnBLevelChanged(int blevel)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserBLevel(blevel);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private void OnBPlayChanged(int bplay)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            SetUserBPlay(bplay);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        #endregion
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        #region Logging
 | 
					        #region Logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal static void LogI(object message)
 | 
					        private static void LogI(object message)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            UnityEngine.Debug.Log($"{Tag} {message}");
 | 
					            Debug.Log($"{Tag} {message}");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal static void LogW(object message)
 | 
					        private static void LogW(object message)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            UnityEngine.Debug.LogWarning($"{Tag} {message}");
 | 
					            Debug.LogWarning($"{Tag} {message}");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal static void LogE(object message)
 | 
					        private static void LogE(object message)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            UnityEngine.Debug.LogError($"{Tag} {message}");
 | 
					            Debug.LogError($"{Tag} {message}");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal static void LogException(string message)
 | 
					        private static void LogEx(string message)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            LogException( new Exception($"{Tag} {message}"));
 | 
					            LogEx( new Exception($"{Tag} {message}"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        internal static void LogException(Exception e)
 | 
					        private static void LogEx(Exception e)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            UnityEngine.Debug.LogException(e);
 | 
					            Debug.LogException(e);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -582,7 +484,7 @@ namespace Guru
 | 
				
			||||||
        private void OnAppPauseHandler(bool paused)
 | 
					        private void OnAppPauseHandler(bool paused)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if(paused) Model.Save(true); // 强制保存数据
 | 
					            if(paused) Model.Save(true); // 强制保存数据
 | 
				
			||||||
            Callbacks.App._onAppPaused?.Invoke(paused);
 | 
					            Callbacks.App.InvokeOnAppPaused(paused);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private void OnApplicationPause(bool paused)
 | 
					        private void OnApplicationPause(bool paused)
 | 
				
			||||||
| 
						 | 
					@ -598,7 +500,7 @@ namespace Guru
 | 
				
			||||||
        private void OnApplicationQuit()
 | 
					        private void OnApplicationQuit()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Model.Save(true);
 | 
					            Model.Save(true);
 | 
				
			||||||
            Callbacks.App._onAppQuit?.Invoke();
 | 
					            Callbacks.App.InvokeOnAppQuit();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
| 
						 | 
					@ -661,14 +563,13 @@ namespace Guru
 | 
				
			||||||
        private void UpdateAllUpdates()
 | 
					        private void UpdateAllUpdates()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            int i = 0;
 | 
					            int i = 0;
 | 
				
			||||||
            IUpdater updater;
 | 
					 | 
				
			||||||
            // ---- Updater Trigger ----
 | 
					            // ---- Updater Trigger ----
 | 
				
			||||||
            if (_updaterRunningList.Count > 0)
 | 
					            if (_updaterRunningList.Count > 0)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                i = 0;
 | 
					                i = 0;
 | 
				
			||||||
                while (i < _updaterRunningList.Count)
 | 
					                while (i < _updaterRunningList.Count)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    updater = _updaterRunningList[i];
 | 
					                    var updater = _updaterRunningList[i];
 | 
				
			||||||
                    if (updater != null) 
 | 
					                    if (updater != null) 
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (updater.State == UpdaterState.Running)
 | 
					                        if (updater.State == UpdaterState.Running)
 | 
				
			||||||
| 
						 | 
					@ -729,12 +630,12 @@ namespace Guru
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #region 推送管理
 | 
					        #region 中台推送管理
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static int _messageRetry = 0;
 | 
					        private static int _messageRetry = 0;
 | 
				
			||||||
        public static void SetPushNotificationEnabled(bool enabled)
 | 
					        public static void SetPushNotificationEnabled(bool enabled)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            DeviceInfoUploadRequest request = new DeviceInfoUploadRequest()
 | 
					            DeviceInfoUploadRequest request = (DeviceInfoUploadRequest) new DeviceInfoUploadRequest()
 | 
				
			||||||
                .SetRetryTimes(1)
 | 
					                .SetRetryTimes(1)
 | 
				
			||||||
                .SetSuccessCallBack(() =>
 | 
					                .SetSuccessCallBack(() =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					@ -746,16 +647,197 @@ namespace Guru
 | 
				
			||||||
                    double retryDelay = Math.Pow(2, _messageRetry);
 | 
					                    double retryDelay = Math.Pow(2, _messageRetry);
 | 
				
			||||||
                    _messageRetry++;
 | 
					                    _messageRetry++;
 | 
				
			||||||
                    CoroutineHelper.Instance.StartDelayed((float)retryDelay, ()=> SetPushNotificationEnabled(enabled));
 | 
					                    CoroutineHelper.Instance.StartDelayed((float)retryDelay, ()=> SetPushNotificationEnabled(enabled));
 | 
				
			||||||
                }) as DeviceInfoUploadRequest;
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (request != null)
 | 
					            if (request == null) return;
 | 
				
			||||||
            {
 | 
					            
 | 
				
			||||||
                request.SetPushEnabled(enabled);
 | 
					            request.SetPushEnabled(enabled);
 | 
				
			||||||
                request.Send();
 | 
					            request.Send();
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region Deeplink
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 添加回调链接
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="deeplink"></param>
 | 
				
			||||||
 | 
					        private void OnDeeplinkCallback(string deeplink)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					           Callbacks.SDK.InvokeDeeplinkCallback(deeplink); // 尝试调用回调
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region 网络状态上报
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private NetworkStatusMonitor _networkStatusMonitor;
 | 
				
			||||||
 | 
					        private string _lastNetworkStatus;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        private void InitNetworkMonitor()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _networkStatusMonitor = new NetworkStatusMonitor(Analytics.SetNetworkStatus, 
 | 
				
			||||||
 | 
					                lastStatus =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                LogEvent("guru_offline", new Dictionary<string, dynamic>()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ["from"] = lastStatus
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 获取当前的网络状态
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns></returns>
 | 
				
			||||||
 | 
					        private string GetNetworkStatus() => _networkStatusMonitor.GetNetworkStatus();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region Firebase 服务
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 启动 Firebase 服务
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private void StartFirebaseService()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            FirebaseUtil.Init(OnFirebaseDepsCheckResult, 
 | 
				
			||||||
 | 
					                OnGetFirebaseId, 
 | 
				
			||||||
 | 
					                OnGetGuruUID, 
 | 
				
			||||||
 | 
					                OnFirebaseLoginResult); // 确保所有的逻辑提前被调用到
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void OnGetGuruUID(bool success)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (success)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Model.UserId = IPMConfig.IPM_UID;
 | 
				
			||||||
 | 
					                if (GuruIAP.Instance != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    GuruIAP.Instance.SetUID(UID);
 | 
				
			||||||
 | 
					                    GuruIAP.Instance.SetUUID(UUID);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                // 自打点设置用户 ID
 | 
				
			||||||
 | 
					                Analytics.SetUid(UID);
 | 
				
			||||||
 | 
					                // Crashlytics 设置 uid
 | 
				
			||||||
 | 
					                CrashlyticsAgent.SetUserId(UID);
 | 
				
			||||||
 | 
					                // 上报所有的事件
 | 
				
			||||||
 | 
					                Analytics.ShouldFlushGuruEvents();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            Callbacks.SDK.InvokeOnGuruUserAuthResult(success);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        private void OnGetFirebaseId(string fid)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // 初始化 Adjust 服务
 | 
				
			||||||
 | 
					            InitAdjustService(fid, InitConfig.OnAdjustDeeplinkCallback);
 | 
				
			||||||
 | 
					            // 初始化自打点
 | 
				
			||||||
 | 
					            Analytics.InitGuruAnalyticService(fid);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            //---------- Event SDK Info ------------
 | 
				
			||||||
 | 
					            LogI($"#6.0 --- SDK is ready, report Info ---");
 | 
				
			||||||
 | 
					            LogSDKInfo((DateTime.UtcNow - _initTime).TotalSeconds);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // TODO: 需要之后用宏隔离应用和实现
 | 
				
			||||||
 | 
					        // Auth 登录认证
 | 
				
			||||||
 | 
					        private void OnFirebaseLoginResult(bool success, Firebase.Auth.FirebaseUser firebaseUser)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _firebaseUser = firebaseUser;
 | 
				
			||||||
 | 
					            Callbacks.SDK.InvokeOnFirebaseAuthResult(success, firebaseUser);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 开始各种组件初始化
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private void OnFirebaseDepsCheckResult(bool success)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            LogI($"#3 --- On FirebaseDeps: {success} ---");
 | 
				
			||||||
 | 
					            IsFirebaseReady = success;
 | 
				
			||||||
 | 
					            Callbacks.SDK.InvokeOnFirebaseReady(success);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Analytics.OnFirebaseInitCompleted();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            LogI($"#3.5 --- Call InitRemoteConfig ---");
 | 
				
			||||||
 | 
					            // 开始Remote Manager初始化 
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            var defaultGuruServiceJson = LoadDefaultGuruServiceJson();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var dict = _initConfig.DefaultRemoteData.ToDictionary(
 | 
				
			||||||
 | 
					                entry => entry.Key,
 | 
				
			||||||
 | 
					                entry => entry.Value);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (!string.IsNullOrEmpty(defaultGuruServiceJson))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                dict[ServicesConfigKey] = defaultGuruServiceJson;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            RemoteConfigManager.Init(dict);
 | 
				
			||||||
 | 
					            RemoteConfigManager.OnFetchCompleted += OnFetchRemoteCallback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            LogI($"#4 --- Apply remote services config ---");
 | 
				
			||||||
 | 
					            // 根据缓存的云控配置来初始化参数
 | 
				
			||||||
 | 
					            InitAllGuruServices();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					        		
 | 
				
			||||||
 | 
					        #region Adjust服务
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 启动 Adjust 服务
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        private static void InitAdjustService(string firebaseId, Action<string> onDeeplinkCallback = null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // 启动 AdjustService
 | 
				
			||||||
 | 
					            string appToken = GuruSettings.Instance.AdjustSetting?.GetAppToken() ?? "";
 | 
				
			||||||
 | 
					            string fbAppId = GuruSettings.Instance.IPMSetting.FacebookAppId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ID))
 | 
				
			||||||
 | 
					            //     Analytics.SetAdjustId(IPMConfig.ADJUST_ID); // 二次启动后,若有值则立即上报属性
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            AdjustService.Instance.Start(appToken, fbAppId, firebaseId, DeviceId,
 | 
				
			||||||
 | 
					                OnAdjustInitComplete, onDeeplinkCallback ,OnGetGoogleAdId );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Adjust 初始化结束
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="adjustId"></param>
 | 
				
			||||||
 | 
					        /// <param name="idfv"></param>
 | 
				
			||||||
 | 
					        /// <param name="idfa"></param>
 | 
				
			||||||
 | 
					        private static void OnAdjustInitComplete(string adjustId, string idfv, string idfa)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug.Log($"{Tag} --- OnAdjustInitComplete:  adjustId:{adjustId}  idfv:{idfv}  idfa:{idfa}");
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            // 获取 ADID 
 | 
				
			||||||
 | 
					            if (string.IsNullOrEmpty(adjustId)) adjustId = "not_set";
 | 
				
			||||||
 | 
					            if (string.IsNullOrEmpty(idfv)) idfv = "not_set";
 | 
				
			||||||
 | 
					            if (string.IsNullOrEmpty(idfa)) idfa = "not_set";
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            IPMConfig.ADJUST_ID = adjustId;
 | 
				
			||||||
 | 
					            IPMConfig.ADJUST_IDFV = idfv;
 | 
				
			||||||
 | 
					            IPMConfig.ADJUST_IDFA = idfa;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            Analytics.SetAdjustId(adjustId);
 | 
				
			||||||
 | 
					            Analytics.SetIDFV(idfv);
 | 
				
			||||||
 | 
					            Analytics.SetIDFA(idfa);
 | 
				
			||||||
 | 
					            Analytics.OnAdjustInitComplete();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static void OnGetGoogleAdId(string googleAdId)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Debug.Log($"{Tag} --- OnGetGoogleAdId: {googleAdId}");
 | 
				
			||||||
 | 
					            // IPMConfig.ADJUST_GOOGLE_ADID = googleAdId;
 | 
				
			||||||
 | 
					            Analytics.SetGoogleAdId(googleAdId);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
        #endregion
 | 
					        #endregion
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  "name": "com.guru.unity.sdk",
 | 
					  "name": "com.guru.unity.sdk",
 | 
				
			||||||
  "displayName": "Guru SDK",
 | 
					  "displayName": "Guru SDK",
 | 
				
			||||||
  "version": "1.0.13",
 | 
					  "version": "1.1.0",
 | 
				
			||||||
  "description": "Guru SDK for unity project",
 | 
					  "description": "Guru SDK for unity project",
 | 
				
			||||||
  "unity": "2020.3",
 | 
					  "unity": "2020.3",
 | 
				
			||||||
  "author":{
 | 
					  "author":{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue