Compare commits
	
		
			48 Commits 
		
	
	
		
			25f4d7e588
			...
			58cc5a3b46
		
	
	| 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 | |
|  | 957f60e797 | 
|  | @ -17,4 +17,6 @@ ApFindDifference,2PACX-1vSmodKOvKjxmiNoYbrXFI6n1XC0aqvlnbYkEGyabLKqS6-C3Yi3nstmC | |||
| GoodsSort,2PACX-1vQrg6Ss2bNYAI7A250t3_zp10UJtbbQXb8I4LtDJ2Q3uopUG_PUadoJy7T4w0jlf4xcTqot2NWsfp1m | ||||
| CookingBlitz,2PACX-1vShqtSSpwYQ8CvK-BVr-wQ5ygGeKKLdpaaWysSN_QumoDZYATemayAQIOdnFRzMP69nEwFYSx51oey8 | ||||
| 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.daemon=true | ||||
| org.gradle.caching=true | ||||
| android.enableR8=**MINIFY_WITH_R_EIGHT** | ||||
| unityStreamingAssets=**STREAMING_ASSETS** | ||||
| # Android Resolver Properties Start | ||||
| android.useAndroidX=true | ||||
|  |  | |||
|  | @ -5,7 +5,8 @@ dependencies { | |||
|     } | ||||
| 
 | ||||
| android { | ||||
|     compileSdkVersion **APIVERSION** | ||||
|     namespace "**NAMESPACE**" | ||||
|     compileSdkVersion **TARGETSDKVERSION** | ||||
|     buildToolsVersion '**BUILDTOOLS**' | ||||
| 
 | ||||
|     compileOptions { | ||||
|  | @ -22,6 +23,7 @@ android { | |||
|         } | ||||
|         versionCode **VERSIONCODE** | ||||
|         versionName '**VERSIONNAME**' | ||||
|         multiDexEnabled true | ||||
|     } | ||||
| 
 | ||||
|     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 | ||||
|     { | ||||
|         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 static string LauncherFullPath = Path.Combine(Application.dataPath, $"Plugins/Android/{LauncherName}.gradle"); | ||||
|         private const string LauncherName = "launcherTemplate"; | ||||
|         private static readonly string LauncherFullPath = Path.Combine(Application.dataPath, $"{K_ANDROID_PLUGINS_NAME}/{LauncherName}.gradle"); | ||||
|          | ||||
|         private static readonly string MainName = "mainTemplate"; | ||||
|         private static string MainFullPath = Path.Combine(Application.dataPath,  $"Plugins/Android/{MainName}.gradle"); | ||||
|         private const string MainName = "mainTemplate"; | ||||
|         private static readonly string MainFullPath = Path.Combine(Application.dataPath,  $"{K_ANDROID_PLUGINS_NAME}/{MainName}.gradle"); | ||||
|          | ||||
|         private static readonly string PropertiesName = "gradleTemplate"; | ||||
|         private static string PropertiesFullPath = Path.Combine(Application.dataPath,  $"Plugins/Android/{PropertiesName}.properties"); | ||||
|         private const string BaseProjectName = "baseProjectTemplate"; | ||||
|         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() | ||||
|         { | ||||
|             FixLauncher(); | ||||
|             FixMain(); | ||||
|             FixProperties(); | ||||
|             CheckTargetSDKVersion(); | ||||
|             ApplyLauncher(); | ||||
|             ApplyBaseProjectTemplates(); | ||||
|             ApplyMainTemplates(); | ||||
|             ApplyGradleTemplate(); | ||||
|             ApplySettings(); | ||||
|             ApplyProguardUser(); | ||||
|             CheckTargetSDKVersion();  // 强制修复构建版本号 | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         private static void FixLauncher() | ||||
|          | ||||
|         private static void ApplyLauncher() | ||||
|         { | ||||
|             if (!File.Exists(LauncherFullPath)) | ||||
|             { | ||||
|  | @ -43,10 +58,9 @@ namespace Guru.Editor | |||
|             var ptn2 = "abortOnError false"; | ||||
|             var lines = File.ReadAllLines(LauncherFullPath); | ||||
| 
 | ||||
|             string line = ""; | ||||
|             for (int i = 0; i < lines.Length; i++) | ||||
|             { | ||||
|                 line = lines[i]; | ||||
|                 var line = lines[i]; | ||||
|                 if (line.Contains(ptn1)) | ||||
|                 { | ||||
|                     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); | ||||
| 
 | ||||
|         } | ||||
|         private static void FixMain() | ||||
|         private static void ApplyMainTemplates() | ||||
|         { | ||||
|             if (!File.Exists(MainFullPath)) | ||||
|             { | ||||
|  | @ -72,13 +86,100 @@ namespace Guru.Editor | |||
|                 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)) | ||||
|             { | ||||
|                 Debug.Log($"[MOD] --- Copy file to: {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() | ||||
|  |  | |||
|  | @ -497,6 +497,7 @@ namespace Guru.Editor | |||
|                 { | ||||
|                     ReadServiceConfig(); // Read file again | ||||
|                     CheckAllComponents(); | ||||
|                     ExecuteAdditionalCommands(); | ||||
|                 }, null, GUILayout.Height(btnH)); | ||||
|             } | ||||
|              | ||||
|  | @ -504,7 +505,14 @@ namespace Guru.Editor | |||
|              | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 执行其他的命令 | ||||
|         /// </summary> | ||||
|         private void ExecuteAdditionalCommands() | ||||
|         { | ||||
|             // 部署 Adjust Signature V3 | ||||
|             DeployAdjustSignatureV3Files();  | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         #endregion | ||||
|  | @ -1245,6 +1253,18 @@ namespace Guru.Editor | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         #region OtherCommands | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 使用 Adjust 签名 V3 导入项目 | ||||
|         /// </summary> | ||||
|         private void DeployAdjustSignatureV3Files() | ||||
|         { | ||||
|             AdjustSignatureHelper.DeployFiles(); | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,7 +7,8 @@ | |||
|         "Guru.LitJson", | ||||
|         "Guru.Runtime", | ||||
|         "MaxSdk.Scripts.IntegrationManager.Editor", | ||||
|         "Guru.Editor" | ||||
|         "Guru.Editor", | ||||
|         "GuruAdjust.Editor" | ||||
|     ], | ||||
|     "includePlatforms": [ | ||||
|         "Editor" | ||||
|  |  | |||
|  | @ -1,12 +1,17 @@ | |||
| 
 | ||||
| namespace Guru | ||||
| { | ||||
|     using System.Collections.Generic; | ||||
|     using System.Text; | ||||
|     using System; | ||||
|      | ||||
|     /// <summary> | ||||
|     /// 启动参数配置 | ||||
|     /// </summary> | ||||
|     public partial class GuruSDKInitConfig | ||||
|     public class GuruSDKInitConfig | ||||
|     { | ||||
|         #region Properties | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 使用自定义的ConsentFlow启动流程 | ||||
|         /// </summary> | ||||
|  | @ -26,7 +31,8 @@ namespace Guru | |||
|         /// <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> | ||||
|         /// 自定义 Service 云控 Key | ||||
|         /// </summary> | ||||
|  | @ -34,7 +40,7 @@ namespace Guru | |||
|         /// <summary> | ||||
|         /// Banner 背景颜色 Hex 值 | ||||
|         /// </summary> | ||||
|         public string BannerBackgroundColor = "#00000000"; | ||||
|         public string BannerBackgroundColor = "#00000040"; | ||||
|         /// <summary> | ||||
|         /// 已购买去广告道具 | ||||
|         /// </summary> | ||||
|  | @ -44,58 +50,40 @@ namespace Guru | |||
|         /// </summary> | ||||
|         public bool DebugMode = false; | ||||
|         /// <summary> | ||||
|         /// Debug模式下开启打点(默认关闭) | ||||
|         /// </summary> | ||||
|         public bool EnableDebugLogEvent = false; | ||||
| 
 | ||||
|         private Dictionary<string, object> _defaultRemoteData = new Dictionary<string, object>(); | ||||
|         /// <summary> | ||||
|         /// 云控参数的默认配置 | ||||
|         /// </summary> | ||||
|         /// <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> | ||||
|         /// 支付初始化Keys | ||||
|         /// </summary> | ||||
|         public byte[] GoogleKeys;       // 数据取自 GooglePlayTangle.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 | ||||
| 
 | ||||
|          | ||||
|         #region Print | ||||
| 
 | ||||
|         public override string ToString() | ||||
|  | @ -119,5 +107,107 @@ namespace Guru | |||
| 
 | ||||
| 
 | ||||
|         #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 | ||||
| { | ||||
|     using System; | ||||
|     using UnityEngine.Serialization; | ||||
|      | ||||
|     [Serializable] | ||||
|     public class GuruServicesConfig | ||||
|  | @ -61,7 +62,7 @@ namespace Guru | |||
|         public string DMAMapRule() => parameters?.dma_map_rule ?? ""; | ||||
|         public bool UseUUID() => parameters?.using_uuid ?? 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 string CdnHost() => parameters?.cdn_host ?? ""; | ||||
|         public bool UsingUUID() => parameters?.using_uuid ?? true; | ||||
|  | @ -91,7 +92,7 @@ namespace Guru | |||
|     [Serializable] | ||||
|     public class GuruParameters | ||||
|     { | ||||
|         public int token_vaild_time = 604800; | ||||
|         public int token_valid_time = 604800; | ||||
|         public int level_end_success_num = 50; | ||||
|         public bool enable_keywords = false; | ||||
|         public double tch_020 = 0; | ||||
|  |  | |||
|  | @ -7,14 +7,17 @@ namespace Guru | |||
|         /// 获取BLevel | ||||
|         /// </summary> | ||||
|         /// <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) | ||||
|         { | ||||
|             if (success) | ||||
|             { | ||||
|                  | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void ClearData() | ||||
|         { | ||||
|             _model.ClearData(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -12,27 +12,17 @@ namespace Guru | |||
|             get => _value; | ||||
|             set | ||||
|             { | ||||
|                 if (_value.Equals(value)) return; | ||||
|                  | ||||
|                 _value = value; | ||||
|                 OnValueChanged?.Invoke(value); | ||||
|             } | ||||
|         } | ||||
|         public event Action<T> OnValueChanged; | ||||
|          | ||||
|          | ||||
|         public BindableProperty()  | ||||
|         { | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|         public BindableProperty(Action<T> onChanged) | ||||
|         { | ||||
|             OnValueChanged = onChanged; | ||||
|         } | ||||
|          | ||||
|         public BindableProperty(T initValue, Action<T> onChanged) | ||||
|         public BindableProperty(T initValue) | ||||
|         { | ||||
|             _value = initValue; | ||||
|             OnValueChanged = onChanged; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,6 +1,3 @@ | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| namespace Guru | ||||
| { | ||||
|     using System; | ||||
|  | @ -8,11 +5,42 @@ namespace Guru | |||
|     using System.Collections.Generic; | ||||
|     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] | ||||
|     internal class GuruSDKModel | ||||
|     { | ||||
|         private const float SaveInterval = 3; | ||||
|         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; | ||||
|  | @ -20,111 +48,77 @@ namespace Guru | |||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (null == _instance) _instance = Load(); | ||||
|                 if (null == _instance) _instance = new GuruSDKModel(); | ||||
|                 return _instance; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         //-------------- data --------------- | ||||
|         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 | ||||
|         public GuruSDKModel() | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if(_successLevel == null) InitProperties(); | ||||
|                 return _successLevel.Value; | ||||
|             } | ||||
|             // 读取内存值 | ||||
|             GuruSDKSerializedModel model = LoadModel(); | ||||
|             _uid = model.uid; | ||||
|             _noAds = model.no_ads; | ||||
|             _bLevel = model.b_level; | ||||
|             _bPlay = model.b_play; | ||||
|             _purchased = model.purchased; | ||||
|         } | ||||
|          | ||||
|         public int BLevel | ||||
|         { | ||||
|             get => _bLevel; | ||||
|             set | ||||
|             { | ||||
|                 if(_successLevel == null) InitProperties(); | ||||
|                 _successLevel.Value = value; | ||||
|                 if (value < _bLevel) | ||||
|                 { | ||||
|                     // 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 | ||||
|             { | ||||
|                 if(_totalPlayed == null) InitProperties(); | ||||
|                 return _totalPlayed.Value; | ||||
|             } | ||||
|             get => _bPlay; | ||||
|             set | ||||
|             { | ||||
|                 if(_totalPlayed == null) InitProperties(); | ||||
|                 _totalPlayed.Value = value; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public int PurchasedCount | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if(_purchasedCount == null) InitProperties(); | ||||
|                 return _purchasedCount.Value; | ||||
|             } | ||||
|             set | ||||
|             { | ||||
|                 if(_purchasedCount == null) InitProperties(); | ||||
|                 _purchasedCount.Value = value; | ||||
|                 _bPlay = value; | ||||
|                 Save(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public string UserId | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if(_uid == null) InitProperties(); | ||||
|                 return _uid.Value; | ||||
|             } | ||||
|             get => _uid; | ||||
|             set | ||||
|             { | ||||
|                 if(_uid == null) InitProperties(); | ||||
|                 _uid.Value = value; | ||||
|                 _uid = value; | ||||
|                 Save(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public bool IsIapUser => PurchasedCount > 0; | ||||
| 
 | ||||
|         public bool IsIapUser => _purchased.Count > 0; | ||||
|          | ||||
|         public bool IsNoAds | ||||
|         { | ||||
|             get => no_ads; | ||||
|             get => _noAds; | ||||
|             set | ||||
|             { | ||||
|                 no_ads = value; | ||||
|                 _noAds = value; | ||||
|                 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 BindableProperty<int> PropBPlay => _totalPlayed; | ||||
|         public BindableProperty<int> PropBuyCount => _purchasedCount; | ||||
|         public BindableProperty<string> Uid => _uid; | ||||
| 
 | ||||
|         #region 初始化 | ||||
| 
 | ||||
|          | ||||
|         public static GuruSDKModel Load() | ||||
| 
 | ||||
|         private GuruSDKSerializedModel LoadModel() | ||||
|         { | ||||
|             GuruSDKModel model = null; | ||||
|             GuruSDKSerializedModel model = null; | ||||
|             if (PlayerPrefs.HasKey(SaveKey)) | ||||
|             { | ||||
|                 var json = PlayerPrefs.GetString(SaveKey, ""); | ||||
|  | @ -132,113 +126,62 @@ namespace Guru | |||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         model =  JsonUtility.FromJson<GuruSDKModel>(json); | ||||
|                         model =  JsonUtility.FromJson<GuruSDKSerializedModel>(json); | ||||
|                     } | ||||
|                     catch (Exception e) | ||||
|                     { | ||||
|                         UnityEngine.Debug.LogError(e); | ||||
|                         Debug.LogError(e); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if(model == null) model = new GuruSDKModel(); | ||||
|             model.InitProperties(); | ||||
|             if(model == null) model = new GuruSDKSerializedModel(); | ||||
|             return model; | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// 保存至数据 | ||||
|         /// 保存至 PlayerPrefs 数据 | ||||
|         /// </summary> | ||||
|         private void SaveToPlayerPrefs() | ||||
|         private void SetToMemory() | ||||
|         { | ||||
|             var json = JsonUtility.ToJson(this); | ||||
|             PlayerPrefs.SetString(SaveKey, json); | ||||
|         } | ||||
| 
 | ||||
|         public void InitProperties() | ||||
|         { | ||||
|             if (_successLevel == null) _successLevel = new BindableProperty<int>(b_level, OnLevelChanged); | ||||
|             if (_totalPlayed == null) _totalPlayed = new BindableProperty<int>(b_play, OnPlayedChanged); | ||||
|             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); | ||||
|             var model = new GuruSDKSerializedModel() | ||||
|             { | ||||
|                 uid = _uid, | ||||
|                 b_level = _bLevel, | ||||
|                 b_play = _bPlay, | ||||
|                 no_ads = _noAds, | ||||
|                 purchased = _purchased, | ||||
|             }; | ||||
|              | ||||
|             var json = JsonUtility.ToJson(model); | ||||
|             if (!string.IsNullOrEmpty(json)) | ||||
|             { | ||||
|                 PlayerPrefs.SetString(SaveKey, json); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// 保存数据 | ||||
|         /// </summary> | ||||
|         /// <param name="force"></param> | ||||
|         public void Save(bool force = false) | ||||
|         /// <param name="forceSave"></param> | ||||
|         public void Save(bool forceSave = false) | ||||
|         { | ||||
|             bool save = force || (Time.realtimeSinceStartup - _lastSavedTime>= SaveInterval); | ||||
|             if (save) | ||||
|             { | ||||
|                 _lastSavedTime = Time.realtimeSinceStartup; | ||||
|                 SaveToPlayerPrefs(); | ||||
|             } | ||||
|         } | ||||
|             SetToMemory(); // 每次保存都要设置到 PlayerPrefs 内 | ||||
| 
 | ||||
|         internal void SetBLevelValue(int value) => OnLevelChanged(value); | ||||
|         internal void SetBPlayValue(int value) => OnPlayedChanged(value); | ||||
| 
 | ||||
| 
 | ||||
|         #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(); | ||||
|             bool shouldWriteToDisk = forceSave || (DateTime.Now - _lastSavedTime)>= TimeSpan.FromSeconds(SaveInterval); | ||||
|             if (!shouldWriteToDisk) return; | ||||
|             _lastSavedTime = DateTime.Now; // 更新最后保存时间 | ||||
|             PlayerPrefs.Save(); // 写入到磁盘 | ||||
|         } | ||||
|          | ||||
|         #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 订单记录 | ||||
| 
 | ||||
| 
 | ||||
|          | ||||
|         public bool HasPurchasedProduct(string receipt) | ||||
|         { | ||||
|             if(purchased == null || purchased.Count == 0) return false; | ||||
|             return purchased.Exists(p => p.receipt == receipt); | ||||
|             if(_purchased.Count == 0) return false; | ||||
|             return _purchased.Exists(p => p.receipt == receipt); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -247,12 +190,12 @@ namespace Guru | |||
|         /// <param name="receipt"></param> | ||||
|         /// <param name="productName"></param> | ||||
|         /// <param name="productId"></param> | ||||
|         /// <param name="appleProductIsRestored"></param> | ||||
|         public void AddReceipt(string receipt, string productName, string productId, bool appleProductIsRestored = false) | ||||
|         { | ||||
|             if (purchased == null) purchased = new List<PurchasedProduct>(20); | ||||
|             if (!HasPurchasedProduct(receipt)) | ||||
|             { | ||||
|                 purchased.Add(new PurchasedProduct() | ||||
|                 _purchased.Add(new PurchasedProduct() | ||||
|                 { | ||||
|                     receipt = receipt, | ||||
|                     productName = productName, | ||||
|  | @ -265,22 +208,16 @@ namespace Guru | |||
| 
 | ||||
|         public string[] GetReceipts(string productName) | ||||
|         { | ||||
|             int count = purchased?.Count ?? 0; | ||||
|             if (count == 0) count = 20; | ||||
|             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); | ||||
|             var receipts = new List<string>(); | ||||
|             receipts.AddRange(from purchasedProduct in _purchased where purchasedProduct.productName == productName select purchasedProduct.receipt); | ||||
|             return receipts.ToArray(); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         public string[] GetReceiptsById(string productId) | ||||
|         { | ||||
|             int count = purchased?.Count ?? 0; | ||||
|             if (count == 0) count = 20; | ||||
|             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); | ||||
|             var receipts = new List<string>(); | ||||
|             receipts.AddRange(from purchasedProduct in _purchased where purchasedProduct.productId == productId select purchasedProduct.receipt); | ||||
|             return receipts.ToArray(); | ||||
|         } | ||||
|          | ||||
|  | @ -288,17 +225,18 @@ namespace Guru | |||
| 
 | ||||
|         #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; | ||||
|     } | ||||
|      | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ namespace Guru | |||
|             _adInitSpec = spec; | ||||
|             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; | ||||
|             } | ||||
|              | ||||
|  | @ -59,7 +59,7 @@ namespace Guru | |||
|             } | ||||
|             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"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -128,7 +128,7 @@ namespace Guru | |||
|             AdServiceHandler(); | ||||
| 
 | ||||
|             // 调用回调 | ||||
|             Callbacks.ConsentFlow._onConsentResult?.Invoke(code); | ||||
|             Callbacks.ConsentFlow.InvokeOnConsentResult(code); | ||||
|              | ||||
| #if UNITY_IOS | ||||
|             CheckAttStatus();  // [iOS] Consent 启动后检查 ATT 初始值 | ||||
|  | @ -185,7 +185,7 @@ namespace Guru | |||
|         { | ||||
|             _attType = InitConfig.UseCustomConsent ? ATTManager.GUIDE_TYPE_CUSTOM : ATTManager.GUIDE_TYPE_ADMOB; // 点位属性确定 | ||||
|             _initialAttStatus = ATTManager.GetStatus(); | ||||
|             SetUserProperty(Analytics.ParameterATTStatus, _initialAttStatus); // 上报一个初始的状态 | ||||
|             SetATTStatus(_initialAttStatus); // 上报一个初始的状态 | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  | @ -202,14 +202,15 @@ namespace Guru | |||
|         private void ReportAttStatus(string status) | ||||
|         { | ||||
|             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)  | ||||
|                 && status != _initialAttStatus  | ||||
|                 && status !=  ATTManager.ATT_STATUS_NOT_DETERMINED) | ||||
|             { | ||||
|                 // 上报点位: | ||||
|                 Analytics.AttResult(status, _attType); | ||||
|                 SetATTStatus(_initialAttStatus); | ||||
|             } | ||||
| 
 | ||||
|             switch(status) | ||||
|  | @ -240,10 +241,10 @@ namespace Guru | |||
|         /// </summary> | ||||
|         private void InitNotiPermission() | ||||
|         { | ||||
|             bool hasNotiGranted = false; | ||||
|             // bool hasNotiGranted = false; | ||||
|             _notiStatue = "no_determined"; | ||||
|             NotificationService.Initialize(); // 初始化 Noti 服务 | ||||
|             SetNotiPerm(NotificationService.GetStatus()); | ||||
|             Analytics.SetNotiPerm(NotificationService.GetStatus()); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  | @ -256,16 +257,16 @@ namespace Guru | |||
|             // 如果未启用自动 Noti 授权,则直接上报状态 | ||||
|             if (!_initConfig.AutoNotificationPermission) | ||||
|             { | ||||
|                 UnityEngine.Debug.LogWarning($"[SDK] ---- AutoNotificationPermission is OFF, Project should request permission own."); | ||||
|                 Debug.LogWarning($"[SDK] ---- AutoNotificationPermission is OFF, Project should request permission own."); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             bool isGranted = NotificationService.IsPermissionGranted(); | ||||
|             UnityEngine.Debug.Log($"[SDK] ---- Check Noti Permission: {isGranted}"); | ||||
|             Debug.Log($"[SDK] ---- Check Noti Permission: {isGranted}"); | ||||
|             if (isGranted) | ||||
|             { | ||||
|                 UnityEngine.Debug.Log($"[SDK] ---- Set Notification Permission: {status}"); | ||||
|                 SetNotiPerm(status); | ||||
|                 Debug.Log($"[SDK] ---- Set Notification Permission: {status}"); | ||||
|                 Analytics.SetNotiPerm(status); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|  | @ -278,11 +279,13 @@ namespace Guru | |||
|         /// <param name="callback"></param> | ||||
|         public static void RequestNotificationPermission(Action<string> callback = null) | ||||
|         { | ||||
|             UnityEngine.Debug.Log($"[SDK] ---- RequestNotificationPermission"); | ||||
|             FirebaseUtil.StartFetchFcmToken(); | ||||
|              | ||||
|             Debug.Log($"[SDK] ---- RequestNotificationPermission"); | ||||
|             NotificationService.RequestPermission(status => | ||||
|             { | ||||
|                 UnityEngine.Debug.Log($"[SDK] ---- Set Notification Permission: {status}"); | ||||
|                 if(!string.IsNullOrEmpty(status)) SetNotiPerm(status); | ||||
|                 Debug.Log($"[SDK] ---- Set Notification Permission: {status}"); | ||||
|                 if(!string.IsNullOrEmpty(status)) Analytics.SetNotiPerm(status); | ||||
|                  | ||||
|                 callback?.Invoke(status); | ||||
|             }); | ||||
|  | @ -311,7 +314,6 @@ namespace Guru | |||
|         #region Ad Services | ||||
| 
 | ||||
|         private static bool _initAdsCompleted = false; | ||||
|         private static bool _isBannerVisible = false; | ||||
|         public static bool IsAdsReady => _initAdsCompleted; | ||||
|         private static int _preBannerAction = 0; | ||||
|          | ||||
|  | @ -324,7 +326,7 @@ namespace Guru | |||
|         /// <summary> | ||||
|         /// 启动广告服务 | ||||
|         /// </summary> | ||||
|         internal static void StartAdService(AdsInitSpec spec = null) | ||||
|         private static void StartAdService(AdsInitSpec spec = null) | ||||
|         { | ||||
|              | ||||
|             //---------- Using InitConfig ---------- | ||||
|  | @ -345,18 +347,18 @@ namespace Guru | |||
|              | ||||
|             //--------- Add Callbacks ----------- | ||||
|             // BADS | ||||
|             ADService.OnBannerStartLoad = OnBannerStartLoad; | ||||
|             ADService.OnBannerLoaded = OnBannerLoaded; | ||||
|             ADService.Instance.OnBannerStartLoad = OnBannerStartLoad; | ||||
|             ADService.Instance.OnBannerLoaded = OnBannerLoaded; | ||||
|             // IADS | ||||
|             ADService.OnInterstitialStartLoad = OnInterstitialStartLoad; | ||||
|             ADService.OnInterstitialLoaded = OnInterstitialLoaded; | ||||
|             ADService.OnInterstitialFailed = OnInterstitialFailed; | ||||
|             ADService.OnInterstitialClosed = OnInterstitialClosed; | ||||
|             ADService.Instance.OnInterstitialStartLoad = OnInterstitialStartLoad; | ||||
|             ADService.Instance.OnInterstitialLoaded = OnInterstitialLoaded; | ||||
|             ADService.Instance.OnInterstitialFailed = OnInterstitialFailed; | ||||
|             ADService.Instance.OnInterstitialClosed = OnInterstitialClosed; | ||||
|             // RADS | ||||
|             ADService.OnRewardedStartLoad = OnRewardStartLoad; | ||||
|             ADService.OnRewardLoaded = OnRewardLoaded; | ||||
|             ADService.OnRewardFailed = OnRewardFailed; | ||||
|             ADService.OnRewardClosed = OnRewardClosed; | ||||
|             ADService.Instance.OnRewardedStartLoad = OnRewardStartLoad; | ||||
|             ADService.Instance.OnRewardLoaded = OnRewardLoaded; | ||||
|             ADService.Instance.OnRewardFailed = OnRewardFailed; | ||||
|             ADService.Instance.OnRewardClosed = OnRewardClosed; | ||||
|              | ||||
|             // ---------- Start Services ---------- | ||||
|             ADService.Instance.StartService(OnAdsInitComplete, spec); | ||||
|  | @ -376,25 +378,25 @@ namespace Guru | |||
|         } | ||||
| 
 | ||||
|         private static void OnBannerStartLoad(string adUnitId) | ||||
|             => Callbacks.Ads._onBannerADStartLoad?.Invoke(adUnitId); | ||||
|             => Callbacks.Ads.InvokeOnBannerADStartLoad(adUnitId); | ||||
|         private static void OnBannerLoaded()  | ||||
|             => Callbacks.Ads._onBannerADLoaded?.Invoke(); | ||||
|             => Callbacks.Ads.InvokeOnBannerADLoaded(); | ||||
|         private static void OnInterstitialStartLoad(string adUnitId)  | ||||
|             => Callbacks.Ads._onInterstitialADStartLoad?.Invoke(adUnitId); | ||||
|             => Callbacks.Ads.InvokeOnInterstitialADStartLoad(adUnitId); | ||||
|         private static void OnInterstitialLoaded()  | ||||
|             => Callbacks.Ads._onInterstitialADLoaded?.Invoke(); | ||||
|             => Callbacks.Ads.InvokeOnInterstitialADLoaded(); | ||||
|         private static void OnInterstitialFailed() | ||||
|             => Callbacks.Ads._onInterstitialADFailed?.Invoke(); | ||||
|             => Callbacks.Ads.InvokeOnInterstitialADFailed(); | ||||
|         private static void OnInterstitialClosed() | ||||
|             => Callbacks.Ads._onInterstitialADClosed?.Invoke(); | ||||
|             => Callbacks.Ads.InvokeOnInterstitialADClosed(); | ||||
|         private static void OnRewardStartLoad(string adUnitId) | ||||
|             => Callbacks.Ads._onRewardedADStartLoad?.Invoke(adUnitId);  | ||||
|             => Callbacks.Ads.InvokeOnRewardedADStartLoad(adUnitId);  | ||||
|         private static void OnRewardLoaded() | ||||
|             => Callbacks.Ads._onRewardedADLoaded?.Invoke();  | ||||
|             => Callbacks.Ads.InvokeOnRewardedADLoaded();  | ||||
|         private static void OnRewardFailed() | ||||
|             => Callbacks.Ads._onRewardADFailed?.Invoke(); | ||||
|             => Callbacks.Ads.InvokeOnRewardADFailed(); | ||||
|         private static void OnRewardClosed() | ||||
|             => Callbacks.Ads._onRewardADClosed?.Invoke(); | ||||
|             => Callbacks.Ads.InvokeOnRewardADClosed(); | ||||
| 
 | ||||
|         private static void OnAdsInitComplete() | ||||
|         { | ||||
|  | @ -414,7 +416,7 @@ namespace Guru | |||
|                     HideBanner(); | ||||
|                 } | ||||
|             } | ||||
|             Callbacks.Ads._onAdsInitComplete?.Invoke(); | ||||
|             Callbacks.Ads.InvokeOnAdsInitComplete(); | ||||
|         } | ||||
| 
 | ||||
|         private static bool CheckAdsReady() | ||||
|  |  | |||
|  | @ -1,6 +1,4 @@ | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| namespace Guru | ||||
| { | ||||
|     using System; | ||||
|  | @ -12,25 +10,10 @@ namespace Guru | |||
|     /// </summary> | ||||
|     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 通用接口 | ||||
| 
 | ||||
|         //TODO: 需要有一个通用的 IEventData 的接口, 需要实现 getName, getData, getSetting, getPriority 等方法 | ||||
|         //TODO: Analytics.Track 的参数改为 IEventData | ||||
|          | ||||
|         /// <summary> | ||||
|         /// 自定义事件打点 | ||||
|         /// </summary> | ||||
|  | @ -39,14 +22,7 @@ namespace Guru | |||
|         /// <param name="priority"></param> | ||||
|         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); | ||||
|              | ||||
|             Analytics.Track(eventName, data, null, priority); | ||||
|         } | ||||
| 
 | ||||
|  | @ -54,12 +30,96 @@ namespace Guru | |||
|         { | ||||
|             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; | ||||
|             } | ||||
|             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 | ||||
|          | ||||
|         #region 游戏打点 | ||||
|  | @ -74,13 +134,13 @@ namespace Guru | |||
|         /// <param name="startType">关卡开始类型: play:开始游戏;replay:重玩;continue:继续游戏</param> | ||||
|         /// <param name="isReplay">是否重新开始: true/false</param> | ||||
|         /// <param name="extra">扩展数据</param> | ||||
|         public static void LogLevelStart(int levelId, string startType = EventLevelStartModePlay,  | ||||
|             string levelType = LevelTypeMain, string levelName = "", string itemId = "", | ||||
|         public static void LogLevelStart(int levelId, string startType = Consts.EventLevelStartModePlay,  | ||||
|             string levelType = Consts.LevelTypeMain, string levelName = "", string itemId = "", | ||||
|             bool isReplay = false, Dictionary<string, object> extra = null) | ||||
|         { | ||||
|             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; | ||||
|             } | ||||
| 
 | ||||
|  | @ -95,10 +155,10 @@ namespace Guru | |||
|         /// <param name="levelName"></param> | ||||
|         /// <param name="itemId"></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) | ||||
|         { | ||||
|             LogLevelStart(levelId, EventLevelStartModeContinue, levelType, levelName, itemId,  true, extra:extra); | ||||
|             LogLevelStart(levelId, Consts.EventLevelStartModeContinue, levelType, levelName, itemId,  true, extra:extra); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  | @ -108,10 +168,10 @@ namespace Guru | |||
|         /// <param name="levelType"></param> | ||||
|         /// <param name="levelName"></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) | ||||
|         { | ||||
|             LogLevelStart(levelId, EventLevelStartModeReplay,levelType, levelName, itemId,  true, extra:extra); | ||||
|             LogLevelStart(levelId, Consts.EventLevelStartModeReplay,levelType, levelName, itemId,  true, extra:extra); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -126,36 +186,37 @@ namespace Guru | |||
|         /// <param name="step">步数(有则上报)</param> | ||||
|         /// <param name="score">分数(有则上报)</param> | ||||
|         /// <param name="extra">扩展数据</param> | ||||
|         public static void LogLevelEnd(int levelId, string result = EventLevelEndSuccess, | ||||
|             string levelType = LevelTypeMain, string levelName = "", string itemId = "", | ||||
|         public static void LogLevelEnd(int levelId, string result = Consts.EventLevelEndSuccess, | ||||
|             string levelType = Consts.LevelTypeMain, string levelName = "", string itemId = "", | ||||
|             int duration = 0, int? step = null, int? score = null, Dictionary<string, object> extra = null) | ||||
|         { | ||||
|             if (!IsInitialSuccess) | ||||
|             { | ||||
|                 UnityEngine.Debug.LogError( | ||||
|                 Debug.LogError( | ||||
|                     $"{Tag} :: LogLevelEnd {levelId} :: Please call <GuruSDK.Start()> first, before you call <LogLevelEnd>."); | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|             if (extra == null) extra = new Dictionary<string, object>(); | ||||
|              | ||||
|             // 优先打 level_end 事件 | ||||
|             Analytics.LogLevelEnd(levelId, result, levelName, levelType, itemId, duration, step, score, extra); | ||||
|              | ||||
|             // 自动记录关卡属性 | ||||
|             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="extra"></param> | ||||
|         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); | ||||
|         } | ||||
|  | @ -182,8 +243,8 @@ namespace Guru | |||
|         /// /// <param name="extra">扩展参数</param> | ||||
|         public static void LogLevelEndSuccess(int bPlay, Dictionary<string, object> extra = null) | ||||
|         { | ||||
|             if (InitConfig.AutoRecordFinishedLevels) return; | ||||
|             Analytics.LevelEndSuccess(bPlay, extra); | ||||
|             var eventData = new LevelEndSuccessEventData(bPlay, extra); | ||||
|             Analytics.TrackLevelEndSuccessEvent(eventData); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -198,10 +259,10 @@ namespace Guru | |||
|         /// <param name="score"></param> | ||||
|         /// <param name="extra"></param> | ||||
|         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) | ||||
|         { | ||||
|             LogLevelEnd(levelId, EventLevelEndFail, levelType, levelName, itemId, duration, step, score, extra); | ||||
|             LogLevelEnd(levelId, Consts.EventLevelEndFail, levelType, levelName, itemId, duration, step, score, extra); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -216,10 +277,10 @@ namespace Guru | |||
|         /// <param name="score"></param> | ||||
|         /// <param name="extra"></param> | ||||
|         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) | ||||
|         { | ||||
|             LogLevelEnd(levelId, EventLevelEndExit, levelType, levelName, itemId, duration, step, score, extra); | ||||
|             LogLevelEnd(levelId, Consts.EventLevelEndExit, levelType, levelName, itemId, duration, step, score, extra); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -234,10 +295,10 @@ namespace Guru | |||
|         /// <param name="score"></param> | ||||
|         /// <param name="extra"></param> | ||||
|         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) | ||||
|         { | ||||
|             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) | ||||
|             { | ||||
|                 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; | ||||
|             } | ||||
|             Analytics.LevelUp(playerLevel, characterName, extra); | ||||
|  | @ -266,7 +327,7 @@ namespace Guru | |||
|         { | ||||
|             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; | ||||
|             } | ||||
|             Analytics.UnlockAchievement(achievementId, extra); | ||||
|  | @ -309,232 +370,38 @@ namespace Guru | |||
|             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); | ||||
|         } | ||||
| 
 | ||||
|         public static void SetAdjustId(string adjustId) | ||||
|         { | ||||
|             SetUserProperty(Consts.PropertyAdjustId, adjustId); | ||||
|         } | ||||
| 
 | ||||
|         /// <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 | ||||
| 
 | ||||
|         #region SDK 打点 | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Log SDK boost time | ||||
|         /// </summary> | ||||
|         /// <param name="time"></param> | ||||
|         private static void LogSDKInitTime(double time) | ||||
|         private static void LogSDKInfo(double time) | ||||
|         { | ||||
|             Analytics.Track(Consts.EventSDKInfo, new Dictionary<string, dynamic>() | ||||
|             { | ||||
|                 { "boost_time", time.ToString("F6") }, | ||||
|                 { Consts.PropertyDeviceID, DeviceId }, | ||||
|                 { "version", Version} | ||||
|                 { "version", Version}, | ||||
|                 { "network", Instance.GetNetworkStatus()}, | ||||
|             }, new Analytics.EventSetting() | ||||
|             { | ||||
|                 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 | ||||
| 
 | ||||
|         #region IAP 打点 | ||||
|  | @ -564,7 +431,7 @@ namespace Guru | |||
|         /// 当付费页面打开时调用 (iap_imp) | ||||
|         /// </summary> | ||||
|         /// <param name="scene">付费页场景名称</param> | ||||
|         /// <param name="productId">列表中首个商品的 ProductId </param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogIAPImp(string scene, Dictionary<string, object> extra = null) | ||||
|         { | ||||
|             Analytics.IAPImp(scene, extra); | ||||
|  | @ -574,7 +441,7 @@ namespace Guru | |||
|         /// 当付费页面关闭时调用 (iap_close) | ||||
|         /// </summary> | ||||
|         /// <param name="scene"></param> | ||||
|         /// <param name="productId"></param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogIAPClose(string scene, Dictionary<string, object> extra = null) | ||||
|         { | ||||
|             Analytics.IAPClose(scene, extra); | ||||
|  | @ -585,7 +452,9 @@ namespace Guru | |||
|         /// </summary> | ||||
|         /// <param name="scene"></param> | ||||
|         /// <param name="productId"></param> | ||||
|         /// <param name="basePlan"></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) | ||||
|         { | ||||
|             Analytics.IAPClick(scene, productId, basePlan, offerId, extra); | ||||
|  | @ -710,6 +579,7 @@ namespace Guru | |||
|         /// <param name="levelName">当前关卡名称</param> | ||||
|         /// <param name="scene">应用场景</param> | ||||
|         /// <param name="props">获取的道具名称列表</param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogEarnVirtualCurrencyBySign(string currencyName,  | ||||
|             int value = 0, int balance = 0, string levelName = "",  | ||||
|             string scene = "home_page", string[] props = null, Dictionary<string, object> extra = null) | ||||
|  | @ -733,6 +603,7 @@ namespace Guru | |||
|         /// <param name="levelName">当前关卡名称</param> | ||||
|         /// <param name="scene">应用场景</param> | ||||
|         /// <param name="props">获取的道具名称列表</param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogEarnVirtualCurrencyByIAP(string currencyName, | ||||
|             int value = 0, int balance = 0, string levelName = "",  | ||||
|             string scene = "store", string[] props = null, Dictionary<string, object> extra = null) | ||||
|  | @ -755,6 +626,7 @@ namespace Guru | |||
|         /// <param name="levelName">当前关卡名称</param> | ||||
|         /// <param name="scene">应用场景</param> | ||||
|         /// <param name="props">获取的道具名称列表</param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogEarnVirtualCurrencyByAds(string currencyName,  | ||||
|             int value = 0, int balance = 0, string levelName = "",  | ||||
|             string scene = "store", string[] props = null, Dictionary<string, object> extra = null) | ||||
|  | @ -763,7 +635,7 @@ namespace Guru | |||
|             string itemName = "ads"; | ||||
|             LogEarnVirtualCurrencyAndProps(currencyName, value, balance, category, itemName, levelName, scene, props, extra); | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 使用了金币半价 + 看广告获取到货币/道具 (earn_virtual_currency) (bonus:ads) | ||||
|         /// <li>通常类型: Coin 收入 </li> | ||||
|  | @ -776,6 +648,7 @@ namespace Guru | |||
|         /// <param name="levelName">当前关卡名称</param> | ||||
|         /// <param name="scene">应用场景</param> | ||||
|         /// <param name="props">获取的道具名称列表</param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogEarnVirtualCurrencyByPaidAds(string currencyName,  | ||||
|             int value = 0, int balance = 0, string levelName = "",  | ||||
|             string scene = Consts.ParameterDefaultScene, string[] props = null, Dictionary<string, object> extra = null) | ||||
|  | @ -797,6 +670,7 @@ namespace Guru | |||
|         /// <param name="levelName">当前关卡名称</param> | ||||
|         /// <param name="scene">应用场景</param> | ||||
|         /// <param name="props">获取的道具名称列表</param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogEarnVirtualCurrencyByLevelComplete(string currencyName,  | ||||
|             int value = 0, int balance = 0, string levelName = "",  | ||||
|             string scene = "store", string[] props = null, Dictionary<string, object> extra = null) | ||||
|  | @ -826,7 +700,7 @@ namespace Guru | |||
|             if (string.IsNullOrEmpty(scene)) scene = Consts.ParameterDefaultScene; | ||||
|             LogEarnVirtualCurrencyAndProps(currencyName, value, balance, category, itemName, levelName, scene, null, extra); // TODO 这里的打点不对 | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 通过道具交换/合成或得了其他道具 (earn_virtual_currency) (igb:coin)  | ||||
|         /// </summary> | ||||
|  | @ -836,6 +710,7 @@ namespace Guru | |||
|         /// <param name="value"></param> | ||||
|         /// <param name="balance"></param> | ||||
|         /// <param name="levelName"></param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogEarnPropByProp(string propName, string otherName, | ||||
|             string scene = Consts.ParameterDefaultScene, | ||||
|             int value = 1, int balance = 0, string levelName = "", Dictionary<string, object> extra = null) | ||||
|  | @ -843,8 +718,8 @@ namespace Guru | |||
|             string category = Consts.CurrencyCategoryIGB; | ||||
|             LogEarnVirtualCurrency(propName, value, balance, category, otherName, levelName, scene, extra); | ||||
|         } | ||||
|          | ||||
|          | ||||
| 
 | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 通过转盘或者抽奖, 获取货币/道具 (earn_virtual_currency) (igb:lottery)  | ||||
|         /// <li>通常类型: Coin 收入 </li> | ||||
|  | @ -857,6 +732,7 @@ namespace Guru | |||
|         /// <param name="levelName">当前关卡名称</param> | ||||
|         /// <param name="scene">应用场景</param> | ||||
|         /// <param name="props">获取的道具名称列表</param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogEarnVirtualCurrencyByLottery(string currencyName,  | ||||
|             int value = 0, int balance = 0, string levelName = "",  | ||||
|             string scene = "store", string[] props = null, Dictionary<string, object> extra = null) | ||||
|  | @ -882,6 +758,7 @@ namespace Guru | |||
|         /// <param name="levelName">当前关卡或者人物等级名称</param> | ||||
|         /// <param name="itemName">购买道具名称</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 = "", | ||||
|             string levelName = "", string scene = "", Dictionary<string, object> extra = null) | ||||
|         { | ||||
|  | @ -894,7 +771,6 @@ namespace Guru | |||
|         /// <param name="currencyName">货币/道具名称</param> | ||||
|         /// <param name="value">货币消耗值 10</param> | ||||
|         /// <param name="balance">结算后货币总量 30 -> 20</param> | ||||
|         /// <param name="category"></param> | ||||
|         /// <param name="itemName"></param> | ||||
|         /// <param name="levelName"></param> | ||||
|         /// <param name="scene"></param> | ||||
|  | @ -915,6 +791,7 @@ namespace Guru | |||
|         /// <param name="balance"></param> | ||||
|         /// <param name="levelName"></param> | ||||
|         /// <param name="scene"></param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogSpendVirtualCurrencyWithProp(string currencyName, string prop, | ||||
|             int value, int balance, | ||||
|             string levelName = "", string scene = "", Dictionary<string, object> extra = null) | ||||
|  | @ -932,6 +809,7 @@ namespace Guru | |||
|         /// <param name="balance"></param> | ||||
|         /// <param name="levelName"></param> | ||||
|         /// <param name="scene"></param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogSpendVirtualCurrencyWithProps(string currencyName, string[] props, | ||||
|             int value, int balance,  | ||||
|             string levelName = "", string scene = "", Dictionary<string, object> extra = null) | ||||
|  | @ -957,6 +835,7 @@ namespace Guru | |||
|         /// <param name="balance"></param> | ||||
|         /// <param name="levelName"></param> | ||||
|         /// <param name="scene"></param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogSpendVirtualCurrencyWithBundle(string currencyName, string bundle, | ||||
|             int value, int balance, | ||||
|             string levelName = "", string scene = "", Dictionary<string, object> extra = null) | ||||
|  | @ -973,6 +852,7 @@ namespace Guru | |||
|         /// <param name="balance"></param> | ||||
|         /// <param name="levelName"></param> | ||||
|         /// <param name="scene"></param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogSpendVirtualCurrencyWithBundles(string currencyName, string[] bundles, | ||||
|             int value, int balance,  | ||||
|             string levelName = "", string scene = "", Dictionary<string, object> extra = null) | ||||
|  | @ -988,16 +868,18 @@ namespace Guru | |||
|                 } | ||||
|             } | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 消耗物品, 交换其他物品 (spend_virtual_currency) (prop) | ||||
|         /// </summary> | ||||
|         /// <param name="currencyName"></param> | ||||
|         /// <param name="bundles"></param> | ||||
|         /// <param name="propName"></param> | ||||
|         /// <param name="otherName"></param> | ||||
|         /// <param name="value"></param> | ||||
|         /// <param name="balance"></param> | ||||
|         /// <param name="levelName"></param> | ||||
|         /// <param name="scene"></param> | ||||
|         /// <param name="extraCategory"></param> | ||||
|         /// <param name="extra"></param> | ||||
|         public static void LogSpendPropWithProp(string propName, string otherName, | ||||
|             int value, int balance,  | ||||
|             string levelName = "", string scene = "", string extraCategory = "", Dictionary<string, object> extra = null) | ||||
|  | @ -1272,7 +1154,7 @@ namespace Guru | |||
|             CrashlyticsAgent.Log(message); | ||||
|         } | ||||
|          | ||||
|         public static void CrashException(string message) | ||||
|         public static void CrashLogException(string message) | ||||
|         { | ||||
|             if (!IsFirebaseReady) return; | ||||
|             CrashlyticsAgent.LogException(message); | ||||
|  | @ -1284,7 +1166,7 @@ namespace Guru | |||
|             CrashlyticsAgent.LogException(ex); | ||||
|         } | ||||
| 
 | ||||
|         public static void CrashCustomKeys(string key, string value) | ||||
|         public static void CrashSetCustomKeys(string key, string value) | ||||
|         { | ||||
|             if (!IsFirebaseReady) return; | ||||
|             CrashlyticsAgent.SetCustomKey(key, value); | ||||
|  | @ -1293,6 +1175,7 @@ namespace Guru | |||
| 
 | ||||
|         #region 优先级设置 | ||||
|          | ||||
|         private static readonly Dictionary<string, int> _eventPriorities = new Dictionary<string, int>(10); | ||||
|          | ||||
|         /// <summary> | ||||
|         /// 设置 | ||||
|  | @ -1301,22 +1184,13 @@ namespace Guru | |||
|         /// <param name="eventNames"></param> | ||||
|         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; | ||||
|             string evt = ""; | ||||
|             while (i < eventNames.Length) | ||||
|             { | ||||
|                 evt = eventNames[i]; | ||||
|                 var evt = eventNames[i]; | ||||
|                 if (!string.IsNullOrEmpty(evt)) | ||||
|                 { | ||||
|                     Model.event_priorities[evt] = (int)priority; | ||||
|                     _eventPriorities[evt] = (int)priority; | ||||
|                 } | ||||
|                 i++; | ||||
|             } | ||||
|  | @ -1324,26 +1198,19 @@ namespace Guru | |||
| 
 | ||||
|         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}); | ||||
|         } | ||||
| 
 | ||||
|         public static EventPriority GetEventPriority(string eventName) | ||||
|         { | ||||
|             if (Model.event_priorities != null  | ||||
|                 && Model.event_priorities.TryGetValue(eventName, out int p)) | ||||
|             if (_eventPriorities.TryGetValue(eventName, out int p)) | ||||
|             { | ||||
|                 return (EventPriority)p; | ||||
|             } | ||||
|             return EventPriority.Default; | ||||
|         } | ||||
|          | ||||
|         internal static int GetEventPriorityInt(string eventName) | ||||
| 
 | ||||
|         public static int GetEventPriorityInt(string eventName) | ||||
|         { | ||||
|             return (int)GetEventPriority(eventName); | ||||
|         } | ||||
|  | @ -1351,7 +1218,7 @@ namespace Guru | |||
|         /// <summary> | ||||
|         /// set all events as 'Emergence' event, which will be triggered immediately | ||||
|         /// </summary> | ||||
|         internal void SetSDKEventPriority() | ||||
|         private void SetSDKEventPriority() | ||||
|         { | ||||
|             SetEventPriority(EventPriority.Emergence, new [] | ||||
|             { | ||||
|  | @ -1359,9 +1226,13 @@ namespace Guru | |||
|                 Consts.EventTchAdRev02Impression, | ||||
|                 Consts.EventLevelStart, | ||||
|                 Consts.EventLevelEnd, | ||||
|                 Consts.EventIAPReturnTrue, | ||||
|                 Consts.EventIAPPurchase, | ||||
|             }); | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | @ -1,13 +1,10 @@ | |||
| namespace Guru | ||||
| { | ||||
|     using System; | ||||
|     using UnityEngine; | ||||
|      | ||||
|      | ||||
|     public partial class GuruSDK | ||||
|     { | ||||
| 
 | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 回调参数类 | ||||
|         /// </summary> | ||||
|  | @ -18,22 +15,29 @@ namespace Guru | |||
|             /// </summary> | ||||
|             public static class App | ||||
|             { | ||||
|                 internal static Action<bool> _onAppPaused; | ||||
|                 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); | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action _onAppQuit; | ||||
|                 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> | ||||
|  | @ -47,8 +51,12 @@ namespace Guru | |||
|                     add => _onConsentResult += value; | ||||
|                     remove => _onConsentResult -= value; | ||||
|                 } | ||||
|                 internal static Action<int> _onConsentResult; | ||||
| 
 | ||||
|                 private static Action<int> _onConsentResult; | ||||
|                 internal static void InvokeOnConsentResult(int code) | ||||
|                 { | ||||
|                     _onConsentResult?.Invoke(code); | ||||
|                 } | ||||
|                  | ||||
|                 /// <summary> | ||||
|                 /// ATT 状态返回 | ||||
|                 /// </summary> | ||||
|  | @ -57,8 +65,11 @@ namespace Guru | |||
|                     add => _onAttResult += value; | ||||
|                     remove => _onAttResult -= value; | ||||
|                 } | ||||
|                 internal static Action<int> _onAttResult; | ||||
| 
 | ||||
|                 private static Action<int> _onAttResult; | ||||
|                 internal static void InvokeOnAttResultCallback(int code) | ||||
|                 { | ||||
|                     _onAttResult?.Invoke(code); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             /// <summary> | ||||
|  | @ -66,85 +77,129 @@ namespace Guru | |||
|             /// </summary> | ||||
|             public static class Ads | ||||
|             { | ||||
|                 internal static Action _onAdsInitComplete; | ||||
|                 private static Action _onAdsInitComplete; | ||||
|                 public static event Action OnAdsInitComplete | ||||
|                 { | ||||
|                     add => _onAdsInitComplete += value; | ||||
|                     remove => _onAdsInitComplete -= value; | ||||
|                 } | ||||
|                 internal static void InvokeOnAdsInitComplete() | ||||
|                 { | ||||
|                     _onAdsInitComplete?.Invoke(); | ||||
|                 } | ||||
|                  | ||||
|                 //------------ BANNER ----------------- | ||||
|                 internal static Action<string> _onBannerADStartLoad; | ||||
|                 private static Action<string> _onBannerADStartLoad; | ||||
|                 public static event Action<string> OnBannerADStartLoad | ||||
|                 { | ||||
|                     add => _onBannerADStartLoad += value; | ||||
|                     remove => _onBannerADStartLoad -= value; | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action _onBannerADLoaded; | ||||
|                 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 ----------------- | ||||
|                 internal static Action<string> _onInterstitialADStartLoad; | ||||
|                 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); | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action _onInterstitialADLoaded; | ||||
|                 private static Action _onInterstitialADLoaded; | ||||
|                 public static event Action OnInterstitialADLoaded | ||||
|                 { | ||||
|                     add => _onInterstitialADLoaded += value; | ||||
|                     remove => _onInterstitialADLoaded -= value; | ||||
|                 } | ||||
| 
 | ||||
|                 internal static Action _onInterstitialADFailed; | ||||
|                 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(); | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action _onInterstitialADClosed; | ||||
|                 private static Action _onInterstitialADClosed; | ||||
|                 public static event Action OnInterstitialADClosed | ||||
|                 { | ||||
|                     add => _onInterstitialADClosed += value; | ||||
|                     remove => _onInterstitialADClosed -= value; | ||||
|                 } | ||||
|                 internal static void InvokeOnInterstitialADClosed() | ||||
|                 { | ||||
|                     _onInterstitialADClosed?.Invoke(); | ||||
|                 } | ||||
| 
 | ||||
|                 //------------ REWARD ----------------- | ||||
|                 internal static Action<string> _onRewardedADStartLoad; | ||||
|                 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); | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action _onRewardedADLoaded; | ||||
|                 private static Action _onRewardedADLoaded; | ||||
|                 public static event Action OnRewardedADLoaded | ||||
|                 { | ||||
|                     add => _onRewardedADLoaded += value; | ||||
|                     remove => _onRewardedADLoaded -= value; | ||||
|                 } | ||||
|                 internal static void InvokeOnRewardedADLoaded() | ||||
|                 { | ||||
|                     _onRewardedADLoaded?.Invoke(); | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action _onRewardADClosed; | ||||
|                 private static Action _onRewardADClosed; | ||||
|                 public static event Action OnRewardedADClosed | ||||
|                 { | ||||
|                     add => _onRewardADClosed += value; | ||||
|                     remove => _onRewardADClosed -= value; | ||||
|                 } | ||||
| 
 | ||||
|                 internal static Action _onRewardADFailed; | ||||
|                 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> | ||||
|  | @ -152,12 +207,16 @@ namespace Guru | |||
|             /// </summary> | ||||
|             public static class Remote | ||||
|             { | ||||
|                 internal static Action<bool> _onRemoteFetchComplete; | ||||
|                 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> | ||||
|  | @ -165,89 +224,150 @@ namespace Guru | |||
|             /// </summary> | ||||
|             public static class IAP | ||||
|             { | ||||
|                 internal static Action _onIAPInitStart; | ||||
|                 private static Action _onIAPInitStart; | ||||
|                 public static event Action OnIAPInitStart | ||||
|                 { | ||||
|                     add => _onIAPInitStart += value; | ||||
|                     remove => _onIAPInitStart -= value; | ||||
|                 } | ||||
|                 internal static void InvokeOnIAPInitStart() | ||||
|                 { | ||||
|                     _onIAPInitStart?.Invoke(); | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action<bool> _onIAPInitComplete; | ||||
|                  | ||||
|                 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); | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action<string> _onPurchaseStart; | ||||
|                  | ||||
|                 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); | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action<string, bool> _onPurchaseEnd; | ||||
|                  | ||||
|                 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); | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action<string, string> _onPurchaseFailed; | ||||
|                  | ||||
|                 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); | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action<bool, string> _onIAPRestored; | ||||
|         | ||||
|                 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 | ||||
|             { | ||||
|                 internal static Action<bool> _onFirebaseReady; | ||||
|                 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); | ||||
|                 } | ||||
|                  | ||||
|                 internal static Action _onGuruServiceReady; | ||||
|                 private static Action _onGuruServiceReady; | ||||
|                 public static event Action OnGuruServiceReady | ||||
|                 { | ||||
|                     add => _onGuruServiceReady += value; | ||||
|                     remove => _onGuruServiceReady -= value; | ||||
|                 } | ||||
|                 internal static void InvokeOnGuruServiceReady() | ||||
|                 { | ||||
|                     _onGuruServiceReady?.Invoke(); | ||||
|                 } | ||||
| 
 | ||||
|                 internal static Action<bool> _onDebuggerDisplayed; | ||||
|                 private 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 | ||||
|                 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 Action<bool> _onFirebaseAuthResult; | ||||
|                 public static event Action<bool> OnFirebaseAuthResult | ||||
|                 internal static void InvokeOnGuruUserAuthResult(bool success) | ||||
|                 { | ||||
|                     add => _onFirebaseAuthResult += value; | ||||
|                     remove => _onFirebaseAuthResult -= value; | ||||
|                     _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 | ||||
|     { | ||||
| 	    /// <summary> | ||||
| 	    /// 打点优先级 | ||||
| 	    /// </summary> | ||||
| 		public enum EventPriority | ||||
| 		{ | ||||
| 			Emergence = 0, | ||||
| 			High = 5, | ||||
| 			Default = 10, | ||||
| 			Low = 15 | ||||
| 		} | ||||
| 	     | ||||
| 		 | ||||
|         /// <summary> | ||||
|         /// Consts values | ||||
|  | @ -219,7 +210,7 @@ namespace Guru | |||
| 			public const string ATTOptIn = "att_opt_in"; | ||||
| 			public const string ATTOpOut = "att_opt_out"; | ||||
| 			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的时间 | ||||
|  | @ -235,6 +226,7 @@ namespace Guru | |||
| 			public const string PropertyCoin = "coin"; //当前金币数 | ||||
| 			public const string PropertyExp = "exp"; // 经验值 | ||||
| 			public const string PropertyHp = "hp"; // 生命值/体力 | ||||
| 			public const string PropertyNetwork = "network"; // 网络状态 | ||||
| 			public const string PropertyAndroidID = "android_id"; // Android 平台 AndroidID | ||||
| 			public const string PropertyIDFV = "idfv"; // iOS  平台 IDFV | ||||
| 			public const string PropertyPicture = "picture"; // 玩家在主线的mapid | ||||
|  | @ -264,6 +256,23 @@ namespace Guru | |||
| 			 | ||||
| 			// SDK  | ||||
| 			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 | ||||
| 			 | ||||
|  |  | |||
|  | @ -7,8 +7,6 @@ namespace Guru | |||
|         private const string K_CMD_NAME_WATERMARK = "gurusdk.unity.wm"; | ||||
|         private const string K_CMD_NAME_CONSOLE = "gurusdk.unity.con"; | ||||
|          | ||||
|          | ||||
|          | ||||
|         #region Android 测试入口 | ||||
|          | ||||
|         /// <summary> | ||||
|  |  | |||
|  | @ -6,8 +6,7 @@ namespace Guru | |||
|      | ||||
|     public partial class GuruSDK | ||||
|     { | ||||
|         private static bool _isDebuggerInited = false; | ||||
|         private static bool _useBaseOpions = true; | ||||
|         private static readonly bool _useBaseOptions = true; | ||||
| 
 | ||||
|         private static GuruDebugger _debugger; | ||||
| 
 | ||||
|  | @ -18,7 +17,7 @@ namespace Guru | |||
|                 if (_debugger == null) | ||||
|                 { | ||||
|                     _debugger = GuruDebugger.Instance; | ||||
|                     if (_useBaseOpions) | ||||
|                     if (_useBaseOptions) | ||||
|                     { | ||||
|                         InitDebuggerLayout(); | ||||
|                     } | ||||
|  | @ -26,7 +25,6 @@ namespace Guru | |||
|                 return _debugger; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|          | ||||
|         /// <summary> | ||||
|         /// 显示广告状态 | ||||
|  | @ -38,9 +36,7 @@ namespace Guru | |||
|             Debugger.ShowAdStatus(); | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|          | ||||
|         /// <summary> | ||||
|         /// 显示 Debugger | ||||
|         /// </summary> | ||||
|  | @ -98,17 +94,15 @@ namespace Guru | |||
|              | ||||
|             GuruDebugger.OnClosed -= OnDebuggerClosed; | ||||
|             GuruDebugger.OnClosed += OnDebuggerClosed; | ||||
|             Callbacks.SDK._onDebuggerDisplayed?.Invoke(true); | ||||
|             Callbacks.SDK.InvokeOnDebuggerDisplayed(true); | ||||
|         } | ||||
|          | ||||
|          | ||||
|         private static void OnDebuggerClosed() | ||||
|         { | ||||
|             GuruDebugger.OnClosed -= OnDebuggerClosed; | ||||
|             Callbacks.SDK._onDebuggerDisplayed?.Invoke(false); | ||||
|             Callbacks.SDK.InvokeOnDebuggerDisplayed(false); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|          | ||||
|         /// <summary> | ||||
|         /// 显示 Debugger | ||||
|         /// </summary> | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| namespace Guru | ||||
| { | ||||
|     using UnityEngine; | ||||
|     using System; | ||||
|     using System.Linq; | ||||
|      | ||||
|  | @ -32,7 +31,7 @@ namespace Guru | |||
|             GuruIAP.Instance.OnBuyFailed += OnBuyFailed; | ||||
|             GuruIAP.Instance.OnGetProductReceipt += OnGetReceipt; | ||||
|              | ||||
|             Callbacks.IAP._onIAPInitStart?.Invoke(); // 初始化之前进行调用 | ||||
|             Callbacks.IAP.InvokeOnIAPInitStart(); // 初始化之前进行调用 | ||||
|              | ||||
|             GuruIAP.Instance.InitWithKeys(uid, googleKey, appleRootCerts, IsDebugMode); | ||||
|         } | ||||
|  | @ -45,7 +44,7 @@ namespace Guru | |||
|         { | ||||
|             LogI($"IAP init result: {success}"); | ||||
|             IsIAPReady = success; | ||||
|             Callbacks.IAP._onIAPInitComplete?.Invoke(success); | ||||
|             Callbacks.IAP.InvokeOnIAPInitComplete(success); | ||||
|         } | ||||
| 
 | ||||
|         private static bool CheckIAPReady() | ||||
|  | @ -70,7 +69,7 @@ namespace Guru | |||
|         /// <returns></returns> | ||||
|         public static ProductInfo GetProductInfo(string productName) | ||||
|         { | ||||
|             return GuruIAP.Instance?.GetInfo(productName) ?? null; | ||||
|             return GuruIAP.Instance?.GetInfo(productName); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  | @ -80,7 +79,7 @@ namespace Guru | |||
|         /// <returns></returns> | ||||
|         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 | ||||
|          | ||||
|         private static Action<string, bool> _onPurchaseCallback; | ||||
|         private static Action<string, bool> InvokeOnPurchaseCallback; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 老接口, 将会被废弃 | ||||
|  | @ -150,7 +149,7 @@ namespace Guru | |||
|         { | ||||
|             if (CheckIAPReady()) | ||||
|             { | ||||
|                 _onPurchaseCallback = purchaseCallback; | ||||
|                 InvokeOnPurchaseCallback = purchaseCallback; | ||||
|                 GuruIAP.Instance.Buy(productName, category); | ||||
|             } | ||||
|         } | ||||
|  | @ -181,9 +180,8 @@ namespace Guru | |||
|         /// <param name="success"></param> | ||||
|         private static void OnBuyEnd(string productName, bool success) | ||||
|         { | ||||
|             if (success) Model.PurchasedCount++; | ||||
|             _onPurchaseCallback?.Invoke(productName, success); | ||||
|             Callbacks.IAP._onPurchaseEnd?.Invoke(productName, success); | ||||
|             InvokeOnPurchaseCallback?.Invoke(productName, success); | ||||
|             Callbacks.IAP.InvokeOnPurchaseEnd(productName, success); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -192,7 +190,7 @@ namespace Guru | |||
|         /// <param name="productName"></param> | ||||
|         private static void OnBuyStart(string productName) | ||||
|         { | ||||
|             Callbacks.IAP._onPurchaseStart?.Invoke(productName); | ||||
|             Callbacks.IAP.InvokeOnPurchaseStart(productName); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  | @ -202,7 +200,7 @@ namespace Guru | |||
|         /// <param name="reason"></param> | ||||
|         private static void OnBuyFailed(string productName, string reason) | ||||
|         { | ||||
|             Callbacks.IAP._onPurchaseFailed?.Invoke(productName, reason); | ||||
|             Callbacks.IAP.InvokeOnPurchaseFailed(productName, reason); | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
|  | @ -223,7 +221,7 @@ namespace Guru | |||
|         } | ||||
|         private static void OnRestored(bool success, string msg) | ||||
|         { | ||||
|             Callbacks.IAP._onIAPRestored?.Invoke(success, msg); // 更新回复购买回调 | ||||
|             Callbacks.IAP.InvokeOnIAPRestored(success, msg); // 更新回复购买回调 | ||||
|         } | ||||
|          | ||||
|         #endregion | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| 
 | ||||
| namespace Guru | ||||
| { | ||||
|     public partial class GuruSDK | ||||
|  | @ -75,29 +76,30 @@ namespace Guru | |||
|         { | ||||
|             Model.IsNoAds = value; | ||||
|             ADService.Instance.IsBuyNoAds = value; | ||||
|             SetUserProperty(Consts.PropertyNoAds, value? "true" : "false"); | ||||
|             if(value) SetUserIsIAP(true); | ||||
|             if (value) | ||||
|             { | ||||
|                 Analytics.SetIsIapUser(true); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 所有成功的主线关卡数量 (b_level) | ||||
|         /// </summary> | ||||
|         public static int SuccessLevelCount | ||||
|         public static int BLevel | ||||
|         { | ||||
|             get => GuruSDKModel.Instance.SuccessLevelId; | ||||
|             set => GuruSDKModel.Instance.SuccessLevelId = value; | ||||
|             get => GuruSDKModel.Instance.BLevel; | ||||
|             set => GuruSDKModel.Instance.BLevel = value; | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// 成功关卡总计数量 (b_play) | ||||
|         /// </summary> | ||||
|         public static int TotalPlayedCount | ||||
|         public static int BPlay | ||||
|         { | ||||
|             get => GuruSDKModel.Instance.TotalPlayedCount; | ||||
|             set => GuruSDKModel.Instance.TotalPlayedCount = value; | ||||
|             get => GuruSDKModel.Instance.BPlay; | ||||
|             set => GuruSDKModel.Instance.BPlay = value; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|          | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -38,19 +38,37 @@ namespace Guru | |||
|         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) | ||||
|         { | ||||
|             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) | ||||
|         { | ||||
|             RemoteConfigManager.UnRegisterOnValueChanged(key, onValueChanged); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// 获取所有云控配置 | ||||
|         /// </summary> | ||||
|         /// <returns></returns> | ||||
|         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); | ||||
|          | ||||
|     } | ||||
|  |  | |||
|  | @ -44,8 +44,7 @@ namespace Guru | |||
|         } | ||||
|          | ||||
|         #endregion | ||||
| 
 | ||||
| 
 | ||||
|          | ||||
|         #region Android System | ||||
| 
 | ||||
| #if UNITY_ANDROID | ||||
|  | @ -78,7 +77,21 @@ namespace Guru | |||
| #endif | ||||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         #region Clear Data Cache | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// 清除数据缓存 | ||||
|         /// </summary> | ||||
|         public static void ClearData() | ||||
|         { | ||||
|             Model.ClearData(); | ||||
|             GuruIAP.Instance.ClearData(); | ||||
|             PlayerPrefs.DeleteAll(); | ||||
|             PlayerPrefs.Save(); | ||||
|         } | ||||
|          | ||||
|         #endregion | ||||
|          | ||||
|     } | ||||
| } | ||||
|  | @ -4,16 +4,17 @@ namespace Guru | |||
|     using System; | ||||
|     using System.Collections; | ||||
|     using System.Collections.Generic; | ||||
|     using System.IO; | ||||
|     using Debug = UnityEngine.Debug; | ||||
|     using Guru.Network; | ||||
|     using System.Linq; | ||||
|      | ||||
|     public partial class GuruSDK: MonoBehaviour | ||||
|     { | ||||
|         // SDK_VERSION | ||||
|         public const string Version = "1.0.14";  | ||||
|         public const string Version = "1.1.0";  | ||||
|          | ||||
|         // Const | ||||
|         public const string Tag = "[Guru]"; | ||||
|         private const string Tag = "[Guru]"; | ||||
|         public const string ServicesConfigKey = "guru_services"; | ||||
|          | ||||
|         private static GuruSDK _instance; | ||||
|  | @ -34,10 +35,9 @@ namespace Guru | |||
|         } | ||||
| 
 | ||||
|         private GuruSDKInitConfig _initConfig; | ||||
|         private Action<bool> _onCompleteCallback; | ||||
| 
 | ||||
|         internal static GuruSDKInitConfig InitConfig => Instance._initConfig; | ||||
|         internal static GuruSDKModel Model => GuruSDKModel.Instance; | ||||
|         private static GuruSDKInitConfig InitConfig => Instance._initConfig; | ||||
|         private static GuruSDKModel Model => GuruSDKModel.Instance; | ||||
|         private static GuruServicesConfig _appServicesConfig; | ||||
|         private static GuruSettings _guruSettings; | ||||
|         private static GuruSettings GuruSettings | ||||
|  | @ -78,6 +78,12 @@ namespace Guru | |||
|         /// </summary> | ||||
|         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 初始化 | ||||
|          | ||||
|         private static GuruSDK CreateInstance() | ||||
|  | @ -87,49 +93,22 @@ namespace Guru | |||
|             _instance = go.AddComponent<GuruSDK>(); | ||||
|             return _instance; | ||||
|         } | ||||
| 
 | ||||
|         public static GuruSDKInitConfig BuildConfig( | ||||
|             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; | ||||
|         } | ||||
| 
 | ||||
|          | ||||
|         // TODO : 下个版本需要将 整个 GuruSDK 做功能性的拆分 | ||||
|          | ||||
|         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) | ||||
|         { | ||||
|             _initTime = DateTime.Now.ToUniversalTime(); | ||||
|             _initTime = DateTime.UtcNow; | ||||
|             // ----- First Open Time ----- | ||||
|             // SetFirstOpenTime(GetFirstOpenTime());  // FirstOpenTime  | ||||
|             LogI($"#1 ---- Guru SDK [{Version}] ----\n{config.ToString()}"); | ||||
|             LogI($"#1 ---- Guru SDK [{Version}] ----\n{config}"); | ||||
|             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> | ||||
|         /// 启动SDK | ||||
|  | @ -138,116 +117,57 @@ namespace Guru | |||
|         /// <param name="onComplete"></param> | ||||
|         private void StartWithConfig(GuruSDKInitConfig config, Action<bool> onComplete) | ||||
|         { | ||||
|             Model.PropBLevel.OnValueChanged += OnBLevelChanged; | ||||
|             Model.PropBPlay.OnValueChanged += OnBPlayChanged; | ||||
|              | ||||
|             IsInitialSuccess = false; | ||||
|             _initConfig = config; | ||||
|             _onCompleteCallback = onComplete; | ||||
|             _isDebugEnabled = config.DebugMode; | ||||
| 
 | ||||
|             InitAssets(); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         private void InitAssets() | ||||
|         { | ||||
|             if (config.EnableDebugLogEvent) Analytics.EnableDebugAnalytics = true; // 允许 Debug 模式下打点 | ||||
|             if (!config.AutoNotificationPermission) FirebaseUtil.SetAutoFetchFcmToken(false); // 不允许自动启动获取 FCM Token | ||||
|              | ||||
|             InitUpdaters(); // Updaters | ||||
|             InitThreadHandler(); // 初始化线程处理器 | ||||
|             InitServices(); // 初始化所有的服务 | ||||
|             InitNetworkMonitor(); // 网络状态 | ||||
|              | ||||
|             onComplete?.Invoke(true); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         void Start() | ||||
|         private void InitServices() | ||||
|         { | ||||
|             //---------- 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 ---- | ||||
|             LogI($"#2 --- InitFirebase ---"); | ||||
|             //---------- Start Firebase ------------ | ||||
|             FirebaseUtil.onInitComplete += OnFirebaseReady; | ||||
|             FirebaseUtil.OnUserAuthResult += OnUserAuthResult; | ||||
|             FirebaseUtil.OnFirebaseAuthResult += OnFirebaseAuthResult; | ||||
|             FirebaseUtil.InitFirebase(null); // 确保所有的逻辑提前被调用到 + Analytics.Init TODO:之后需要改为事件驱动 | ||||
|              | ||||
|             StartFirebaseService(); | ||||
|             LogI($"#2.1 --- InitFacebook ---"); | ||||
|             //---------- 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; | ||||
|             _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> | ||||
|         /// <param name="dict"></param> | ||||
|         /// <returns></returns> | ||||
|         private Dictionary<string, object> BuildDefaultRemoteData(Dictionary<string, object> dict) | ||||
|         private string LoadDefaultGuruServiceJson() | ||||
|         { | ||||
|             if (dict == null) dict = new Dictionary<string, object>(3); | ||||
|              | ||||
|             // 注入默认的 Services 配置值 | ||||
|             string json = Model.LoadDefaltServicesConfigJson();  | ||||
|             if (!string.IsNullOrEmpty(json)) dict[ServicesConfigKey] = json; | ||||
|         | ||||
|             return dict; | ||||
|             // 加载本地 Services 配置值 | ||||
|             var txtAsset = Resources.Load<TextAsset>(ServicesConfigKey); | ||||
|             if (txtAsset != null) | ||||
|             { | ||||
|                 return txtAsset.text; | ||||
|             } | ||||
|             return ""; | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  | @ -258,11 +178,9 @@ namespace Guru | |||
|         { | ||||
|             LogI($"#6 --- Remote fetch complete: {success} ---"); | ||||
|             ABTestManager.Init(); // 启动AB测试解析器 | ||||
|             Callbacks.Remote._onRemoteFetchComplete?.Invoke(success); | ||||
|             Callbacks.Remote.InvokeOnRemoteFetchComplete(success); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         private void Update() | ||||
|         { | ||||
|             UpdateAllUpdates(); // 驱动所有的更新器 | ||||
|  | @ -276,18 +194,17 @@ namespace Guru | |||
|         /// <summary> | ||||
|         /// Apply Cloud guru-service configs for sdk assets | ||||
|         /// </summary> | ||||
|         private void InitAllServices() | ||||
|         private void InitAllGuruServices() | ||||
|         { | ||||
|             // -------- Init Analytics --------- | ||||
|             InitUserProperties(); | ||||
|             SetSDKEventPriority(); | ||||
|             // -------- Init Noti ----------- | ||||
|             // -------- Init Notification ----------- | ||||
|             InitNotiPermission(); | ||||
|              | ||||
|             bool useKeywords = false; | ||||
|             bool useIAP = _initConfig.IAPEnabled; | ||||
|             bool appleReview = false; | ||||
|             bool enableAnaErrorLog = false; | ||||
|             // bool enableAnaErrorLog = false; | ||||
|              | ||||
|             //----------- Set GuruServices ---------------- | ||||
|             var services = GetRemoteServicesConfig(); | ||||
|  | @ -297,7 +214,7 @@ namespace Guru | |||
|                 useKeywords = _appServicesConfig.KeywordsEnabled(); | ||||
|                 // 使用初始化配置中的 IAPEnable来联合限定, 如果本地写死关闭则不走云控开启 | ||||
|                 useIAP = _initConfig.IAPEnabled && _appServicesConfig.IsIAPEnabled();  | ||||
|                 enableAnaErrorLog = _appServicesConfig.EnableAnaErrorLog(); | ||||
|                 // enableAnaErrorLog = _appServicesConfig.EnableAnaErrorLog(); | ||||
|                  | ||||
|                 Try(() => | ||||
|                 { | ||||
|  | @ -305,7 +222,7 @@ namespace Guru | |||
|                     //---------------------------------------------------------------- | ||||
| 
 | ||||
|                     // 自打点设置错误上报 | ||||
|                     if(enableAnaErrorLog) GuruAnalytics.EnableErrorLog = true; | ||||
|                     // if(enableAnaErrorLog) GuruAnalytics.EnableErrorLog = true; | ||||
|                      | ||||
|                     // adjust 事件设置 | ||||
|                     if (null != _appServicesConfig.adjust_settings && null != GuruSettings) | ||||
|  | @ -318,7 +235,7 @@ namespace Guru | |||
|                         GuruSettings.UpdateAdjustEvents(_appServicesConfig.adjust_settings.events); | ||||
|                     } | ||||
|                  | ||||
|                     LogI($"#4.2 --- Start GuruSttings ---"); | ||||
|                     LogI($"#4.2 --- Start GuruSettings ---"); | ||||
|                     // GuruSettings 设置 | ||||
|                     if (null != _appServicesConfig.app_settings) | ||||
|                     { | ||||
|  | @ -359,7 +276,7 @@ namespace Guru | |||
|                     //--------------------------------- | ||||
|                 }, ex => | ||||
|                 { | ||||
|                     UnityEngine.Debug.LogError($"--- ERROR on apply services: {ex.Message}"); | ||||
|                     Debug.LogError($"--- ERROR on apply services: {ex.Message}"); | ||||
|                 }); | ||||
|            | ||||
|                  | ||||
|  | @ -373,14 +290,13 @@ namespace Guru | |||
|                     LogI($"#4.3 --- Start IAP ---"); | ||||
|                     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 | ||||
|                 }, ex => | ||||
|                 { | ||||
|                     UnityEngine.Debug.LogError($"--- ERROR on useIAP: {ex.Message}"); | ||||
|                     Debug.LogError($"--- ERROR on useIAP: {ex.Message}"); | ||||
|                 }); | ||||
|             } | ||||
|             //----------- Set Keywords ---------------- | ||||
|  | @ -390,10 +306,10 @@ namespace Guru | |||
|                 Try(() => | ||||
|                 { | ||||
|                     LogI($"#4.4 --- Start Keywords ---"); | ||||
|                     KeywordsManager.Install(Model.IsIapUser, Model.SuccessLevelId); // 启动Keyword管理器 | ||||
|                     KeywordsManager.Install(Model.IsIapUser, Model.BLevel); // 启动Keyword管理器 | ||||
|                 }, ex => | ||||
|                 { | ||||
|                     UnityEngine.Debug.LogError($"--- ERROR on Keywords: {ex.Message}"); | ||||
|                     Debug.LogError($"--- ERROR on Keywords: {ex.Message}"); | ||||
|                 }); | ||||
|             } | ||||
| 
 | ||||
|  | @ -403,7 +319,7 @@ namespace Guru | |||
|                 // StartAppleReviewFlow(); // 直接显示 ATT 弹窗, 跳过 Consent 流程 | ||||
|                 Try(() => | ||||
|                 { | ||||
|                     LogI($"#4.5.0 ---  StartAppleReviewFlow ---"); | ||||
|                     LogI($"#4.5 ---  StartAppleReviewFlow ---"); | ||||
|                     StartAppleReviewFlow(); // 直接显示 ATT 弹窗, 跳过 Consent 流程 | ||||
|                 }, ex => | ||||
|                 { | ||||
|  | @ -415,26 +331,23 @@ namespace Guru | |||
|             //----------- Set Consent ---------------- | ||||
|             if (!InitConfig.UseCustomConsent && !appleReview) | ||||
|             { | ||||
|                 // LogI($"--- #3 Start Consent Flow ---"); | ||||
|                 // StartConsentFlow(); | ||||
|                 Try(() => | ||||
|                 LogI($"#4.6 --- Start Consent Flow ---"); | ||||
|                 Try(StartConsentFlow, ex => | ||||
|                 { | ||||
|                     StartConsentFlow(); | ||||
|                 }, ex => | ||||
|                 { | ||||
|                     UnityEngine.Debug.LogError($"--- ERROR on StartConsentFlow: {ex.Message}"); | ||||
|                     Debug.LogError($"--- ERROR on StartConsentFlow: {ex.Message}"); | ||||
|                 }); | ||||
|             } | ||||
| 
 | ||||
|             IsServiceReady = true; | ||||
|              | ||||
|             // 中台服务初始化结束 | ||||
|             Callbacks.SDK._onGuruServiceReady?.Invoke(); | ||||
|              | ||||
| #if UNITY_ANDROID | ||||
|             LogI($"#5.1 --- Android StartAndroidDebug Cmd lines---"); | ||||
|             // Android 命令行调试 | ||||
|             StartAndroidDebugCmds();            | ||||
| #endif | ||||
|              | ||||
|             IsServiceReady = true; | ||||
|              | ||||
|             // 中台服务初始化结束 | ||||
|             Callbacks.SDK.InvokeOnGuruServiceReady(); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  | @ -460,7 +373,7 @@ namespace Guru | |||
|             { | ||||
|                 // No remote data fetched from cloud, should use default values | ||||
|                 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)) | ||||
|  | @ -481,7 +394,7 @@ namespace Guru | |||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 LogException(ex); | ||||
|                 LogEx(ex); | ||||
|                 // ignored | ||||
|                 onException?.Invoke(ex); | ||||
|             } | ||||
|  | @ -505,46 +418,32 @@ namespace Guru | |||
| #endif | ||||
|         #endregion | ||||
|          | ||||
|         #region 数据 | ||||
| 
 | ||||
|         private void OnBLevelChanged(int blevel) | ||||
|         { | ||||
|             SetUserBLevel(blevel); | ||||
|         } | ||||
| 
 | ||||
|         private void OnBPlayChanged(int bplay) | ||||
|         { | ||||
|             SetUserBPlay(bplay); | ||||
|         } | ||||
|          | ||||
|         #endregion | ||||
|          | ||||
|         #region Logging | ||||
|          | ||||
|         internal static void LogI(object message) | ||||
| 
 | ||||
|         private static void LogI(object message) | ||||
|         { | ||||
|             UnityEngine.Debug.Log($"{Tag} {message}"); | ||||
|         } | ||||
|          | ||||
|         internal static void LogW(object message) | ||||
|         { | ||||
|             UnityEngine.Debug.LogWarning($"{Tag} {message}"); | ||||
|         } | ||||
|          | ||||
|         internal static void LogE(object message) | ||||
|         { | ||||
|             UnityEngine.Debug.LogError($"{Tag} {message}"); | ||||
|             Debug.Log($"{Tag} {message}"); | ||||
|         } | ||||
| 
 | ||||
|          | ||||
|         internal static void LogException(string message) | ||||
|         private static void LogW(object message) | ||||
|         { | ||||
|             LogException( new Exception($"{Tag} {message}")); | ||||
|             Debug.LogWarning($"{Tag} {message}"); | ||||
|         } | ||||
|          | ||||
|         internal static void LogException(Exception e) | ||||
| 
 | ||||
|         private static void LogE(object message) | ||||
|         { | ||||
|             UnityEngine.Debug.LogException(e); | ||||
|             Debug.LogError($"{Tag} {message}"); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         private static void LogEx(string message) | ||||
|         { | ||||
|             LogEx( new Exception($"{Tag} {message}")); | ||||
|         } | ||||
| 
 | ||||
|         private static void LogEx(Exception e) | ||||
|         { | ||||
|             Debug.LogException(e); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  | @ -585,7 +484,7 @@ namespace Guru | |||
|         private void OnAppPauseHandler(bool paused) | ||||
|         { | ||||
|             if(paused) Model.Save(true); // 强制保存数据 | ||||
|             Callbacks.App._onAppPaused?.Invoke(paused); | ||||
|             Callbacks.App.InvokeOnAppPaused(paused); | ||||
|         } | ||||
|          | ||||
|         private void OnApplicationPause(bool paused) | ||||
|  | @ -601,7 +500,7 @@ namespace Guru | |||
|         private void OnApplicationQuit() | ||||
|         { | ||||
|             Model.Save(true); | ||||
|             Callbacks.App._onAppQuit?.Invoke(); | ||||
|             Callbacks.App.InvokeOnAppQuit(); | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
|  | @ -664,14 +563,13 @@ namespace Guru | |||
|         private void UpdateAllUpdates() | ||||
|         { | ||||
|             int i = 0; | ||||
|             IUpdater updater; | ||||
|             // ---- Updater Trigger ---- | ||||
|             if (_updaterRunningList.Count > 0) | ||||
|             { | ||||
|                 i = 0; | ||||
|                 while (i < _updaterRunningList.Count) | ||||
|                 { | ||||
|                     updater = _updaterRunningList[i]; | ||||
|                     var updater = _updaterRunningList[i]; | ||||
|                     if (updater != null)  | ||||
|                     { | ||||
|                         if (updater.State == UpdaterState.Running) | ||||
|  | @ -732,12 +630,12 @@ namespace Guru | |||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         #region 推送管理 | ||||
|         #region 中台推送管理 | ||||
| 
 | ||||
|         private static int _messageRetry = 0; | ||||
|         public static void SetPushNotificationEnabled(bool enabled) | ||||
|         { | ||||
|             DeviceInfoUploadRequest request = new DeviceInfoUploadRequest() | ||||
|             DeviceInfoUploadRequest request = (DeviceInfoUploadRequest) new DeviceInfoUploadRequest() | ||||
|                 .SetRetryTimes(1) | ||||
|                 .SetSuccessCallBack(() => | ||||
|                 { | ||||
|  | @ -749,15 +647,197 @@ namespace Guru | |||
|                     double retryDelay = Math.Pow(2, _messageRetry); | ||||
|                     _messageRetry++; | ||||
|                     CoroutineHelper.Instance.StartDelayed((float)retryDelay, ()=> SetPushNotificationEnabled(enabled)); | ||||
|                 }) as DeviceInfoUploadRequest; | ||||
|                 }); | ||||
| 
 | ||||
|             if (request != null) | ||||
|             { | ||||
|                 request.SetPushEnabled(enabled); | ||||
|                 request.Send(); | ||||
|             } | ||||
|             if (request == null) return; | ||||
|              | ||||
|             request.SetPushEnabled(enabled); | ||||
|             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 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -1,7 +1,7 @@ | |||
| { | ||||
|   "name": "com.guru.unity.sdk", | ||||
|   "displayName": "Guru SDK", | ||||
|   "version": "1.0.14", | ||||
|   "version": "1.1.0", | ||||
|   "description": "Guru SDK for unity project", | ||||
|   "unity": "2020.3", | ||||
|   "author":{ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue