Compare commits
No commits in common. "main" and "dev" have entirely different histories.
|
|
@ -5,8 +5,7 @@ dependencies {
|
|||
}
|
||||
|
||||
android {
|
||||
namespace "**NAMESPACE**"
|
||||
compileSdkVersion **TARGETSDKVERSION**
|
||||
compileSdkVersion **APIVERSION**
|
||||
buildToolsVersion '**BUILDTOOLS**'
|
||||
|
||||
compileOptions {
|
||||
|
|
@ -23,7 +22,6 @@ android {
|
|||
}
|
||||
versionCode **VERSIONCODE**
|
||||
versionName '**VERSIONNAME**'
|
||||
multiDexEnabled true
|
||||
}
|
||||
|
||||
aaptOptions {
|
||||
|
|
|
|||
|
|
@ -11,28 +11,28 @@ namespace Guru.Editor
|
|||
public class AndroidProjectMod
|
||||
{
|
||||
private const int TargetSDKVersion = 34;
|
||||
private const string K_ANDROID_PLUGINS_NAME = "Plugins/Android";
|
||||
private const string K_ANRDROID_PLUGINS_NAME = "Plugins/Android";
|
||||
|
||||
private const string LauncherName = "launcherTemplate";
|
||||
private static readonly string LauncherFullPath = Path.Combine(Application.dataPath, $"{K_ANDROID_PLUGINS_NAME}/{LauncherName}.gradle");
|
||||
private static string LauncherFullPath = Path.Combine(Application.dataPath, $"{K_ANRDROID_PLUGINS_NAME}/{LauncherName}.gradle");
|
||||
|
||||
private const string MainName = "mainTemplate";
|
||||
private static readonly string MainFullPath = Path.Combine(Application.dataPath, $"{K_ANDROID_PLUGINS_NAME}/{MainName}.gradle");
|
||||
private static string MainFullPath = Path.Combine(Application.dataPath, $"{K_ANRDROID_PLUGINS_NAME}/{MainName}.gradle");
|
||||
|
||||
private const string BaseProjectName = "baseProjectTemplate";
|
||||
private static readonly string BaseProjectFullPath = Path.Combine(Application.dataPath, $"{K_ANDROID_PLUGINS_NAME}/{BaseProjectName}.gradle");
|
||||
private static string BaseProjectFullPath = Path.Combine(Application.dataPath, $"{K_ANRDROID_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 static string PropertiesFullPath = Path.Combine(Application.dataPath, $"{K_ANRDROID_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 static string SettingsFullPath = Path.Combine(Application.dataPath, $"Plugins/Android/{SettingsName}.gradle");
|
||||
private const string K_LINE_UNITYPROJECT = "def unityProjectPath";
|
||||
|
||||
|
||||
private const string ProguardUserName = "proguard-user";
|
||||
private static readonly string ProguardUserFullPath = Path.Combine(Application.dataPath, $"{K_ANDROID_PLUGINS_NAME}/{ProguardUserName}.txt");
|
||||
private static string ProguardUserFullPath = Path.Combine(Application.dataPath, $"{K_ANRDROID_PLUGINS_NAME}/{ProguardUserName}.txt");
|
||||
|
||||
public static void Apply()
|
||||
{
|
||||
|
|
@ -40,11 +40,12 @@ namespace Guru.Editor
|
|||
ApplyBaseProjectTemplates();
|
||||
ApplyMainTemplates();
|
||||
ApplyGradleTemplate();
|
||||
ApplySettings();
|
||||
// ApplySettings();
|
||||
ApplyProguardUser();
|
||||
CheckTargetSDKVersion(); // 强制修复构建版本号
|
||||
}
|
||||
|
||||
|
||||
private static void ApplyLauncher()
|
||||
{
|
||||
if (!File.Exists(LauncherFullPath))
|
||||
|
|
@ -58,9 +59,10 @@ namespace Guru.Editor
|
|||
var ptn2 = "abortOnError false";
|
||||
var lines = File.ReadAllLines(LauncherFullPath);
|
||||
|
||||
string line = "";
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
var line = lines[i];
|
||||
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");
|
||||
|
|
@ -96,6 +98,8 @@ namespace Guru.Editor
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void ApplyGradleTemplate()
|
||||
{
|
||||
if (!File.Exists(PropertiesFullPath))
|
||||
|
|
@ -110,10 +114,6 @@ namespace Guru.Editor
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 该版本中不再使用 R8
|
||||
/// </summary>
|
||||
/// <param name="filePath"></param>
|
||||
private static void FixGradleTemplate(string filePath)
|
||||
{
|
||||
if (File.Exists(filePath))
|
||||
|
|
@ -123,7 +123,7 @@ namespace Guru.Editor
|
|||
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (lines[i].Contains(K_ENABLE_R8))
|
||||
if (lines[i].StartsWith(K_ENABLE_R8))
|
||||
{
|
||||
lines[i] = $"# {lines[i]}"; // 禁用R8
|
||||
isDirty = true;
|
||||
|
|
@ -137,7 +137,7 @@ namespace Guru.Editor
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// 写入 settings.gradle 配置文件
|
||||
/// 写入所有的配置文件
|
||||
/// </summary>
|
||||
private static void ApplySettings()
|
||||
{
|
||||
|
|
@ -148,6 +148,7 @@ namespace Guru.Editor
|
|||
FixProjectPathInSettings(SettingsFullPath);
|
||||
}
|
||||
|
||||
|
||||
private static void FixProjectPathInSettings(string settingsPath)
|
||||
{
|
||||
bool isDirty = false;
|
||||
|
|
@ -157,7 +158,7 @@ namespace Guru.Editor
|
|||
var lines = File.ReadAllLines(settingsPath);
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (lines[i].Contains(K_LINE_UNITY_PROJECT))
|
||||
if (lines[i].Contains(K_LINE_UNITYPROJECT))
|
||||
{
|
||||
lines[i] = $" def unityProjectPath = $/file:////{projectPath}/$.replace(\"\\\\\", \"/\")";
|
||||
isDirty = true;
|
||||
|
|
|
|||
|
|
@ -497,7 +497,6 @@ namespace Guru.Editor
|
|||
{
|
||||
ReadServiceConfig(); // Read file again
|
||||
CheckAllComponents();
|
||||
ExecuteAdditionalCommands();
|
||||
}, null, GUILayout.Height(btnH));
|
||||
}
|
||||
|
||||
|
|
@ -505,14 +504,7 @@ namespace Guru.Editor
|
|||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行其他的命令
|
||||
/// </summary>
|
||||
private void ExecuteAdditionalCommands()
|
||||
{
|
||||
// 部署 Adjust Signature V3
|
||||
DeployAdjustSignatureV3Files();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
|
@ -1253,18 +1245,6 @@ namespace Guru.Editor
|
|||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region OtherCommands
|
||||
|
||||
/// <summary>
|
||||
/// 使用 Adjust 签名 V3 导入项目
|
||||
/// </summary>
|
||||
private void DeployAdjustSignatureV3Files()
|
||||
{
|
||||
AdjustSignatureHelper.DeployFiles();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@
|
|||
"Guru.LitJson",
|
||||
"Guru.Runtime",
|
||||
"MaxSdk.Scripts.IntegrationManager.Editor",
|
||||
"Guru.Editor",
|
||||
"GuruAdjust.Editor"
|
||||
"Guru.Editor"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
namespace Guru
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -8,10 +7,8 @@ namespace Guru
|
|||
/// <summary>
|
||||
/// 启动参数配置
|
||||
/// </summary>
|
||||
public class GuruSDKInitConfig
|
||||
public partial class GuruSDKInitConfig
|
||||
{
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// 使用自定义的ConsentFlow启动流程
|
||||
/// </summary>
|
||||
|
|
@ -31,8 +28,7 @@ namespace Guru
|
|||
/// <summary>
|
||||
/// 自动记录完成的关卡
|
||||
/// </summary>
|
||||
[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;
|
||||
public bool AutoRecordFinishedLevels = true;
|
||||
/// <summary>
|
||||
/// 自定义 Service 云控 Key
|
||||
/// </summary>
|
||||
|
|
@ -40,7 +36,7 @@ namespace Guru
|
|||
/// <summary>
|
||||
/// Banner 背景颜色 Hex 值
|
||||
/// </summary>
|
||||
public string BannerBackgroundColor = "#00000040";
|
||||
public string BannerBackgroundColor = "#00000000";
|
||||
/// <summary>
|
||||
/// 已购买去广告道具
|
||||
/// </summary>
|
||||
|
|
@ -53,24 +49,11 @@ namespace Guru
|
|||
/// Debug模式下开启打点(默认关闭)
|
||||
/// </summary>
|
||||
public bool EnableDebugLogEvent = false;
|
||||
|
||||
private Dictionary<string, object> _defaultRemoteData = new Dictionary<string, object>();
|
||||
/// <summary>
|
||||
/// 云控参数的默认配置
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Dictionary<string, object> DefaultRemoteData
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
_defaultRemoteData = value;
|
||||
}
|
||||
}
|
||||
get => _defaultRemoteData;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> DefaultRemoteData = new Dictionary<string, object>();
|
||||
/// <summary>
|
||||
/// 启用 AdjustDeeplink
|
||||
/// </summary>
|
||||
|
|
@ -82,6 +65,49 @@ namespace Guru
|
|||
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,
|
||||
Action<string> onAdjustDeeplinkCallback = null,
|
||||
Dictionary<string, object> defaultRemoteData = null,
|
||||
byte[] googleKeys = null,
|
||||
byte[] appleRootCerts = null,
|
||||
bool debugEnableEventLog = false)
|
||||
{
|
||||
// 创建启动用参数
|
||||
GuruSDKInitConfig config = new GuruSDKInitConfig()
|
||||
{
|
||||
UseCustomConsent = useCustomConsent,
|
||||
AutoLoadWhenAdsReady = autoLoadAds,
|
||||
IAPEnabled = iapEnabled,
|
||||
AutoRecordFinishedLevels = autoRecordFinishedLevels,
|
||||
IsBuyNoAds = isBuyNoAds,
|
||||
BannerBackgroundColor = bannerBackgroundColor,
|
||||
DebugMode = debugMode,
|
||||
OnAdjustDeeplinkCallback = onAdjustDeeplinkCallback,
|
||||
GoogleKeys = googleKeys,
|
||||
AppleRootCerts = appleRootCerts,
|
||||
DefaultRemoteData = defaultRemoteData ?? new Dictionary<string, object>(),
|
||||
EnableDebugLogEvent = debugEnableEventLog,
|
||||
};
|
||||
#if UNITY_EDITOR
|
||||
config.DebugMode = true;
|
||||
#endif
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Print
|
||||
|
|
@ -107,107 +133,5 @@ 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,9 +1,8 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Guru
|
||||
{
|
||||
using System;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
[Serializable]
|
||||
public class GuruServicesConfig
|
||||
|
|
@ -62,7 +61,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_valid_time ?? 604800;
|
||||
public int TokenValidTime() => parameters?.token_vaild_time ?? 604800;
|
||||
public int LevelEndSuccessNum() => parameters?.level_end_success_num ?? 50;
|
||||
public string CdnHost() => parameters?.cdn_host ?? "";
|
||||
public bool UsingUUID() => parameters?.using_uuid ?? true;
|
||||
|
|
@ -92,7 +91,7 @@ namespace Guru
|
|||
[Serializable]
|
||||
public class GuruParameters
|
||||
{
|
||||
public int token_valid_time = 604800;
|
||||
public int token_vaild_time = 604800;
|
||||
public int level_end_success_num = 50;
|
||||
public bool enable_keywords = false;
|
||||
public double tch_020 = 0;
|
||||
|
|
|
|||
|
|
@ -7,17 +7,14 @@ namespace Guru
|
|||
/// 获取BLevel
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override int GetBLevel() => Model.BLevel; // BLevel
|
||||
|
||||
private GuruSDKModel Model => GuruSDKModel.Instance;
|
||||
protected override int GetBLevel() => GuruSDKModel.Instance.SuccessLevelId; // BLevel
|
||||
|
||||
protected override void OnPurchaseOver(bool success, string productName)
|
||||
{
|
||||
}
|
||||
|
||||
public void ClearData()
|
||||
if (success)
|
||||
{
|
||||
_model.ClearData();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,17 +12,27 @@ namespace Guru
|
|||
get => _value;
|
||||
set
|
||||
{
|
||||
if (_value.Equals(value)) return;
|
||||
|
||||
_value = value;
|
||||
OnValueChanged?.Invoke(value);
|
||||
}
|
||||
}
|
||||
public event Action<T> OnValueChanged;
|
||||
|
||||
public BindableProperty(T initValue)
|
||||
|
||||
public BindableProperty()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public BindableProperty(Action<T> onChanged)
|
||||
{
|
||||
OnValueChanged = onChanged;
|
||||
}
|
||||
|
||||
public BindableProperty(T initValue, Action<T> onChanged)
|
||||
{
|
||||
_value = initValue;
|
||||
OnValueChanged = onChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
|
||||
|
||||
|
||||
namespace Guru
|
||||
{
|
||||
using System;
|
||||
|
|
@ -5,42 +8,11 @@ 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;
|
||||
|
|
@ -48,77 +20,111 @@ namespace Guru
|
|||
{
|
||||
get
|
||||
{
|
||||
if (null == _instance) _instance = new GuruSDKModel();
|
||||
if (null == _instance) _instance = Load();
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public GuruSDKModel()
|
||||
{
|
||||
// 读取内存值
|
||||
GuruSDKSerializedModel model = LoadModel();
|
||||
_uid = model.uid;
|
||||
_noAds = model.no_ads;
|
||||
_bLevel = model.b_level;
|
||||
_bPlay = model.b_play;
|
||||
_purchased = model.purchased;
|
||||
}
|
||||
//-------------- 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 int BLevel
|
||||
public List<PurchasedProduct> purchased;
|
||||
|
||||
public Dictionary<string, int> event_priorities;
|
||||
|
||||
//-------------- data ---------------
|
||||
|
||||
private float _lastSavedTime = 0;
|
||||
|
||||
public int SuccessLevelId
|
||||
{
|
||||
get => _bLevel;
|
||||
get
|
||||
{
|
||||
if(_successLevel == null) InitProperties();
|
||||
return _successLevel.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < _bLevel)
|
||||
{
|
||||
// b_level 必须比上一次的值大
|
||||
Debug.LogWarning($"[SDK] :: Set b_level [{value}] should not be less than original value [{_bLevel}]");
|
||||
return;
|
||||
}
|
||||
_bLevel = value;
|
||||
Save();
|
||||
if(_successLevel == null) InitProperties();
|
||||
_successLevel.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int BPlay
|
||||
public int TotalPlayedCount
|
||||
{
|
||||
get => _bPlay;
|
||||
get
|
||||
{
|
||||
if(_totalPlayed == null) InitProperties();
|
||||
return _totalPlayed.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
_bPlay = value;
|
||||
Save();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public string UserId
|
||||
{
|
||||
get => _uid;
|
||||
get
|
||||
{
|
||||
if(_uid == null) InitProperties();
|
||||
return _uid.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
_uid = value;
|
||||
Save();
|
||||
if(_uid == null) InitProperties();
|
||||
_uid.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool IsIapUser => _purchased.Count > 0;
|
||||
public bool IsIapUser => PurchasedCount > 0;
|
||||
|
||||
public bool IsNoAds
|
||||
{
|
||||
get => _noAds;
|
||||
get => no_ads;
|
||||
set
|
||||
{
|
||||
_noAds = value;
|
||||
no_ads = 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 初始化
|
||||
|
||||
|
||||
private GuruSDKSerializedModel LoadModel()
|
||||
public static GuruSDKModel Load()
|
||||
{
|
||||
GuruSDKSerializedModel model = null;
|
||||
GuruSDKModel model = null;
|
||||
if (PlayerPrefs.HasKey(SaveKey))
|
||||
{
|
||||
var json = PlayerPrefs.GetString(SaveKey, "");
|
||||
|
|
@ -126,62 +132,113 @@ namespace Guru
|
|||
{
|
||||
try
|
||||
{
|
||||
model = JsonUtility.FromJson<GuruSDKSerializedModel>(json);
|
||||
model = JsonUtility.FromJson<GuruSDKModel>(json);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
UnityEngine.Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(model == null) model = new GuruSDKSerializedModel();
|
||||
if(model == null) model = new GuruSDKModel();
|
||||
model.InitProperties();
|
||||
return model;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存至 PlayerPrefs 数据
|
||||
/// 保存至数据
|
||||
/// </summary>
|
||||
private void SetToMemory()
|
||||
{
|
||||
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))
|
||||
private void SaveToPlayerPrefs()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存数据
|
||||
/// </summary>
|
||||
/// <param name="forceSave"></param>
|
||||
public void Save(bool forceSave = false)
|
||||
/// <param name="force"></param>
|
||||
public void Save(bool force = false)
|
||||
{
|
||||
SetToMemory(); // 每次保存都要设置到 PlayerPrefs 内
|
||||
bool save = force || (Time.realtimeSinceStartup - _lastSavedTime>= SaveInterval);
|
||||
if (save)
|
||||
{
|
||||
_lastSavedTime = Time.realtimeSinceStartup;
|
||||
SaveToPlayerPrefs();
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldWriteToDisk = forceSave || (DateTime.Now - _lastSavedTime)>= TimeSpan.FromSeconds(SaveInterval);
|
||||
if (!shouldWriteToDisk) return;
|
||||
_lastSavedTime = DateTime.Now; // 更新最后保存时间
|
||||
PlayerPrefs.Save(); // 写入到磁盘
|
||||
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();
|
||||
}
|
||||
|
||||
#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.Count == 0) return false;
|
||||
return _purchased.Exists(p => p.receipt == receipt);
|
||||
if(purchased == null || purchased.Count == 0) return false;
|
||||
return purchased.Exists(p => p.receipt == receipt);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -190,12 +247,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,
|
||||
|
|
@ -208,16 +265,22 @@ namespace Guru
|
|||
|
||||
public string[] GetReceipts(string productName)
|
||||
{
|
||||
var receipts = new List<string>();
|
||||
receipts.AddRange(from purchasedProduct in _purchased where purchasedProduct.productName == productName select purchasedProduct.receipt);
|
||||
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);
|
||||
return receipts.ToArray();
|
||||
}
|
||||
|
||||
|
||||
public string[] GetReceiptsById(string productId)
|
||||
{
|
||||
var receipts = new List<string>();
|
||||
receipts.AddRange(from purchasedProduct in _purchased where purchasedProduct.productId == productId select purchasedProduct.receipt);
|
||||
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);
|
||||
return receipts.ToArray();
|
||||
}
|
||||
|
||||
|
|
@ -225,15 +288,15 @@ namespace Guru
|
|||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#region 清除数据
|
||||
|
||||
public void ClearData()
|
||||
[Serializable]
|
||||
internal class PurchasedProduct
|
||||
{
|
||||
PlayerPrefs.DeleteKey(SaveKey);
|
||||
}
|
||||
|
||||
#endregion
|
||||
public string productName;
|
||||
public string productId;
|
||||
public string receipt;
|
||||
public bool appleProductIsRestored;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -242,5 +305,4 @@ namespace Guru
|
|||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ namespace Guru
|
|||
_adInitSpec = spec;
|
||||
if (InitConfig.UseCustomConsent)
|
||||
{
|
||||
Debug.Log($"{Tag} --- Call <color=orange>StartAdsWithCustomConsent</color> when you use custom consent, and pass the result (boolean) to the method.");
|
||||
UnityEngine.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
|
||||
{
|
||||
Debug.Log($"{Tag} --- User refuse to provide ads Id, Ads Service will be cancelled");
|
||||
UnityEngine.Debug.Log($"{Tag} --- User refuse to provide ads Id, Ads Service will be cancelled");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ namespace Guru
|
|||
{
|
||||
_attType = InitConfig.UseCustomConsent ? ATTManager.GUIDE_TYPE_CUSTOM : ATTManager.GUIDE_TYPE_ADMOB; // 点位属性确定
|
||||
_initialAttStatus = ATTManager.GetStatus();
|
||||
SetATTStatus(_initialAttStatus); // 上报一个初始的状态
|
||||
SetUserProperty(Analytics.ParameterATTStatus, _initialAttStatus); // 上报一个初始的状态
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -202,15 +202,14 @@ namespace Guru
|
|||
private void ReportAttStatus(string status)
|
||||
{
|
||||
LogI($"{Tag} --- Get Att status:{status} att Type:{_attType} recall:{_autoReCallAtt}");
|
||||
SetATTStatus(_initialAttStatus); // 上报一个初始的状态
|
||||
// SetUserProperty(Analytics.ParameterATTStatus, status); // 当前的状态
|
||||
SetUserProperty(Analytics.ParameterATTStatus, status); // 当前的状态
|
||||
|
||||
if (!string.IsNullOrEmpty(status)
|
||||
&& status != _initialAttStatus
|
||||
&& status != ATTManager.ATT_STATUS_NOT_DETERMINED)
|
||||
{
|
||||
// 上报点位:
|
||||
SetATTStatus(_initialAttStatus);
|
||||
Analytics.AttResult(status, _attType);
|
||||
}
|
||||
|
||||
switch(status)
|
||||
|
|
@ -244,7 +243,7 @@ namespace Guru
|
|||
// bool hasNotiGranted = false;
|
||||
_notiStatue = "no_determined";
|
||||
NotificationService.Initialize(); // 初始化 Noti 服务
|
||||
Analytics.SetNotiPerm(NotificationService.GetStatus());
|
||||
SetNotiPerm(NotificationService.GetStatus());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -266,7 +265,7 @@ namespace Guru
|
|||
if (isGranted)
|
||||
{
|
||||
Debug.Log($"[SDK] ---- Set Notification Permission: {status}");
|
||||
Analytics.SetNotiPerm(status);
|
||||
SetNotiPerm(status);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +284,7 @@ namespace Guru
|
|||
NotificationService.RequestPermission(status =>
|
||||
{
|
||||
Debug.Log($"[SDK] ---- Set Notification Permission: {status}");
|
||||
if(!string.IsNullOrEmpty(status)) Analytics.SetNotiPerm(status);
|
||||
if(!string.IsNullOrEmpty(status)) SetNotiPerm(status);
|
||||
|
||||
callback?.Invoke(status);
|
||||
});
|
||||
|
|
@ -326,7 +325,7 @@ namespace Guru
|
|||
/// <summary>
|
||||
/// 启动广告服务
|
||||
/// </summary>
|
||||
private static void StartAdService(AdsInitSpec spec = null)
|
||||
internal static void StartAdService(AdsInitSpec spec = null)
|
||||
{
|
||||
|
||||
//---------- Using InitConfig ----------
|
||||
|
|
|
|||
|
|
@ -10,9 +10,8 @@ namespace Guru
|
|||
/// </summary>
|
||||
public partial class GuruSDK
|
||||
{
|
||||
|
||||
#region 通用接口
|
||||
//TODO: 需要有一个通用的 IEventData 的接口, 需要实现 getName, getData, getSetting, getPriority 等方法
|
||||
//TODO: Analytics.Track 的参数改为 IEventData
|
||||
|
||||
/// <summary>
|
||||
/// 自定义事件打点
|
||||
|
|
@ -22,7 +21,14 @@ 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);
|
||||
}
|
||||
|
||||
|
|
@ -36,90 +42,6 @@ namespace Guru
|
|||
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 游戏打点
|
||||
|
|
@ -196,9 +118,6 @@ namespace Guru
|
|||
$"{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);
|
||||
|
||||
|
|
@ -207,16 +126,18 @@ namespace Guru
|
|||
{
|
||||
if (result == Consts.EventLevelEndSuccess)
|
||||
{
|
||||
if (levelType.ToLower() == Consts.LevelTypeMain)
|
||||
if (levelType == Consts.LevelTypeMain)
|
||||
{
|
||||
Model.BLevel = levelId; // 自动记录 [主线] 关卡完成次数
|
||||
if (levelId > Model.SuccessLevelId) Model.SuccessLevelId = levelId; // 自动记录关卡完成次数
|
||||
}
|
||||
|
||||
Model.BPlay++; // 自动记录关卡总次数
|
||||
Model.TotalPlayedCount++; // 自动记录关卡总次数
|
||||
|
||||
var eventData = new LevelEndSuccessEventData(Model.BPlay, extra);
|
||||
Analytics.TrackLevelEndSuccessEvent(eventData); // 自动 level_end_success
|
||||
Analytics.LevelEndSuccess(Model.TotalPlayedCount); // 自动 level_end_success
|
||||
}
|
||||
|
||||
Analytics.BLevel = Model.SuccessLevelId; // 记录 BLevel
|
||||
Analytics.BPlay = Model.TotalPlayedCount; // 记录 BPlay
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -243,8 +164,8 @@ namespace Guru
|
|||
/// /// <param name="extra">扩展参数</param>
|
||||
public static void LogLevelEndSuccess(int bPlay, Dictionary<string, object> extra = null)
|
||||
{
|
||||
var eventData = new LevelEndSuccessEventData(bPlay, extra);
|
||||
Analytics.TrackLevelEndSuccessEvent(eventData);
|
||||
if (InitConfig.AutoRecordFinishedLevels) return;
|
||||
Analytics.LevelEndSuccess(bPlay, extra);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -370,6 +291,173 @@ namespace Guru
|
|||
LogEvent(Consts.EventHpPoints, dict);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region 用户属性
|
||||
|
||||
/// <summary>
|
||||
/// 提前调用用户属性
|
||||
/// </summary>
|
||||
private static void InitUserProperties()
|
||||
{
|
||||
if (!IsInitialSuccess)
|
||||
{
|
||||
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); // 设置用户已经购买了去广告
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
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="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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
public static void SetNetworkStatus()
|
||||
{
|
||||
SetUserProperty(Consts.PropertyNetwork, Instance.GetNetworkStatus());
|
||||
}
|
||||
|
||||
private static bool _hasUserPropertiesInitiallyUpdated = false;
|
||||
/// <summary>
|
||||
/// 初始化时补全一下所有的属性打点
|
||||
/// 如果用户已经设置过 Key, 则不会再次设置
|
||||
/// <a href="https://docs.google.com/spreadsheets/d/1N47rXgjatRHFvzWWx0Hqv5C1D9NHHGbggi6pQ65c-zQ/edit#gid=1858695240">用户属性文档</a>
|
||||
/// </summary>
|
||||
private static void InitiallyUpdateUserProperties()
|
||||
{
|
||||
if (_hasUserPropertiesInitiallyUpdated) return;
|
||||
_hasUserPropertiesInitiallyUpdated = true;
|
||||
|
||||
SetFirstOpenTime(TimeUtil.GetCurrentTimeStamp().ToString()); // first_open_time
|
||||
SetUserIsIAP(Model?.IsIapUser ?? false); // is_iap_user
|
||||
SetUserBLevel(Model?.SuccessLevelId ?? 0); // b_level
|
||||
SetUserBLevel(Model?.TotalPlayedCount ?? 0); // b_play
|
||||
SetUserProperty(Consts.PropertyDeviceID, DeviceId); // device_id
|
||||
|
||||
SetUserIapCoin(0); // iap_coin
|
||||
SetUserNonIapCoin(0); // non_iap_coin
|
||||
SetUserCoin(0);// coin
|
||||
SetUserGrade(0); // grade
|
||||
SetUserExp(0); // exp
|
||||
SetUserHp(0); // hp
|
||||
|
||||
if(!string.IsNullOrEmpty(UID))
|
||||
SetUID(UID); // user_id
|
||||
|
||||
#if UNITY_IOS
|
||||
SetATTStatus("notDetermined"); // att_status
|
||||
#endif
|
||||
SetNotiPerm("not_determined"); // noti_perm
|
||||
SetNetworkStatus(); // NetworkStatus
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region SDK 打点
|
||||
|
|
@ -378,7 +466,7 @@ namespace Guru
|
|||
/// Log SDK boost time
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
private static void LogSDKInfo(double time)
|
||||
private static void LogSDKInitTime(double time)
|
||||
{
|
||||
Analytics.Track(Consts.EventSDKInfo, new Dictionary<string, dynamic>()
|
||||
{
|
||||
|
|
@ -390,16 +478,8 @@ namespace Guru
|
|||
{
|
||||
EnableFirebaseAnalytics = true,
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 GuruSDK 实验分组
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetGuruExperimentGroupId()
|
||||
{
|
||||
if (!GuruAnalytics.IsReady) return "not_set";
|
||||
return GuruAnalytics.Instance.ExperimentGroupId;
|
||||
SetUserProperty("sdk_version", Version);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -1154,7 +1234,7 @@ namespace Guru
|
|||
CrashlyticsAgent.Log(message);
|
||||
}
|
||||
|
||||
public static void CrashLogException(string message)
|
||||
public static void CrashException(string message)
|
||||
{
|
||||
if (!IsFirebaseReady) return;
|
||||
CrashlyticsAgent.LogException(message);
|
||||
|
|
@ -1166,7 +1246,7 @@ namespace Guru
|
|||
CrashlyticsAgent.LogException(ex);
|
||||
}
|
||||
|
||||
public static void CrashSetCustomKeys(string key, string value)
|
||||
public static void CrashCustomKeys(string key, string value)
|
||||
{
|
||||
if (!IsFirebaseReady) return;
|
||||
CrashlyticsAgent.SetCustomKey(key, value);
|
||||
|
|
@ -1175,7 +1255,6 @@ namespace Guru
|
|||
|
||||
#region 优先级设置
|
||||
|
||||
private static readonly Dictionary<string, int> _eventPriorities = new Dictionary<string, int>(10);
|
||||
|
||||
/// <summary>
|
||||
/// 设置
|
||||
|
|
@ -1184,13 +1263,15 @@ namespace Guru
|
|||
/// <param name="eventNames"></param>
|
||||
public static void SetEventPriority(EventPriority priority, string[] eventNames)
|
||||
{
|
||||
if (Model.event_priorities == null) Model.event_priorities = new Dictionary<string, int>(10);
|
||||
|
||||
int i = 0;
|
||||
while (i < eventNames.Length)
|
||||
{
|
||||
var evt = eventNames[i];
|
||||
if (!string.IsNullOrEmpty(evt))
|
||||
{
|
||||
_eventPriorities[evt] = (int)priority;
|
||||
Model.event_priorities[evt] = (int)priority;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
|
@ -1203,14 +1284,15 @@ namespace Guru
|
|||
|
||||
public static EventPriority GetEventPriority(string eventName)
|
||||
{
|
||||
if (_eventPriorities.TryGetValue(eventName, out int p))
|
||||
if (Model.event_priorities != null
|
||||
&& Model.event_priorities.TryGetValue(eventName, out int p))
|
||||
{
|
||||
return (EventPriority)p;
|
||||
}
|
||||
return EventPriority.Default;
|
||||
}
|
||||
|
||||
public static int GetEventPriorityInt(string eventName)
|
||||
internal static int GetEventPriorityInt(string eventName)
|
||||
{
|
||||
return (int)GetEventPriority(eventName);
|
||||
}
|
||||
|
|
@ -1218,7 +1300,7 @@ namespace Guru
|
|||
/// <summary>
|
||||
/// set all events as 'Emergence' event, which will be triggered immediately
|
||||
/// </summary>
|
||||
private void SetSDKEventPriority()
|
||||
internal void SetSDKEventPriority()
|
||||
{
|
||||
SetEventPriority(EventPriority.Emergence, new []
|
||||
{
|
||||
|
|
@ -1226,13 +1308,9 @@ namespace Guru
|
|||
Consts.EventTchAdRev02Impression,
|
||||
Consts.EventLevelStart,
|
||||
Consts.EventLevelEnd,
|
||||
Consts.EventIAPReturnTrue,
|
||||
Consts.EventIAPPurchase,
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -334,16 +334,27 @@ namespace Guru
|
|||
}
|
||||
|
||||
private static Action<bool> _onUserAuthResult;
|
||||
public static event Action<bool> OnGuruUserAuthResult
|
||||
public static event Action<bool> OnUserAuthResult
|
||||
{
|
||||
add => _onUserAuthResult += value;
|
||||
remove => _onUserAuthResult -= value;
|
||||
}
|
||||
internal static void InvokeOnGuruUserAuthResult(bool success)
|
||||
internal static void InvokeOnUserAuthResult(bool success)
|
||||
{
|
||||
_onUserAuthResult?.Invoke(success);
|
||||
}
|
||||
|
||||
private static Action<bool> _onFirebaseAuthResult;
|
||||
public static event Action<bool> OnFirebaseAuthResult
|
||||
{
|
||||
add => _onFirebaseAuthResult += value;
|
||||
remove => _onFirebaseAuthResult -= value;
|
||||
}
|
||||
internal static void InvokeOnFirebaseAuthResult(bool success)
|
||||
{
|
||||
_onFirebaseAuthResult?.Invoke(success);
|
||||
}
|
||||
|
||||
// DeepLink 回调
|
||||
private static Action<string> _onDeeplinkCallback;
|
||||
public static event Action<string> OnDeeplinkCallback
|
||||
|
|
@ -356,19 +367,6 @@ namespace Guru
|
|||
_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,7 +2,16 @@ namespace Guru
|
|||
{
|
||||
public partial class GuruSDK
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 打点优先级
|
||||
/// </summary>
|
||||
public enum EventPriority
|
||||
{
|
||||
Emergence = 0,
|
||||
High = 5,
|
||||
Default = 10,
|
||||
Low = 15
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Consts values
|
||||
|
|
@ -210,7 +219,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的时间
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ 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>
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ namespace Guru
|
|||
/// <param name="success"></param>
|
||||
private static void OnBuyEnd(string productName, bool success)
|
||||
{
|
||||
if (success) Model.PurchasedCount++;
|
||||
InvokeOnPurchaseCallback?.Invoke(productName, success);
|
||||
Callbacks.IAP.InvokeOnPurchaseEnd(productName, success);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
namespace Guru
|
||||
{
|
||||
public partial class GuruSDK
|
||||
|
|
@ -76,30 +75,29 @@ namespace Guru
|
|||
{
|
||||
Model.IsNoAds = value;
|
||||
ADService.Instance.IsBuyNoAds = value;
|
||||
if (value)
|
||||
{
|
||||
Analytics.SetIsIapUser(true);
|
||||
}
|
||||
SetUserProperty(Consts.PropertyNoAds, value? "true" : "false");
|
||||
if(value) SetUserIsIAP(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 所有成功的主线关卡数量 (b_level)
|
||||
/// </summary>
|
||||
public static int BLevel
|
||||
public static int SuccessLevelCount
|
||||
{
|
||||
get => GuruSDKModel.Instance.BLevel;
|
||||
set => GuruSDKModel.Instance.BLevel = value;
|
||||
get => GuruSDKModel.Instance.SuccessLevelId;
|
||||
set => GuruSDKModel.Instance.SuccessLevelId = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 成功关卡总计数量 (b_play)
|
||||
/// </summary>
|
||||
public static int BPlay
|
||||
public static int TotalPlayedCount
|
||||
{
|
||||
get => GuruSDKModel.Instance.BPlay;
|
||||
set => GuruSDKModel.Instance.BPlay = value;
|
||||
get => GuruSDKModel.Instance.TotalPlayedCount;
|
||||
set => GuruSDKModel.Instance.TotalPlayedCount = value;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -77,21 +77,5 @@ 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,9 +4,9 @@ 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
|
||||
{
|
||||
|
|
@ -78,12 +78,6 @@ 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()
|
||||
|
|
@ -95,15 +89,38 @@ namespace Guru
|
|||
}
|
||||
|
||||
// TODO : 下个版本需要将 整个 GuruSDK 做功能性的拆分
|
||||
// GuruSDk.Callbacks -> GuruSDkCallbacks 所有的内置回调改为成员变量,
|
||||
// 去掉所有的内部类, 去掉所有的 Static
|
||||
// Static 只用于常量
|
||||
// TODO: 下一个版本改为标准的 Builder 模式
|
||||
public static GuruSDKInitConfig BuildConfig(
|
||||
bool useCustomConsent = false,
|
||||
bool autoLoadAds = true,
|
||||
bool iapEnabled = true,
|
||||
bool autoRecordFinishedLevels = true,
|
||||
bool debugMode = false,
|
||||
bool isBuyNoAds = false,
|
||||
Action<string> onAdjustDeeplinkCallback = null,
|
||||
string bannerColor = "#00000000",
|
||||
Dictionary<string, object> defaultRemoteData = null,
|
||||
byte[] googleKeys = null,
|
||||
byte[] appleRootCerts = null,
|
||||
bool debugEnableEventLog = false)
|
||||
{
|
||||
var config = GuruSDKInitConfig.Build(useCustomConsent, autoLoadAds, iapEnabled,
|
||||
autoRecordFinishedLevels, isBuyNoAds, bannerColor,
|
||||
debugMode, onAdjustDeeplinkCallback, defaultRemoteData, googleKeys, appleRootCerts, debugEnableEventLog);
|
||||
return config;
|
||||
}
|
||||
|
||||
public static void Init(Action<bool> onComplete)
|
||||
{
|
||||
Init(GuruSDKInitConfig.Builder().Build(), onComplete);
|
||||
Init(GuruSDKInitConfig.Build(), onComplete);
|
||||
}
|
||||
|
||||
public static void Init(GuruSDKInitConfig config, Action<bool> onComplete)
|
||||
{
|
||||
_initTime = DateTime.UtcNow;
|
||||
_initTime = DateTime.Now.ToUniversalTime();
|
||||
// ----- First Open Time -----
|
||||
// SetFirstOpenTime(GetFirstOpenTime()); // FirstOpenTime
|
||||
LogI($"#1 ---- Guru SDK [{Version}] ----\n{config}");
|
||||
|
|
@ -117,6 +134,9 @@ 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;
|
||||
_isDebugEnabled = config.DebugMode;
|
||||
|
|
@ -128,26 +148,19 @@ namespace Guru
|
|||
InitThreadHandler(); // 初始化线程处理器
|
||||
InitServices(); // 初始化所有的服务
|
||||
InitNetworkMonitor(); // 网络状态
|
||||
InitiallyUpdateUserProperties(); // 上报所有初始化用户属性
|
||||
|
||||
onComplete?.Invoke(true);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Analytics.InitAnalytics(); // 打点提前初始化
|
||||
//---- Start All tools ----
|
||||
LogI($"#2 --- InitFirebase ---");
|
||||
//---------- Start Firebase ------------
|
||||
StartFirebaseService();
|
||||
|
||||
LogI($"#2.1 --- InitFacebook ---");
|
||||
//---------- Start Facebook ------------
|
||||
FBService.Instance.StartService(Analytics.OnFBInitComplete);
|
||||
|
|
@ -155,19 +168,89 @@ namespace Guru
|
|||
IsInitialSuccess = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 启动 Firebase 服务
|
||||
/// </summary>
|
||||
private void StartFirebaseService()
|
||||
{
|
||||
FirebaseUtil.onInitComplete += OnFirebaseReady;
|
||||
FirebaseUtil.OnUserAuthResult += OnUserAuthResult;
|
||||
FirebaseUtil.OnFirebaseAuthResult += OnFirebaseAuthResult;
|
||||
|
||||
if (InitConfig.OnAdjustDeeplinkCallback != null)
|
||||
{
|
||||
//TODO: 下个版本 AdjustService 和 Firebase 解耦
|
||||
FirebaseUtil.OnAdjustDeeplinkCallback = InitConfig.OnAdjustDeeplinkCallback; // 挂载 Deeplink 的回调
|
||||
}
|
||||
|
||||
FirebaseUtil.InitFirebase(Analytics.OnFirebaseInitCompleted); // 确保所有的逻辑提前被调用到
|
||||
}
|
||||
|
||||
private void OnUserAuthResult(bool success)
|
||||
{
|
||||
|
||||
if (success && string.IsNullOrEmpty(IPMConfig.IPM_UID))
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
Callbacks.SDK.InvokeOnUserAuthResult(success);
|
||||
|
||||
if (success)
|
||||
{
|
||||
Model.UserId = IPMConfig.IPM_UID;
|
||||
if (GuruIAP.Instance != null)
|
||||
{
|
||||
GuruIAP.Instance.SetUID(UID);
|
||||
GuruIAP.Instance.SetUUID(UUID);
|
||||
}
|
||||
|
||||
SetUID(UID);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFirebaseAuthResult(bool success)
|
||||
{
|
||||
Callbacks.SDK.InvokeOnFirebaseAuthResult(success);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始各种组件初始化
|
||||
/// </summary>
|
||||
private void OnFirebaseReady(bool success)
|
||||
{
|
||||
FirebaseUtil.onInitComplete -= OnFirebaseReady;
|
||||
LogI($"#3 --- On FirebaseDeps: {success} ---");
|
||||
IsFirebaseReady = success;
|
||||
Callbacks.SDK.InvokeOnFirebaseReady(success);
|
||||
// LogFirebaseDeps(success);
|
||||
|
||||
LogI($"#3.5 --- Call InitRemoteConfig ---");
|
||||
// 开始Remote Manager初始化
|
||||
RemoteConfigManager.Init(BuildDefaultRemoteData(_initConfig.DefaultRemoteData));
|
||||
RemoteConfigManager.OnFetchCompleted += OnFetchRemoteCallback;
|
||||
|
||||
LogI($"#4 --- Apply remote services config ---");
|
||||
// 根据缓存的云控配置来初始化参数
|
||||
InitAllGuruServices();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 注入云控参数基础数据
|
||||
/// </summary>
|
||||
/// <param name="dict"></param>
|
||||
/// <returns></returns>
|
||||
private string LoadDefaultGuruServiceJson()
|
||||
private Dictionary<string, object> BuildDefaultRemoteData(Dictionary<string, object> dict)
|
||||
{
|
||||
// 加载本地 Services 配置值
|
||||
var txtAsset = Resources.Load<TextAsset>(ServicesConfigKey);
|
||||
if (txtAsset != null)
|
||||
{
|
||||
return txtAsset.text;
|
||||
}
|
||||
return "";
|
||||
if (dict == null) dict = new Dictionary<string, object>(3);
|
||||
|
||||
// 注入默认的 Services 配置值
|
||||
string json = Model.LoadDefaltServicesConfigJson();
|
||||
if (!string.IsNullOrEmpty(json)) dict[ServicesConfigKey] = json;
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -181,6 +264,8 @@ namespace Guru
|
|||
Callbacks.Remote.InvokeOnRemoteFetchComplete(success);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
UpdateAllUpdates(); // 驱动所有的更新器
|
||||
|
|
@ -197,6 +282,7 @@ namespace Guru
|
|||
private void InitAllGuruServices()
|
||||
{
|
||||
// -------- Init Analytics ---------
|
||||
InitUserProperties();
|
||||
SetSDKEventPriority();
|
||||
// -------- Init Notification -----------
|
||||
InitNotiPermission();
|
||||
|
|
@ -290,9 +376,10 @@ namespace Guru
|
|||
LogI($"#4.3 --- Start IAP ---");
|
||||
if (_initConfig.GoogleKeys == null || _initConfig.AppleRootCerts == null)
|
||||
{
|
||||
LogEx("[IAP] GoogleKeys is null when using IAPService! Integration failed. App will Exit");
|
||||
LogException("[IAP] GoogleKeys is null when using IAPService! Integration failed. App will Exit");
|
||||
}
|
||||
|
||||
|
||||
InitIAP(UID, _initConfig.GoogleKeys, _initConfig.AppleRootCerts); // 初始化IAP
|
||||
}, ex =>
|
||||
{
|
||||
|
|
@ -306,7 +393,7 @@ namespace Guru
|
|||
Try(() =>
|
||||
{
|
||||
LogI($"#4.4 --- Start Keywords ---");
|
||||
KeywordsManager.Install(Model.IsIapUser, Model.BLevel); // 启动Keyword管理器
|
||||
KeywordsManager.Install(Model.IsIapUser, Model.SuccessLevelId); // 启动Keyword管理器
|
||||
}, ex =>
|
||||
{
|
||||
Debug.LogError($"--- ERROR on Keywords: {ex.Message}");
|
||||
|
|
@ -319,7 +406,7 @@ namespace Guru
|
|||
// StartAppleReviewFlow(); // 直接显示 ATT 弹窗, 跳过 Consent 流程
|
||||
Try(() =>
|
||||
{
|
||||
LogI($"#4.5 --- StartAppleReviewFlow ---");
|
||||
LogI($"#4.5.0 --- StartAppleReviewFlow ---");
|
||||
StartAppleReviewFlow(); // 直接显示 ATT 弹窗, 跳过 Consent 流程
|
||||
}, ex =>
|
||||
{
|
||||
|
|
@ -331,23 +418,27 @@ namespace Guru
|
|||
//----------- Set Consent ----------------
|
||||
if (!InitConfig.UseCustomConsent && !appleReview)
|
||||
{
|
||||
LogI($"#4.6 --- Start Consent Flow ---");
|
||||
// LogI($"--- #3 Start Consent Flow ---");
|
||||
// StartConsentFlow();
|
||||
Try(StartConsentFlow, ex =>
|
||||
{
|
||||
Debug.LogError($"--- ERROR on StartConsentFlow: {ex.Message}");
|
||||
});
|
||||
}
|
||||
|
||||
#if UNITY_ANDROID
|
||||
LogI($"#5.1 --- Android StartAndroidDebug Cmd lines---");
|
||||
// Android 命令行调试
|
||||
StartAndroidDebugCmds();
|
||||
#endif
|
||||
|
||||
IsServiceReady = true;
|
||||
|
||||
// 中台服务初始化结束
|
||||
Callbacks.SDK.InvokeOnGuruServiceReady();
|
||||
|
||||
#if UNITY_ANDROID
|
||||
// Android 命令行调试
|
||||
StartAndroidDebugCmds();
|
||||
#endif
|
||||
|
||||
LogI($"#5 --- sync sdk time ---");
|
||||
// TODO: 本调用放在这里不合适, 应该和 Firebase 解耦
|
||||
LogSDKInitTime((DateTime.Now.ToUniversalTime() - _initTime).TotalSeconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -394,7 +485,7 @@ namespace Guru
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogEx(ex);
|
||||
LogException(ex);
|
||||
// ignored
|
||||
onException?.Invoke(ex);
|
||||
}
|
||||
|
|
@ -418,30 +509,44 @@ namespace Guru
|
|||
#endif
|
||||
#endregion
|
||||
|
||||
#region 数据
|
||||
|
||||
private void OnBLevelChanged(int bLevel)
|
||||
{
|
||||
SetUserBLevel(bLevel);
|
||||
}
|
||||
|
||||
private void OnBPlayChanged(int bPlay)
|
||||
{
|
||||
SetUserBPlay(bPlay);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Logging
|
||||
|
||||
private static void LogI(object message)
|
||||
internal static void LogI(object message)
|
||||
{
|
||||
Debug.Log($"{Tag} {message}");
|
||||
}
|
||||
|
||||
private static void LogW(object message)
|
||||
internal static void LogW(object message)
|
||||
{
|
||||
Debug.LogWarning($"{Tag} {message}");
|
||||
}
|
||||
|
||||
private static void LogE(object message)
|
||||
internal static void LogE(object message)
|
||||
{
|
||||
Debug.LogError($"{Tag} {message}");
|
||||
}
|
||||
|
||||
|
||||
private static void LogEx(string message)
|
||||
internal static void LogException(string message)
|
||||
{
|
||||
LogEx( new Exception($"{Tag} {message}"));
|
||||
LogException( new Exception($"{Tag} {message}"));
|
||||
}
|
||||
|
||||
private static void LogEx(Exception e)
|
||||
internal static void LogException(Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
|
|
@ -667,177 +772,32 @@ namespace Guru
|
|||
Callbacks.SDK.InvokeDeeplinkCallback(deeplink); // 尝试调用回调
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region 网络状态上报
|
||||
|
||||
|
||||
private NetworkStatusMonitor _networkStatusMonitor;
|
||||
private string _lastNetworkStatus;
|
||||
private string _networkStatus;
|
||||
|
||||
private void InitNetworkMonitor()
|
||||
{
|
||||
_networkStatusMonitor = new NetworkStatusMonitor(Analytics.SetNetworkStatus,
|
||||
lastStatus =>
|
||||
{
|
||||
LogEvent("guru_offline", new Dictionary<string, dynamic>()
|
||||
{
|
||||
["from"] = lastStatus
|
||||
});
|
||||
});
|
||||
// SetUserProperty(Consts.PropertyNetwork, GetNetworkStatus());
|
||||
// TODO: 下个版本加入真正的自动更新网络状态的实现
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前的网络状态
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private string GetNetworkStatus() => _networkStatusMonitor.GetNetworkStatus();
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Firebase 服务
|
||||
|
||||
/// <summary>
|
||||
/// 启动 Firebase 服务
|
||||
/// </summary>
|
||||
private void StartFirebaseService()
|
||||
private string GetNetworkStatus()
|
||||
{
|
||||
FirebaseUtil.Init(OnFirebaseDepsCheckResult,
|
||||
OnGetFirebaseId,
|
||||
OnGetGuruUID,
|
||||
OnFirebaseLoginResult); // 确保所有的逻辑提前被调用到
|
||||
}
|
||||
|
||||
private void OnGetGuruUID(bool success)
|
||||
if(_networkStatusMonitor == null)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
Model.UserId = IPMConfig.IPM_UID;
|
||||
if (GuruIAP.Instance != null)
|
||||
{
|
||||
GuruIAP.Instance.SetUID(UID);
|
||||
GuruIAP.Instance.SetUUID(UUID);
|
||||
_networkStatusMonitor = new NetworkStatusMonitor();
|
||||
}
|
||||
|
||||
// 自打点设置用户 ID
|
||||
Analytics.SetUid(UID);
|
||||
// Crashlytics 设置 uid
|
||||
CrashlyticsAgent.SetUserId(UID);
|
||||
// 上报所有的事件
|
||||
Analytics.ShouldFlushGuruEvents();
|
||||
return _networkStatusMonitor.GetNetworkStatus();
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue