Compare commits
14 Commits
cf832d88ad
...
c8b85b0f79
| Author | SHA1 | Date |
|---|---|---|
|
|
c8b85b0f79 | |
|
|
9cf0dd5801 | |
|
|
719be42b59 | |
|
|
95271aaa98 | |
|
|
a768b1de90 | |
|
|
720b47dcbf | |
|
|
b4fbb5d3da | |
|
|
3f0f13be6c | |
|
|
23c1b8f4fc | |
|
|
96750cc3d8 | |
|
|
548959dd34 | |
|
|
9de443249d | |
|
|
6dd2574763 | |
|
|
bd39fb09f1 |
|
|
@ -53,9 +53,12 @@ namespace Guru
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="appToken"></param>
|
/// <param name="appToken"></param>
|
||||||
/// <param name="fbAppId">MIR 追踪 AppID</param>
|
/// <param name="fbAppId">MIR 追踪 AppID</param>
|
||||||
/// <param name="onInitComplete"></param>
|
/// <param name="deviceId"></param>
|
||||||
|
/// <param name="onInitComplete">初始化完成的时候会返回 AdjustId </param>
|
||||||
/// <param name="onDeeplinkCallback"></param>
|
/// <param name="onDeeplinkCallback"></param>
|
||||||
public static void StartService(string appToken, string fbAppId = "", Action<string> onInitComplete = null, Action<string> onDeeplinkCallback = null)
|
/// <param name="firebaseId"></param>
|
||||||
|
public static void StartService(string appToken, string fbAppId = "", string firebaseId = "", string deviceId = "",
|
||||||
|
Action<string> onInitComplete = null, Action<string> onDeeplinkCallback = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(appToken))
|
if (string.IsNullOrEmpty(appToken))
|
||||||
{
|
{
|
||||||
|
|
@ -65,7 +68,7 @@ namespace Guru
|
||||||
|
|
||||||
_onInitComplete = onInitComplete;
|
_onInitComplete = onInitComplete;
|
||||||
|
|
||||||
InstallEvent(IPMConfig.FIREBASE_ID, IPMConfig.IPM_DEVICE_ID); // 注入启动参数
|
InstallEvent(firebaseId, deviceId); // 注入启动参数
|
||||||
|
|
||||||
AdjustEnvironment environment = GetAdjustEnvironment();
|
AdjustEnvironment environment = GetAdjustEnvironment();
|
||||||
AdjustConfig config = new AdjustConfig(appToken, environment);
|
AdjustConfig config = new AdjustConfig(appToken, environment);
|
||||||
|
|
|
||||||
|
|
@ -20,19 +20,19 @@ namespace Guru
|
||||||
bool res;
|
bool res;
|
||||||
from = $"{files}/{AndroidLib}.f";
|
from = $"{files}/{AndroidLib}.f";
|
||||||
to = $"{Application.dataPath}/Plugins/Android/{AndroidLib}";
|
to = $"{Application.dataPath}/Plugins/Android/{AndroidLib}";
|
||||||
res = CopyFile(from, to);
|
res = CopyFile(from, to); // 无需覆盖
|
||||||
if (res) Debug.Log($"Copy <color=#88ff00>{AndroidLib} to {to}</color> success...");
|
if (res) Debug.Log($"Copy <color=#88ff00>{AndroidLib} to {to}</color> success...");
|
||||||
from = $"{files}/{AndroidLib}.f.meta";
|
from = $"{files}/{AndroidLib}.f.meta";
|
||||||
to = $"{Application.dataPath}/Plugins/Android/{AndroidLib}.meta";
|
to = $"{Application.dataPath}/Plugins/Android/{AndroidLib}.meta";
|
||||||
CopyFile(from, to);
|
CopyFile(from, to); // 无需覆盖
|
||||||
|
|
||||||
from = $"{files}/{iOSLib}.f";
|
from = $"{files}/{iOSLib}.f";
|
||||||
to = $"{Application.dataPath}/Plugins/iOS/{iOSLib}";
|
to = $"{Application.dataPath}/Plugins/iOS/{iOSLib}";
|
||||||
res = CopyFile(from, to);
|
res = CopyFile(from, to); // 无需覆盖
|
||||||
if (res) Debug.Log($"Copy <color=#88ff00>{iOSLib} to {to}</color> success...");
|
if (res) Debug.Log($"Copy <color=#88ff00>{iOSLib} to {to}</color> success...");
|
||||||
from = $"{files}/{iOSLib}.f.meta";
|
from = $"{files}/{iOSLib}.f.meta";
|
||||||
to = $"{Application.dataPath}/Plugins/iOS/{iOSLib}.meta";
|
to = $"{Application.dataPath}/Plugins/iOS/{iOSLib}.meta";
|
||||||
CopyFile(from, to);
|
CopyFile(from, to); // 无需覆盖
|
||||||
|
|
||||||
AssetDatabase.Refresh();
|
AssetDatabase.Refresh();
|
||||||
}
|
}
|
||||||
|
|
@ -55,25 +55,25 @@ namespace Guru
|
||||||
return Path.GetFullPath($"{Application.dataPath}/../Packages/com.guru.unity.sdk.core/Runtime/GuruAdjust/Editor/Signature");
|
return Path.GetFullPath($"{Application.dataPath}/../Packages/com.guru.unity.sdk.core/Runtime/GuruAdjust/Editor/Signature");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool CopyFile(string source, string dest)
|
private static bool CopyFile(string from, string to, bool overwrite = false)
|
||||||
{
|
{
|
||||||
if (File.Exists(source))
|
if (File.Exists(to) && !overwrite)
|
||||||
{
|
{
|
||||||
if (!File.Exists(dest))
|
// 如果目标文件存在, 且不允许覆写, 则不进行拷贝
|
||||||
{
|
return false;
|
||||||
File.Delete(dest);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var destDir = Directory.GetParent(dest);
|
|
||||||
if(!destDir.Exists) destDir.Create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
File.Copy(source, dest, true);
|
if (File.Exists(from))
|
||||||
|
{
|
||||||
|
// 确保拷贝目录存在
|
||||||
|
var destDir = Directory.GetParent(to);
|
||||||
|
if(destDir != null && !destDir.Exists) destDir.Create();
|
||||||
|
|
||||||
|
File.Copy(from, to, overwrite);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Log($"<colo=red>File not found: {source}...</color>");
|
Debug.Log($"<colo=red>File not found: {from}...</color>");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,18 +8,20 @@ Sample Dependencies.xml:
|
||||||
<androidPackage spec="androidx.core:core:1.7.0" />
|
<androidPackage spec="androidx.core:core:1.7.0" />
|
||||||
<!-- <androidPackage spec="androidx.appcompat:appcompat:1.5.1" />-->
|
<!-- <androidPackage spec="androidx.appcompat:appcompat:1.5.1" />-->
|
||||||
<androidPackage spec="androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" />
|
<androidPackage spec="androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" />
|
||||||
<androidPackage spec="androidx.work:work-runtime:2.7.1" />
|
<androidPackage spec="androidx.work:work-runtime:2.8.1" />
|
||||||
<androidPackage spec="androidx.work:work-runtime-ktx:2.7.1" />
|
<androidPackage spec="androidx.work:work-runtime-ktx:2.8.1" />
|
||||||
<androidPackage spec="androidx.work:work-rxjava2:2.7.1" />
|
<androidPackage spec="androidx.work:work-rxjava2:2.8.1" />
|
||||||
<androidPackage spec="androidx.lifecycle:lifecycle-process:2.4.0" />
|
<androidPackage spec="androidx.lifecycle:lifecycle-process:2.4.0" />
|
||||||
<androidPackage spec="com.jakewharton.timber:timber:4.7.1" />
|
<androidPackage spec="com.jakewharton.timber:timber:4.7.1" />
|
||||||
<androidPackage spec="com.google.code.gson:gson:2.8.5" />
|
<androidPackage spec="com.google.code.gson:gson:2.8.5" />
|
||||||
<androidPackage spec="androidx.room:room-runtime:2.4.3" />
|
<androidPackage spec="androidx.room:room-runtime:2.6.1" />
|
||||||
<androidPackage spec="androidx.room:room-rxjava2:2.4.3" />
|
<androidPackage spec="androidx.room:room-rxjava2:2.6.1" />
|
||||||
<androidPackage spec="com.squareup.retrofit2:retrofit:2.7.1" />
|
<androidPackage spec="com.squareup.retrofit2:retrofit:2.7.1" />
|
||||||
<androidPackage spec="com.squareup.retrofit2:converter-gson:2.7.1" />
|
<androidPackage spec="com.squareup.retrofit2:converter-gson:2.7.1" />
|
||||||
<androidPackage spec="com.squareup.retrofit2:adapter-rxjava2:2.7.1" />
|
<androidPackage spec="com.squareup.retrofit2:adapter-rxjava2:2.7.1" />
|
||||||
<androidPackage spec="com.squareup.okhttp3:okhttp:4.9.3" />
|
<androidPackage spec="com.squareup.okhttp3:okhttp:4.12.0" />
|
||||||
|
<androidPackage spec="com.squareup.okhttp3:okhttp-dnsoverhttps:4.12.0" />
|
||||||
|
<androidPackage spec="com.google.net.cronet:cronet-okhttp:0.1.0" />
|
||||||
<!-- <androidPackage spec="com.mapzen:on-the-road:0.8.1" />-->
|
<!-- <androidPackage spec="com.mapzen:on-the-road:0.8.1" />-->
|
||||||
<!-- <androidPackage spec="com.squareup.retrofit2:retrofit:2.7.1" />-->
|
<!-- <androidPackage spec="com.squareup.retrofit2:retrofit:2.7.1" />-->
|
||||||
</androidPackages>
|
</androidPackages>
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,5 +1,5 @@
|
||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 32eda01e213614348899eefe856392d3
|
guid: 8009d3bf70bb4438599a32f6ea601f9d
|
||||||
PluginImporter:
|
PluginImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
Binary file not shown.
|
|
@ -1,6 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -14,7 +11,7 @@ namespace Guru
|
||||||
public class GuruAnalytics
|
public class GuruAnalytics
|
||||||
{
|
{
|
||||||
// Plugin Version
|
// Plugin Version
|
||||||
private const string Version = "1.11.1";
|
private const string Version = "1.12.0";
|
||||||
|
|
||||||
public static readonly string Tag = "[ANU]";
|
public static readonly string Tag = "[ANU]";
|
||||||
private static readonly string ActionName = "logger_error";
|
private static readonly string ActionName = "logger_error";
|
||||||
|
|
@ -86,6 +83,9 @@ namespace Guru
|
||||||
private readonly List<int> _errorCodeList = new List<int>();
|
private readonly List<int> _errorCodeList = new List<int>();
|
||||||
private bool _enableErrorLog;
|
private bool _enableErrorLog;
|
||||||
|
|
||||||
|
private string _experimentGroupId;
|
||||||
|
public string ExperimentGroupId => _experimentGroupId;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 启动日志错误上报
|
/// 启动日志错误上报
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -105,20 +105,46 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化接口
|
/// 初始化接口
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false,
|
public static void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false)
|
||||||
bool enableErrorLog = false)
|
|
||||||
{
|
{
|
||||||
Debug.Log($"{Tag} --- Guru Analytics [{Version}] initialing...");
|
Debug.Log($"{Tag} --- Guru Analytics [{Version}] initialing...");
|
||||||
|
|
||||||
if (_instance == null)
|
if (_instance == null)
|
||||||
{
|
{
|
||||||
_instance = new GuruAnalytics();
|
_instance = new GuruAnalytics();
|
||||||
|
bool enableErrorLog = false;
|
||||||
|
string groupId = "not_set";
|
||||||
|
#if UNITY_ANDROID
|
||||||
|
enableErrorLog = true;
|
||||||
|
// 获取云控参数
|
||||||
|
// TODO: 针对 GuruSDK 整体的云控值做一个分组的解决方案
|
||||||
|
var guruInitParams = GuruAnalyticsConfigManager.GetInitParams();
|
||||||
|
// 记录分组数据
|
||||||
|
groupId = guruInitParams.groupId;
|
||||||
|
|
||||||
|
if (guruInitParams.enabled && Instance.Agent is AnalyticsAgentAndroid androidAgent)
|
||||||
|
{
|
||||||
|
// 强制转换为 Android 的自打点初始化接口
|
||||||
|
androidAgent.InitAndroidConfig(appId, deviceInfo,
|
||||||
|
guruInitParams.baseUrl, guruInitParams.uploadIpAddress, // <--- Android 附加参数
|
||||||
|
onInitComplete, isDebug);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 外部(云控)如果关闭使用 Android 自打点附加参数, 则使用正常的启动接口
|
||||||
_instance.Agent.Init(appId, deviceInfo, onInitComplete, isDebug);
|
_instance.Agent.Init(appId, deviceInfo, onInitComplete, isDebug);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// iOS 使用正常的启动接口
|
||||||
|
_instance.Agent.Init(appId, deviceInfo, onInitComplete, isDebug);
|
||||||
|
#endif
|
||||||
|
|
||||||
_instance.EnableErrorLog = enableErrorLog;
|
_instance.EnableErrorLog = enableErrorLog;
|
||||||
_instance._isReady = true;
|
_instance._isReady = true;
|
||||||
|
_instance._experimentGroupId = groupId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置视图名称
|
/// 设置视图名称
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -450,92 +476,6 @@ namespace Guru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
private void ParseWithRaw(string raw)
|
|
||||||
{
|
|
||||||
var code = (int)AnalyticsCode.Unknown;
|
|
||||||
string info;
|
|
||||||
|
|
||||||
//------- message send to unity ----------
|
|
||||||
Debug.Log($"{Tag} get callback errorInfo:\n{raw}");
|
|
||||||
|
|
||||||
|
|
||||||
var patten = "msg\":\"";
|
|
||||||
if (raw.Contains(patten))
|
|
||||||
{
|
|
||||||
|
|
||||||
info = raw.Substring(raw.IndexOf(patten, StringComparison.Ordinal) + patten.Length);
|
|
||||||
if (!string.IsNullOrEmpty(info))
|
|
||||||
{
|
|
||||||
if (info.StartsWith("\"")) info = info.Substring(1, info.Length - 1);
|
|
||||||
if (info.EndsWith("\"}}")) info = info.Replace("\"}}", "");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
info = "msg is null";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
info = "no msg property";
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
var idx = raw.IndexOf(patten, StringComparison.Ordinal) + patten.Length;
|
|
||||||
string act = raw.Substring(idx, ActionName.Length);
|
|
||||||
if (act == ActionName)
|
|
||||||
{
|
|
||||||
patten = "code\":";
|
|
||||||
var patten2 = ",\"msg";
|
|
||||||
idx = raw.IndexOf(patten, StringComparison.Ordinal);
|
|
||||||
var idx2 = raw.IndexOf(patten2, StringComparison.Ordinal);
|
|
||||||
|
|
||||||
var len = idx2 - (idx + patten.Length);
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
string c = raw.Substring(idx + patten.Length, len);
|
|
||||||
int.TryParse(c, out code);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Catch target code to report errors
|
|
||||||
switch ((AnalyticsCode)code)
|
|
||||||
{
|
|
||||||
case AnalyticsCode.Network_Lost:
|
|
||||||
case AnalyticsCode.ERROR_API:
|
|
||||||
case AnalyticsCode.ERROR_RESPONSE:
|
|
||||||
case AnalyticsCode.ERROR_CACHE_CONTROL:
|
|
||||||
case AnalyticsCode.ERROR_DELETE_EXPIRED:
|
|
||||||
case AnalyticsCode.ERROR_LOAD_MARK:
|
|
||||||
case AnalyticsCode.ERROR_DNS:
|
|
||||||
case AnalyticsCode.ERROR_ZIP:
|
|
||||||
OnLoggerErrorEvent(code, info);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Debug.LogError($"{Tag} Catch ex: {ex}\tJson:{raw}");
|
|
||||||
Analytics.LogCrashlytics(raw, false);
|
|
||||||
Analytics.LogCrashlytics($"{Tag} --- Json:{raw} Ex:{ex}");
|
|
||||||
OnLoggerErrorEvent(code, info);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (raw.Contains("msg"))
|
|
||||||
{
|
|
||||||
Analytics.LogCrashlytics(raw, false);
|
|
||||||
Analytics.LogCrashlytics($"{Tag} --- format error:{raw}");
|
|
||||||
OnLoggerErrorEvent(code, raw.Substring(raw.IndexOf("msg\":", StringComparison.Ordinal) + 5));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
**/
|
|
||||||
|
|
||||||
private void ReportCodeInfo(int code, string info)
|
private void ReportCodeInfo(int code, string info)
|
||||||
{
|
{
|
||||||
var ac = (AnalyticsCode)code;
|
var ac = (AnalyticsCode)code;
|
||||||
|
|
@ -558,11 +498,13 @@ namespace Guru
|
||||||
case AnalyticsCode.ERROR_ZIP:
|
case AnalyticsCode.ERROR_ZIP:
|
||||||
case AnalyticsCode.ERROR_DNS_CACHE:
|
case AnalyticsCode.ERROR_DNS_CACHE:
|
||||||
case AnalyticsCode.CRONET_INTERCEPTOR:
|
case AnalyticsCode.CRONET_INTERCEPTOR:
|
||||||
|
case AnalyticsCode.EVENT_LOOKUP:
|
||||||
|
case AnalyticsCode.EVENT_SESSION_ACTIVE:
|
||||||
canCatch = true;
|
canCatch = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code > 100 && code <= 200)
|
if (!canCatch && code is > 100 and <= 200)
|
||||||
{
|
{
|
||||||
// 100 < code <= 200
|
// 100 < code <= 200
|
||||||
canCatch = true;
|
canCatch = true;
|
||||||
|
|
@ -601,6 +543,8 @@ namespace Guru
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 网络状态枚举
|
/// 网络状态枚举
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -608,21 +552,24 @@ namespace Guru
|
||||||
{
|
{
|
||||||
Unknown = -1,
|
Unknown = -1,
|
||||||
|
|
||||||
DELETE_EXPIRED = 12,
|
DELETE_EXPIRED = 12, // 删除过期事件
|
||||||
UPLOAD_FAIL = 14,
|
UPLOAD_FAIL = 14, // 上报事件失败
|
||||||
NETWORK_LOST = 22,
|
NETWORK_LOST = 22, // 网络状态不可用
|
||||||
CRONET_INIT_FAIL = 26,
|
CRONET_INIT_FAIL = 26, // 开启Cronet失败
|
||||||
CRONET_INIT_EXCEPTION = 27,
|
CRONET_INIT_EXCEPTION = 27, // 开启Cronet报错
|
||||||
|
|
||||||
ERROR_API = 101,
|
ERROR_API = 101, // 调用api出错
|
||||||
ERROR_RESPONSE = 102,
|
ERROR_RESPONSE = 102, // api返回结果错误
|
||||||
ERROR_CACHE_CONTROL = 103,
|
ERROR_CACHE_CONTROL = 103, // 设置cacheControl出错
|
||||||
ERROR_DELETE_EXPIRED = 104,
|
ERROR_DELETE_EXPIRED = 104, // 删除过期事件出错
|
||||||
ERROR_LOAD_MARK = 105,
|
ERROR_LOAD_MARK = 105, // 从数据库取事件以及更改事件状态为正在上报出错
|
||||||
ERROR_DNS = 106,
|
ERROR_DNS = 106, // dns 错误
|
||||||
ERROR_ZIP = 107,
|
ERROR_ZIP = 107, // zip 错误
|
||||||
ERROR_DNS_CACHE = 108,
|
ERROR_DNS_CACHE = 108, // zip 错误
|
||||||
CRONET_INTERCEPTOR = 109,
|
CRONET_INTERCEPTOR = 109, // cronet拦截器
|
||||||
|
|
||||||
|
EVENT_LOOKUP = 1003,
|
||||||
|
EVENT_SESSION_ACTIVE = 1004,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,274 @@
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
using Random = UnityEngine.Random;
|
||||||
|
using Firebase.RemoteConfig;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
public class GuruAnalyticsConfigManager
|
||||||
|
{
|
||||||
|
|
||||||
|
private const string Tag = "[SDK][ANU][EXP]";
|
||||||
|
|
||||||
|
private static bool IsDebug
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR || DEBUG
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static string _localExperimentGroupId = "";
|
||||||
|
private static string LocalExperimentGroupId
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_localExperimentGroupId))
|
||||||
|
{
|
||||||
|
_localExperimentGroupId = PlayerPrefs.GetString(nameof(LocalExperimentGroupId), "");
|
||||||
|
}
|
||||||
|
return _localExperimentGroupId;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_localExperimentGroupId = value;
|
||||||
|
PlayerPrefs.SetString(nameof(LocalExperimentGroupId), value);
|
||||||
|
PlayerPrefs.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始数据
|
||||||
|
private const string JSON_GROUP_B =
|
||||||
|
"{\"cap\":\"firebase|facebook|guru\",\"init_delay_s\":10,\"experiment\":\"B\",\"guru_upload_ip_address\":[\"13.248.248.135\", \"3.33.195.44\"]}";
|
||||||
|
|
||||||
|
private const string JSON_GROUP_C =
|
||||||
|
"{\"cap\":\"firebase|facebook|guru\",\"init_delay_s\":10,\"experiment\":\"C\",\"guru_upload_ip_address\":[\"34.107.185.54\"],\"guru_event_url\":\"https://collect3.saas.castbox.fm\"}";
|
||||||
|
**/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 解析 JSON 字符串
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="json"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static GuruAnalyticsExperimentData Parse(string json)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(json)) return null;
|
||||||
|
return JsonParser.ToObject<GuruAnalyticsExperimentData>(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 云控数据参数
|
||||||
|
/// </summary>
|
||||||
|
public const string KEY_GURU_ANALYTICS_EXP = "guru_analytics_exp";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 默认的本地配置
|
||||||
|
/// </summary>
|
||||||
|
private const string DEFAULT_GURU_ANALYTICS_EXP = @"{
|
||||||
|
""enable"": true,
|
||||||
|
""exps"": [{
|
||||||
|
""groupId"": ""B"",
|
||||||
|
""baseUrl"": ""https://collect.saas.castbox.fm"",
|
||||||
|
""uploadIpAddress"": [""13.248.248.135"", ""3.33.195.44""]
|
||||||
|
}, {
|
||||||
|
""groupId"": ""C"",
|
||||||
|
""baseUrl"": ""https://collect3.saas.castbox.fm"",
|
||||||
|
""uploadIpAddress"": [""34.107.185.54""]
|
||||||
|
}]
|
||||||
|
}";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取默认数据
|
||||||
|
/// </summary>
|
||||||
|
private static GuruAnalyticsExperimentData DefaultData => Parse(DEFAULT_GURU_ANALYTICS_EXP);
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在当前版本中,随机获取线上配置的值
|
||||||
|
/// 若无法获取线上配置,则默认是 B 分组
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="groupId"></param>
|
||||||
|
/// <param name="baseUrl"></param>
|
||||||
|
/// <param name="uploadIpAddress"></param>
|
||||||
|
/// <param name="isEnable"></param>
|
||||||
|
internal static GuruInitParams GetInitParams()
|
||||||
|
{
|
||||||
|
var groupId = "";
|
||||||
|
var baseUrl = "";
|
||||||
|
string[] uploadIpAddress = null;
|
||||||
|
var isEnabled = true;
|
||||||
|
GuruAnalyticsExperimentConfig config;
|
||||||
|
|
||||||
|
if(IsDebug) Debug.LogWarning($"{Tag} --- #0 Analytics EXP saved groupId :{LocalExperimentGroupId}");
|
||||||
|
|
||||||
|
// 拉取云控数据
|
||||||
|
var json = "";
|
||||||
|
if(FirebaseUtil.IsFirebaseInitialized && FirebaseRemoteConfig.DefaultInstance.Keys.Contains(KEY_GURU_ANALYTICS_EXP))
|
||||||
|
json = FirebaseRemoteConfig.DefaultInstance.GetValue(GuruAnalyticsConfigManager.KEY_GURU_ANALYTICS_EXP).StringValue;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(json))
|
||||||
|
{
|
||||||
|
// 没有云控值,走本地的数据配置,随机取值
|
||||||
|
if(IsDebug) Debug.LogWarning($"{Tag} --- #1 Analytics EXP json is Null -> using DefaultData");
|
||||||
|
config = GetDefaultGuruAnalyticsExpConfig();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 有云控值,则直接使用云控的数据
|
||||||
|
if(IsDebug) Debug.LogWarning($"{Tag} --- #2 Analytics EXP Try to get remote json -> {json}");
|
||||||
|
var expData = Parse(json);
|
||||||
|
if (expData == null)
|
||||||
|
{
|
||||||
|
// 如果云控值为空,则使用本地分组
|
||||||
|
if(IsDebug) Debug.LogWarning($"{Tag} --- #2.1 Analytics EXP Parse failed -> using DefaultData");
|
||||||
|
config = GetDefaultGuruAnalyticsExpConfig();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 如果云控值不为空,但不可用,则直接使用默认分组
|
||||||
|
if (!expData.enable)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"{Tag} --- #2.2 Analytics EXP Disabled -> using DefaultData");
|
||||||
|
expData = DefaultData;
|
||||||
|
}
|
||||||
|
config = expData.GetFirstConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最后取不到的话只能默认分组了
|
||||||
|
if (config == null) {
|
||||||
|
config = DefaultData.GetFirstConfig(); // 默认是 B 组
|
||||||
|
if(IsDebug) Debug.LogWarning($"{Tag} --- #3 Try get config is Null -> using Default config");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config != null)
|
||||||
|
{
|
||||||
|
baseUrl = config.baseUrl;
|
||||||
|
groupId = config.groupId;
|
||||||
|
uploadIpAddress = config.uploadIpAddress;
|
||||||
|
LocalExperimentGroupId = groupId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isEnabled = false;
|
||||||
|
}
|
||||||
|
Debug.Log($"{Tag} --- Analytics EXP params:: groupId:{groupId} baseUrl:{baseUrl} uploadIpAddress:[{ (uploadIpAddress != null ? string.Join(",", uploadIpAddress) : "null")}]");
|
||||||
|
|
||||||
|
return new GuruInitParams()
|
||||||
|
{
|
||||||
|
groupId = groupId,
|
||||||
|
baseUrl = baseUrl,
|
||||||
|
uploadIpAddress = uploadIpAddress,
|
||||||
|
enabled = isEnabled
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static GuruAnalyticsExperimentConfig GetDefaultGuruAnalyticsExpConfig()
|
||||||
|
{
|
||||||
|
GuruAnalyticsExperimentConfig config = null;
|
||||||
|
if (!string.IsNullOrEmpty(LocalExperimentGroupId))
|
||||||
|
{
|
||||||
|
config = DefaultData.GetConfig(LocalExperimentGroupId); // 非空则取值
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
config = DefaultData.GetRandomConfig(); // 随机获取本地的 Config
|
||||||
|
}
|
||||||
|
if(IsDebug) Debug.LogWarning($"{Tag} --- #1.1 using Default GroupId: {config.groupId}");
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 实验数据主题
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
internal class GuruAnalyticsExperimentData
|
||||||
|
{
|
||||||
|
public readonly bool enable = true; // 默认是打开的状态
|
||||||
|
public GuruAnalyticsExperimentConfig[] experiments; // 实验列表
|
||||||
|
public string ToJson() => JsonParser.ToJson(this); // 转换成 JSON 字符串
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取随机分组
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public GuruAnalyticsExperimentConfig GetRandomConfig()
|
||||||
|
{
|
||||||
|
if (experiments == null || experiments.Length == 0) return null;
|
||||||
|
return experiments[Random.Range(0, experiments.Length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据分组名称获取分组
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="groupId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public GuruAnalyticsExperimentConfig GetConfig(string groupId)
|
||||||
|
{
|
||||||
|
foreach (var g in experiments)
|
||||||
|
{
|
||||||
|
if (g.groupId == groupId) return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取首个配置
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public GuruAnalyticsExperimentConfig GetFirstConfig()
|
||||||
|
{
|
||||||
|
if (experiments != null && experiments.Length > 0) return experiments[0];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分组是否存在
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="groupId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsGroupExists(string groupId)
|
||||||
|
{
|
||||||
|
foreach (var g in experiments)
|
||||||
|
{
|
||||||
|
if (g.groupId == groupId) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 实验配置
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
internal class GuruAnalyticsExperimentConfig
|
||||||
|
{
|
||||||
|
public string groupId;
|
||||||
|
public string baseUrl;
|
||||||
|
public string[] uploadIpAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
internal class GuruInitParams
|
||||||
|
{
|
||||||
|
public string groupId;
|
||||||
|
public string baseUrl;
|
||||||
|
public string[] uploadIpAddress;
|
||||||
|
public bool enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a840d9218d324971b528c639ddfea270
|
||||||
|
timeCreated: 1721722549
|
||||||
|
|
@ -17,7 +17,7 @@ namespace Guru
|
||||||
void SetUid(string uid);
|
void SetUid(string uid);
|
||||||
bool IsDebug { get; }
|
bool IsDebug { get; }
|
||||||
bool EnableErrorLog { get; set; }
|
bool EnableErrorLog { get; set; }
|
||||||
void LogEvent(string eventName, string parameters, int priority = -1);
|
void LogEvent(string eventName, string parameters, int priority = 0);
|
||||||
void ReportEventSuccessRate(); // 上报任务成功率
|
void ReportEventSuccessRate(); // 上报任务成功率
|
||||||
void SetTch02Value(double value); // 设置太极02数值
|
void SetTch02Value(double value); // 设置太极02数值
|
||||||
void InitCallback(string objName, string method); // 设置回调对象参数
|
void InitCallback(string objName, string method); // 设置回调对象参数
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -12,20 +8,16 @@ namespace Guru
|
||||||
|
|
||||||
#if UNITY_ANDROID
|
#if UNITY_ANDROID
|
||||||
|
|
||||||
public static readonly string AnalyticsClassName = "com.guru.unity.analytics.Analytics";
|
private static readonly string AnalyticsClassName = "com.guru.unity.analytics.Analytics";
|
||||||
private static AndroidJavaClass _classAnalytics;
|
private static AndroidJavaClass _classAnalytics;
|
||||||
private static AndroidJavaClass ClassAnalytics => _classAnalytics ??= new AndroidJavaClass(AnalyticsClassName);
|
private static AndroidJavaClass ClassAnalytics => _classAnalytics ??= new AndroidJavaClass(AnalyticsClassName);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
private static bool _isDebug = false;
|
private static bool _isDebug = false;
|
||||||
public static bool UseWorker = true;
|
|
||||||
public static bool UseCronet = false;
|
|
||||||
public static string BaseUrl = "";
|
public static string BaseUrl = "";
|
||||||
|
|
||||||
#region 工具方法
|
#region 工具方法
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 调用静态方法
|
/// 调用静态方法
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -64,7 +56,7 @@ namespace Guru
|
||||||
{
|
{
|
||||||
if (ClassAnalytics != null)
|
if (ClassAnalytics != null)
|
||||||
{
|
{
|
||||||
if(_isDebug) Debug.Log($"{GuruAnalytics.Tag} Android call static <{typeof(T).ToString()}> :: {methodName}");
|
if(_isDebug) Debug.Log($"{GuruAnalytics.Tag} Android call static <{typeof(T)}> :: {methodName}");
|
||||||
return ClassAnalytics.CallStatic<T>(methodName, args);
|
return ClassAnalytics.CallStatic<T>(methodName, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -80,18 +72,61 @@ namespace Guru
|
||||||
|
|
||||||
#region 接口实现
|
#region 接口实现
|
||||||
|
|
||||||
public async void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false)
|
/// <summary>
|
||||||
|
/// 默认的启动参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="appId"></param>
|
||||||
|
/// <param name="deviceInfo"></param>
|
||||||
|
/// <param name="onInitComplete"></param>
|
||||||
|
/// <param name="isDebug"></param>
|
||||||
|
public void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false)
|
||||||
|
{
|
||||||
|
InitAndroidConfig(appId, deviceInfo, "", null, onInitComplete, isDebug); // 调用接口
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 面向 Android 启动专用的 API
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="appId"></param>
|
||||||
|
/// <param name="deviceInfo"></param>
|
||||||
|
/// <param name="baseUrl"></param>
|
||||||
|
/// <param name="uploadIpAddress"></param>
|
||||||
|
/// <param name="onInitComplete"></param>
|
||||||
|
/// <param name="isDebug"></param>
|
||||||
|
public void InitAndroidConfig(string appId, string deviceInfo, string baseUrl, string[]uploadIpAddress,Action onInitComplete = null, bool isDebug = false)
|
||||||
{
|
{
|
||||||
_isDebug = isDebug;
|
_isDebug = isDebug;
|
||||||
string bundleId = Application.identifier;
|
string bundleId = Application.identifier;
|
||||||
// public static void init(String appId, String deviceInfo, String bundleId, boolean isDebug, boolean useWorker, boolean useCronet, String baseUrl)
|
CallSDKInit(appId, deviceInfo, bundleId, baseUrl, uploadIpAddress , true, false, _isDebug); // 调用接口
|
||||||
|
|
||||||
// TODO: 将来把 CallStatic 转为异步实现
|
|
||||||
CallStatic("init", appId, deviceInfo, bundleId, isDebug, UseWorker, UseCronet, BaseUrl); // 调用接口
|
|
||||||
|
|
||||||
onInitComplete?.Invoke();
|
onInitComplete?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/********* Android API **********
|
||||||
|
public static void init(String appId,
|
||||||
|
String deviceInfo,
|
||||||
|
String bundleId,
|
||||||
|
boolean debug,
|
||||||
|
boolean useWorker,
|
||||||
|
boolean enabledCronet,
|
||||||
|
String baseUrl,
|
||||||
|
List<String> uploadIpAddress)
|
||||||
|
*/
|
||||||
|
private void CallSDKInit(string appId,
|
||||||
|
string deviceInfo,
|
||||||
|
string bundleId,
|
||||||
|
string baseUrl = "",
|
||||||
|
string[] uploadIpAddress = null,
|
||||||
|
bool useWorker = true,
|
||||||
|
bool useCronet = false,
|
||||||
|
bool isDebug = false)
|
||||||
|
{
|
||||||
|
CallStatic("init", appId, deviceInfo, bundleId, isDebug, useWorker, useCronet, baseUrl, string.Join(",", uploadIpAddress ?? Array.Empty<string>())); // 调用接口
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void SetScreen(string screenName)
|
public void SetScreen(string screenName)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(screenName)) return;
|
if (string.IsNullOrEmpty(screenName)) return;
|
||||||
|
|
@ -134,10 +169,7 @@ namespace Guru
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDebug => CallStatic<bool>("isDebug");
|
public bool IsDebug => CallStatic<bool>("isDebug");
|
||||||
public void LogEvent(string eventName, string parameters, int priority = -1)
|
public void LogEvent(string eventName, string parameters, int priority = 0) => CallStatic("logEvent", eventName, parameters, priority);
|
||||||
{
|
|
||||||
CallStatic("logEvent", eventName, parameters, priority);
|
|
||||||
}
|
|
||||||
public void ReportEventSuccessRate() => CallStatic("reportEventRate");
|
public void ReportEventSuccessRate() => CallStatic("reportEventRate");
|
||||||
public void SetTch02Value(double value) => CallStatic("setTch02Value", value);
|
public void SetTch02Value(double value) => CallStatic("setTch02Value", value);
|
||||||
public void InitCallback(string objName, string method) => CallStatic("initCallback", objName, method);
|
public void InitCallback(string objName, string method) => CallStatic("initCallback", objName, method);
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ namespace Guru
|
||||||
|
|
||||||
public bool IsDebug => _isDebug;
|
public bool IsDebug => _isDebug;
|
||||||
|
|
||||||
public void LogEvent(string eventName, string data, int priority = -1)
|
public void LogEvent(string eventName, string data, int priority = 0)
|
||||||
{
|
{
|
||||||
#if UNITY_IOS
|
#if UNITY_IOS
|
||||||
unityLogEvent(eventName, data);
|
unityLogEvent(eventName, data);
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ namespace Guru
|
||||||
public bool IsDebug => _isDebug;
|
public bool IsDebug => _isDebug;
|
||||||
|
|
||||||
|
|
||||||
public void LogEvent(string eventName, string parameters, int priority = -1)
|
public void LogEvent(string eventName, string parameters, int priority = 0)
|
||||||
{
|
{
|
||||||
if (_isShowLog)
|
if (_isShowLog)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 82693d012b64748c8ac997389b0426a7
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,143 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace Guru
|
|
||||||
{
|
|
||||||
public class GuruAnalyticsDemo: MonoBehaviour
|
|
||||||
{
|
|
||||||
[SerializeField] private bool _isDebug = true;
|
|
||||||
[SerializeField] private Button _btnInitSDK;
|
|
||||||
[SerializeField] private Button _btnStatus;
|
|
||||||
[SerializeField] private Button _btnUserProperties;
|
|
||||||
[SerializeField] private Button _btnEvents;
|
|
||||||
[SerializeField] private Button _btnEvents2;
|
|
||||||
[SerializeField] private Button _btnReport;
|
|
||||||
[SerializeField] private Button _btnTestCrash;
|
|
||||||
|
|
||||||
// ----------- All Status IDs -----------
|
|
||||||
private static readonly string AdjustID = "e35b41522140fa2db9089ef3c78eb8f9";
|
|
||||||
private static readonly string FirebaseID = "b7ab5fc399a7bc8725c004943fa82837";
|
|
||||||
private static readonly string UID = "BS-YYYYF";
|
|
||||||
private static readonly string AdID = "dda3cc2b-5a5e-44cb-8a59-4a0b1b3780fd";
|
|
||||||
private static readonly string DeviceID = "e2fb3c5a4c36473648c989bd86a41153";
|
|
||||||
private static readonly string AppID = "";
|
|
||||||
private static readonly string DeviceInfo = "";
|
|
||||||
|
|
||||||
|
|
||||||
private static readonly string ScreenName = "MainMenu";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void Awake()
|
|
||||||
{
|
|
||||||
_btnInitSDK.onClick.AddListener(OnClickInit);
|
|
||||||
_btnStatus.onClick.AddListener(OnClickStatus);
|
|
||||||
_btnUserProperties.onClick.AddListener(OnClickUserProperties);
|
|
||||||
_btnEvents.onClick.AddListener(OnClickEvents);
|
|
||||||
_btnEvents2.onClick.AddListener(OnClickEvents2);
|
|
||||||
_btnReport.onClick.AddListener(OnClickReport);
|
|
||||||
_btnTestCrash.onClick.AddListener(OnClickTestCrash);
|
|
||||||
#if !UNITY_IOS
|
|
||||||
_btnTestCrash.gameObject.SetActive(false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region Button Callbacks
|
|
||||||
|
|
||||||
|
|
||||||
private void OnClickInit()
|
|
||||||
{
|
|
||||||
Debug.Log($"---- [DEMO] Call Analytics init");
|
|
||||||
GuruAnalytics.Init(AppID, DeviceInfo, OnGuruAnalyticsInitComplete, _isDebug);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnGuruAnalyticsInitComplete()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnClickStatus()
|
|
||||||
{
|
|
||||||
Debug.Log($"---- [DEMO] Report Stats IDs: UID:{UID} DeviceID:{DeviceID} FirebaseID:{FirebaseID} AdID:{AdID} AdjustID:{AdjustID}");
|
|
||||||
GuruAnalytics.Instance.SetUid(UID);
|
|
||||||
GuruAnalytics.Instance.SetDeviceId(DeviceID);
|
|
||||||
GuruAnalytics.Instance.SetFirebaseId(FirebaseID);
|
|
||||||
GuruAnalytics.Instance.SetAdId(AdID);
|
|
||||||
GuruAnalytics.Instance.SetAdjustId(AdjustID);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnClickUserProperties()
|
|
||||||
{
|
|
||||||
string item_category = "main";
|
|
||||||
int level = 7;
|
|
||||||
Debug.Log($"---- [DEMO] Call SetUserProperty: item_category:{item_category} level:{level}");
|
|
||||||
GuruAnalytics.Instance.SetUserProperty("item_category", item_category);
|
|
||||||
GuruAnalytics.Instance.SetUserProperty("level", level.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnClickEvents()
|
|
||||||
{
|
|
||||||
Debug.Log($"---- [DEMO] Report Screen: {ScreenName}");
|
|
||||||
GuruAnalytics.Instance.SetScreen(ScreenName);
|
|
||||||
|
|
||||||
string eventName = "user_get_coin";
|
|
||||||
Dictionary<string, dynamic> data = new Dictionary<string, dynamic>()
|
|
||||||
{
|
|
||||||
{ "level", 7 },
|
|
||||||
{ "user_coin", 105L },
|
|
||||||
{ "win_rate", 21.25f },
|
|
||||||
{ "b_level", 7 },
|
|
||||||
{ "result", "retry" }
|
|
||||||
};
|
|
||||||
|
|
||||||
string s = "---- Data ----\n";
|
|
||||||
foreach (var k in data.Keys)
|
|
||||||
{
|
|
||||||
s += $"-- K:{k} V:{data[k]}\n";
|
|
||||||
}
|
|
||||||
Debug.Log(s);
|
|
||||||
|
|
||||||
Debug.Log($"---- [DEMO] Call LogEvent");
|
|
||||||
GuruAnalytics.Instance.LogEvent(eventName, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnClickEvents2()
|
|
||||||
{
|
|
||||||
string eventName = "user_data_loaded";
|
|
||||||
GuruAnalytics.Instance.LogEvent(eventName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void OnClickReport()
|
|
||||||
{
|
|
||||||
GuruAnalytics.Instance.ReportEventSuccessRate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void OnClickTestCrash()
|
|
||||||
{
|
|
||||||
#if UNITY_IOS
|
|
||||||
Debug.Log($"--> OnClickTestCrash");
|
|
||||||
GuruAnalytics.TestCrash();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 8fde2a18f7d347408a6b869ee03e7de9
|
|
||||||
timeCreated: 1672712830
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: ea095a004daab4fc096aa297c21fca99
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -116,7 +116,7 @@ namespace Guru
|
||||||
|
|
||||||
private void OnLoadMaxBanner()
|
private void OnLoadMaxBanner()
|
||||||
{
|
{
|
||||||
_badsloadStartTime = DateTime.UtcNow;
|
_badsLoadStartTime = DateTime.UtcNow;
|
||||||
_chanelMax.LoadBannerAD();
|
_chanelMax.LoadBannerAD();
|
||||||
OnBannerStartLoad?.Invoke(_chanelMax.MaxBADSSlotID);
|
OnBannerStartLoad?.Invoke(_chanelMax.MaxBADSSlotID);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Guru.Ads;
|
|
||||||
|
|
||||||
|
//TODO: 将 BADS,IADS,RADS 分别放到不同的类中,方便维护
|
||||||
public abstract class ADServiceBase<T> : IADService where T : new()
|
public abstract class ADServiceBase<T> : IADService where T : new()
|
||||||
{
|
{
|
||||||
// 单利定义
|
// 单利定义
|
||||||
|
|
@ -21,9 +20,9 @@ namespace Guru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static readonly string Tag = "[SDK][ADS]";
|
private const string Tag = "[SDK][ADS]";
|
||||||
public bool IsInitialized => MaxSdk.IsInitialized() || _isServiceStarted;
|
public bool IsInitialized => MaxSdk.IsInitialized() || _isServiceStarted;
|
||||||
protected bool IsNetworkEnabled => Application.internetReachability != NetworkReachability.NotReachable;
|
private static bool IsNetworkEnabled => Application.internetReachability != NetworkReachability.NotReachable;
|
||||||
|
|
||||||
private const int MAX_ADS_RELOAD_INTERVAL = 6; // 广告加载最高时间为 2 的 6 次方 = 64秒
|
private const int MAX_ADS_RELOAD_INTERVAL = 6; // 广告加载最高时间为 2 的 6 次方 = 64秒
|
||||||
|
|
||||||
|
|
@ -31,28 +30,23 @@ namespace Guru
|
||||||
|
|
||||||
protected Action _onSdkInitReady;
|
protected Action _onSdkInitReady;
|
||||||
|
|
||||||
public static Action<string> OnBannerStartLoad;
|
public Action<string> OnBannerStartLoad;
|
||||||
public static Action OnBannerLoaded;
|
public Action OnBannerLoaded;
|
||||||
|
|
||||||
public static Action<string> OnInterstitialStartLoad;
|
public Action<string> OnInterstitialStartLoad;
|
||||||
public static Action OnInterstitialLoaded;
|
public Action OnInterstitialLoaded;
|
||||||
public static Action OnInterstitialFailed;
|
public Action OnInterstitialFailed;
|
||||||
public static Action OnInterstitialClosed;
|
public Action OnInterstitialClosed;
|
||||||
|
|
||||||
public static Action<string> OnRewardedStartLoad;
|
public Action<string> OnRewardedStartLoad;
|
||||||
public static Action OnRewardLoaded;
|
public Action OnRewardLoaded;
|
||||||
public static Action OnRewardFailed;
|
public Action OnRewardFailed;
|
||||||
public static Action OnRewardClosed;
|
public Action OnRewardClosed;
|
||||||
|
|
||||||
private Dictionary<string, string> _reviewCreativeIds = new Dictionary<string, string>(10); // Creative ID 缓存: Cid : RCid
|
private AdsModel _model;
|
||||||
private Dictionary<string, List<AdImpressionData>> _impressionCache = new Dictionary<string, List<AdImpressionData>>(10);
|
|
||||||
|
|
||||||
protected AdsModel _model;
|
|
||||||
protected AdsInitSpec _initSpec = null;
|
protected AdsInitSpec _initSpec = null;
|
||||||
|
|
||||||
private AdImpressionDriver _impressionDriver;
|
private AdsModel Model
|
||||||
|
|
||||||
public AdsModel Model
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
@ -67,8 +61,7 @@ namespace Guru
|
||||||
/// 启动广告服务
|
/// 启动广告服务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="callback">广告初始化回调</param>
|
/// <param name="callback">广告初始化回调</param>
|
||||||
/// <param name="autoLoadAds">自动启动广告加载</param>
|
/// <param name="initSpec">初始化配置参数</param>
|
||||||
/// <param name="isDebugMode">debug模式</param>
|
|
||||||
public virtual void StartService(Action callback = null, AdsInitSpec initSpec = null)
|
public virtual void StartService(Action callback = null, AdsInitSpec initSpec = null)
|
||||||
{
|
{
|
||||||
if (IsInitialized) return; // 已经初始化后, 无需再次初始化
|
if (IsInitialized) return; // 已经初始化后, 无需再次初始化
|
||||||
|
|
@ -82,9 +75,6 @@ namespace Guru
|
||||||
if(_model == null) _model = AdsModel.Create();
|
if(_model == null) _model = AdsModel.Create();
|
||||||
this.Log("AD SDK Start Init");
|
this.Log("AD SDK Start Init");
|
||||||
|
|
||||||
_impressionDriver = new AdImpressionDriver();
|
|
||||||
_impressionDriver.Init(ReportAdsRevenue); // 初始化 Impression 驱动器
|
|
||||||
|
|
||||||
InitMaxCallbacks(); // 初始化 MAX 广告
|
InitMaxCallbacks(); // 初始化 MAX 广告
|
||||||
InitService(); // 内部继承接口
|
InitService(); // 内部继承接口
|
||||||
}
|
}
|
||||||
|
|
@ -104,8 +94,9 @@ namespace Guru
|
||||||
MaxSdkCallbacks.Banner.OnAdLoadedEvent += OnBannerLoadedEvent;
|
MaxSdkCallbacks.Banner.OnAdLoadedEvent += OnBannerLoadedEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdLoadFailedEvent += OnBannerFailedEvent;
|
MaxSdkCallbacks.Banner.OnAdLoadFailedEvent += OnBannerFailedEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdClickedEvent += OnBannerClickedEvent;
|
MaxSdkCallbacks.Banner.OnAdClickedEvent += OnBannerClickedEvent;
|
||||||
|
// MaxSdkCallbacks.Banner.OnAdReviewCreativeIdGeneratedEvent += OnAdReviewCreativeIdGeneratedEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent += OnBannerRevenuePaidEvent;
|
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent += OnBannerRevenuePaidEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdReviewCreativeIdGeneratedEvent += OnAdReviewCreativeIdGeneratedEvent;
|
|
||||||
//--------------- IV 回调 -----------------
|
//--------------- IV 回调 -----------------
|
||||||
MaxSdkCallbacks.Interstitial.OnAdLoadedEvent += OnInterstitialLoadedEvent;
|
MaxSdkCallbacks.Interstitial.OnAdLoadedEvent += OnInterstitialLoadedEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent += OnInterstitialFailedEvent;
|
MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent += OnInterstitialFailedEvent;
|
||||||
|
|
@ -114,7 +105,7 @@ namespace Guru
|
||||||
MaxSdkCallbacks.Interstitial.OnAdDisplayedEvent += OnInterstitialDisplayEvent;
|
MaxSdkCallbacks.Interstitial.OnAdDisplayedEvent += OnInterstitialDisplayEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdHiddenEvent += OnInterstitialDismissedEvent;
|
MaxSdkCallbacks.Interstitial.OnAdHiddenEvent += OnInterstitialDismissedEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdRevenuePaidEvent += OnInterstitialPaidEvent;
|
MaxSdkCallbacks.Interstitial.OnAdRevenuePaidEvent += OnInterstitialPaidEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdReviewCreativeIdGeneratedEvent += OnAdReviewCreativeIdGeneratedEvent;
|
// MaxSdkCallbacks.Interstitial.OnAdReviewCreativeIdGeneratedEvent += OnAdReviewCreativeIdGeneratedEvent;
|
||||||
//--------------- RV 回调 -----------------
|
//--------------- RV 回调 -----------------
|
||||||
MaxSdkCallbacks.Rewarded.OnAdLoadedEvent += OnRewardedAdLoadedEvent;
|
MaxSdkCallbacks.Rewarded.OnAdLoadedEvent += OnRewardedAdLoadedEvent;
|
||||||
MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent += OnRewardedAdFailedEvent;
|
MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent += OnRewardedAdFailedEvent;
|
||||||
|
|
@ -122,20 +113,15 @@ namespace Guru
|
||||||
MaxSdkCallbacks.Rewarded.OnAdDisplayedEvent += OnRewardedAdDisplayedEvent;
|
MaxSdkCallbacks.Rewarded.OnAdDisplayedEvent += OnRewardedAdDisplayedEvent;
|
||||||
MaxSdkCallbacks.Rewarded.OnAdClickedEvent += OnRewardedAdClickedEvent;
|
MaxSdkCallbacks.Rewarded.OnAdClickedEvent += OnRewardedAdClickedEvent;
|
||||||
MaxSdkCallbacks.Rewarded.OnAdHiddenEvent += OnRewardedAdDismissedEvent;
|
MaxSdkCallbacks.Rewarded.OnAdHiddenEvent += OnRewardedAdDismissedEvent;
|
||||||
MaxSdkCallbacks.Rewarded.OnAdReceivedRewardEvent += OnRewardedAdReceivedRewardEvent;
|
|
||||||
MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent += OnRewardedAdPaidEvent;
|
MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent += OnRewardedAdPaidEvent;
|
||||||
MaxSdkCallbacks.Rewarded.OnAdReviewCreativeIdGeneratedEvent += OnAdReviewCreativeIdGeneratedEvent;
|
MaxSdkCallbacks.Rewarded.OnAdReceivedRewardEvent += OnRewardedAdReceivedRewardEvent;
|
||||||
|
// MaxSdkCallbacks.Rewarded.OnAdReviewCreativeIdGeneratedEvent += OnAdReviewCreativeIdGeneratedEvent;
|
||||||
//--------------- Creative 回调 -----------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-------------- SDK 初始化 -------------------
|
//-------------- SDK 初始化 -------------------
|
||||||
MaxSdk.SetExtraParameter("enable_black_screen_fixes", "true"); // 修复黑屏
|
MaxSdk.SetExtraParameter("enable_black_screen_fixes", "true"); // 修复黑屏
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected virtual void InitService()
|
protected virtual void InitService()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -163,7 +149,7 @@ namespace Guru
|
||||||
/// 可加载广告
|
/// 可加载广告
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual bool CanLoadAds()
|
private bool CanLoadAds()
|
||||||
{
|
{
|
||||||
return IsInitialized && IsNetworkEnabled;
|
return IsInitialized && IsNetworkEnabled;
|
||||||
}
|
}
|
||||||
|
|
@ -214,26 +200,21 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 上报广告收益
|
/// 上报广告收益
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="adInfo"></param>
|
/// <param name="data"></param>
|
||||||
/// <param name="reviewedCreativeId"></param>
|
private void ReportAdsRevenue(AdParams data)
|
||||||
private void ReportAdsRevenue(AdImpressionData data)
|
|
||||||
{
|
{
|
||||||
// #1 ad_impression
|
// #1 ad_impression
|
||||||
Analytics.ADImpression(data);
|
Analytics.ADImpression(data.ToAdImpressionData());
|
||||||
|
|
||||||
// #2 tch_001 和 tch_02
|
// #2 tch_001
|
||||||
double revenue = data.value;
|
double revenue = data.value;
|
||||||
CalcTch001Value(revenue);
|
CalcTch001Value(revenue);
|
||||||
CalcTch02Value(revenue);
|
CalcTch02Value(revenue);
|
||||||
|
|
||||||
// #3 adjust_ad_revenue
|
// #3 adjust_ad_revenue
|
||||||
AdjustService.TrackADRevenue(data.value, data.currency, data.ad_source, data.ad_unit_name, data.ad_placement);
|
AdjustService.TrackADRevenue(data.value, data.currency, data.adSource, data.adUnitId, data.networkPlacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 计算太极001收益
|
/// 计算太极001收益
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -242,10 +223,10 @@ namespace Guru
|
||||||
{
|
{
|
||||||
TchAD001RevValue += revenue;
|
TchAD001RevValue += revenue;
|
||||||
double revenueValue = TchAD001RevValue;
|
double revenueValue = TchAD001RevValue;
|
||||||
Debug.Log($"[TaichConfig] get <TchAD001RevValue> totally: {revenueValue}");
|
// Debug.Log($"{Tag} --- [Tch] get <TchAD001RevValue> totally: {revenueValue}");
|
||||||
if (revenueValue >= Analytics.Tch001TargetValue)
|
if (revenueValue >= Analytics.Tch001TargetValue)
|
||||||
{
|
{
|
||||||
Debug.Log($"[TaichConfig] call <tch_ad_rev_roas_001> with value: {revenueValue}");
|
Debug.Log($"{Tag} --- [Tch] call <tch_ad_rev_roas_001> with value: {revenueValue}");
|
||||||
Analytics.Tch001ADRev(revenueValue);
|
Analytics.Tch001ADRev(revenueValue);
|
||||||
TchAD001RevValue = 0.0;
|
TchAD001RevValue = 0.0;
|
||||||
}
|
}
|
||||||
|
|
@ -274,15 +255,15 @@ namespace Guru
|
||||||
|
|
||||||
#region Banner Ads
|
#region Banner Ads
|
||||||
|
|
||||||
private string _backColorStr = "#50A436";
|
|
||||||
private Color _backColor = new Color(0, 0, 0, 0);
|
private Color _backColor = new Color(0, 0, 0, 0);
|
||||||
private string _badsCategory;
|
private string _badsCategory;
|
||||||
protected DateTime _badsloadStartTime;
|
protected DateTime _badsLoadStartTime;
|
||||||
private bool _bannerVisible = false;
|
private bool _bannerVisible = false;
|
||||||
public bool IsBannerVisible => _bannerVisible;
|
public bool IsBannerVisible => _bannerVisible;
|
||||||
private int _badsloadedNum = 0;
|
private int _badsLoadedNum = 0;
|
||||||
private int _badsLoadFailNum = 0;
|
private int _badsLoadFailNum = 0;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取动作间隔之间的毫秒数
|
/// 获取动作间隔之间的毫秒数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -309,32 +290,32 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Banner MAX 加载方式
|
/// Banner MAX 加载方式
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected void LoadMaxBannerAd()
|
private void LoadMaxBannerAd()
|
||||||
{
|
{
|
||||||
OnLoadBads();
|
OnLoadBads();
|
||||||
// Banners are automatically sized to 320x50 on phones and 728x90 on tablets
|
// Banners are automatically sized to 320x50 on phones and 728x90 on tablets
|
||||||
// You may use the utility method `MaxSdkUtils.isTablet()` to help with view sizing adjustments
|
// You may use the utility method `MaxSdkUtils.isTablet()` to help with view sizing adjustments
|
||||||
var id = GetBannerID();
|
var adUnitId = GetBannerID();
|
||||||
MaxSdk.CreateBanner(id, MaxSdkBase.BannerPosition.BottomCenter);
|
MaxSdk.CreateBanner(adUnitId, MaxSdkBase.BannerPosition.BottomCenter);
|
||||||
MaxSdk.SetBannerExtraParameter(id, "adaptive_banner", "false");
|
MaxSdk.SetBannerExtraParameter(adUnitId, "adaptive_banner", "false");
|
||||||
// Set background or background color for banners to be fully functional
|
// Set background or background color for banners to be fully functional
|
||||||
MaxSdk.SetBannerBackgroundColor(id, _backColor);
|
MaxSdk.SetBannerBackgroundColor(adUnitId, _backColor);
|
||||||
// Analytics.ADBadsLoad(GetBannerID());
|
// Analytics.ADBadsLoad(GetBannerID());
|
||||||
Analytics.ADBadsLoad(AdParams.Build(id));
|
Analytics.TrackAdBadsLoad(AdParams.Build(adUnitId:adUnitId).ToAdLoadedData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLoadBads()
|
private void OnLoadBads()
|
||||||
{
|
{
|
||||||
_badsloadStartTime = DateTime.UtcNow;
|
_badsLoadStartTime = DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnBadsLoaded()
|
private void OnBadsLoaded()
|
||||||
{
|
{
|
||||||
_badsloadStartTime = DateTime.UtcNow;
|
_badsLoadStartTime = DateTime.UtcNow;
|
||||||
OnBannerLoaded?.Invoke();
|
OnBannerLoaded?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SetBannerAutoRefresh(bool value = true, string adUnitId = "")
|
public void SetBannerAutoRefresh(bool value = true, string adUnitId = "")
|
||||||
{
|
{
|
||||||
if(string.IsNullOrEmpty(adUnitId)) adUnitId = GetBannerID();
|
if(string.IsNullOrEmpty(adUnitId)) adUnitId = GetBannerID();
|
||||||
if (value)
|
if (value)
|
||||||
|
|
@ -360,9 +341,10 @@ namespace Guru
|
||||||
SetBannerAutoRefresh(true, adUnitId);
|
SetBannerAutoRefresh(true, adUnitId);
|
||||||
if (!_bannerVisible)
|
if (!_bannerVisible)
|
||||||
{
|
{
|
||||||
|
// 从隐藏状态到显示,累计的加载次数和失败次数清零
|
||||||
_bannerVisible = true;
|
_bannerVisible = true;
|
||||||
OnBannerImpEvent(adUnitId);
|
OnBannerImpEvent(adUnitId);
|
||||||
_badsloadedNum = 0;
|
_badsLoadedNum = 0;
|
||||||
_badsLoadFailNum = 0;
|
_badsLoadFailNum = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -370,7 +352,7 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 隐藏 Banner
|
/// 隐藏 Banner
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void HideBanner()
|
public void HideBanner()
|
||||||
{
|
{
|
||||||
string adUnitId = GetBannerID();
|
string adUnitId = GetBannerID();
|
||||||
MaxSdk.HideBanner(adUnitId);
|
MaxSdk.HideBanner(adUnitId);
|
||||||
|
|
@ -386,47 +368,44 @@ namespace Guru
|
||||||
/// 设置 Banner 背景颜色
|
/// 设置 Banner 背景颜色
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="color"></param>
|
/// <param name="color"></param>
|
||||||
public virtual void SetBannerBackgroundColor(Color color)
|
public void SetBannerBackgroundColor(Color color)
|
||||||
{
|
{
|
||||||
_backColor = color;
|
_backColor = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBannerLoadedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
private void OnBannerLoadedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||||
{
|
{
|
||||||
_badsloadedNum++;
|
_badsLoadedNum++; // 记录加载次数
|
||||||
// --- fixed by Yufei 2024-5-29 为 don't report bads_loaded any more. ---
|
|
||||||
// Analytics.ADBadsLoaded(AdParams.Build(adUnitId, adInfo,
|
|
||||||
// duration: GetAdsLoadDuration(ref _badsloadStartTime), category: _badsCategory));
|
|
||||||
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
|
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
|
||||||
OnBadsLoaded();
|
OnBadsLoaded();
|
||||||
|
// BADSLoaded 事件已经不做上报处理了
|
||||||
|
// --- fixed by YuFei 2024-5-29 为 don't report bads_loaded any more. ---
|
||||||
|
// Analytics.ADBadsLoaded(AdParams.Build(adUnitId, adInfo,
|
||||||
|
// duration: GetAdsLoadDuration(ref _badsLoadStartTime), category: _badsCategory));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBannerFailedEvent(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
|
private void OnBannerFailedEvent(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
|
||||||
{
|
{
|
||||||
_badsLoadFailNum ++;
|
_badsLoadFailNum++; // 记录加载失败次数
|
||||||
// Analytics.ADBadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _badsloadStartTime), _badsCategory);
|
Analytics.TrackAdBadsFailed(BuildBadsFailedData(adUnitId, errorInfo));
|
||||||
Analytics.ADBadsFailed(AdParams.Build(adUnitId,
|
|
||||||
duration: GetActionDuration(_badsloadStartTime), category: _badsCategory,
|
|
||||||
errorCode: (int)errorInfo.Code,
|
|
||||||
waterfallName: errorInfo?.WaterfallInfo?.Name ?? ""));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBannerClickedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
private void OnBannerClickedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||||
{
|
{
|
||||||
// Analytics.ADBadsClick(adUnitId, _badsCategory);
|
// Analytics.ADBadsClick(adUnitId, _badsCategory);
|
||||||
Analytics.ADBadsClick(AdParams.Build(adUnitId, adInfo, _badsCategory));
|
Analytics.TrackAdBadsClick(BuildBadsClickData(adInfo, adUnitId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnBannerImpEvent(string adUnitId)
|
private void OnBannerImpEvent(string adUnitId)
|
||||||
{
|
{
|
||||||
// Analytics.ADBadsClick(adUnitId, _badsCategory);
|
// Analytics.ADBadsClick(adUnitId, _badsCategory);
|
||||||
Analytics.ADBadsImp(AdParams.Build(adUnitId, category: _badsCategory));
|
Analytics.TrackAdBadsImp(BuildBadsImpData(adUnitId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void OnBannerHideEvent()
|
private void OnBannerHideEvent()
|
||||||
{
|
{
|
||||||
Analytics.ADBadsHide(_badsloadedNum, _badsLoadFailNum);
|
Analytics.TrackAdBadsHide(_badsLoadedNum, _badsLoadFailNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -438,8 +417,7 @@ namespace Guru
|
||||||
{
|
{
|
||||||
if (_bannerVisible)
|
if (_bannerVisible)
|
||||||
{
|
{
|
||||||
// Banner 只有显示时才上报收益值
|
ReportAdsRevenue(AdParams.Build(adInfo, adUnitId));
|
||||||
AppendImpressionData(adInfo, eventName:Analytics.EventBadsPaid, itemCategory:_badsCategory);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -450,7 +428,7 @@ namespace Guru
|
||||||
private string _iadsCategory = "main";
|
private string _iadsCategory = "main";
|
||||||
private int _interstitialRetryAttempt;
|
private int _interstitialRetryAttempt;
|
||||||
private Action _interCloseAction;
|
private Action _interCloseAction;
|
||||||
protected bool _isIadsLoading = false;
|
private bool _isIadsLoading = false;
|
||||||
protected DateTime _iadsLoadStartTime;
|
protected DateTime _iadsLoadStartTime;
|
||||||
private DateTime _iadsDisplayStartTime;
|
private DateTime _iadsDisplayStartTime;
|
||||||
|
|
||||||
|
|
@ -468,15 +446,15 @@ namespace Guru
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void LoadMaxInterstitial()
|
private void LoadMaxInterstitial()
|
||||||
{
|
{
|
||||||
OnLoadIads();
|
OnLoadIads();
|
||||||
var id = GetInterstitialID();
|
var adUnitId = GetInterstitialID();
|
||||||
Analytics.ADIadsLoad(AdParams.Build(id));
|
Analytics.TrackAdIadsLoad(AdParams.Build(adUnitId:adUnitId).ToAdLoadedData());
|
||||||
MaxSdk.LoadInterstitial(id);
|
MaxSdk.LoadInterstitial(adUnitId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLoadIads()
|
private void OnLoadIads()
|
||||||
{
|
{
|
||||||
_iadsLoadStartTime = DateTime.UtcNow;
|
_iadsLoadStartTime = DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
|
|
@ -491,8 +469,7 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 显示插屏广告
|
/// 显示插屏广告
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rewardAction">广告奖励回调</param>
|
/// <param name="category">广告奖励回调</param>
|
||||||
/// <param name="failAction">广告失败回调</param>
|
|
||||||
/// <param name="dismissAction">广告界面关闭回调</param>
|
/// <param name="dismissAction">广告界面关闭回调</param>
|
||||||
public virtual void ShowInterstitialAD(string category, Action dismissAction = null)
|
public virtual void ShowInterstitialAD(string category, Action dismissAction = null)
|
||||||
{
|
{
|
||||||
|
|
@ -513,7 +490,6 @@ namespace Guru
|
||||||
MaxSdk.ShowInterstitial(GetInterstitialID());
|
MaxSdk.ShowInterstitial(GetInterstitialID());
|
||||||
|
|
||||||
_iadsDisplayStartTime = DateTime.UtcNow;
|
_iadsDisplayStartTime = DateTime.UtcNow;
|
||||||
// RequestInterstitialAD(); // 直接加载下一个广告
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnInterstitialLoadedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
protected virtual void OnInterstitialLoadedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||||
|
|
@ -522,12 +498,9 @@ namespace Guru
|
||||||
// Interstitial ad is ready to be shown. MaxSdk.IsInterstitialReady(interstitialAdUnitId) will now return 'true'
|
// Interstitial ad is ready to be shown. MaxSdk.IsInterstitialReady(interstitialAdUnitId) will now return 'true'
|
||||||
// Reset retry attempt
|
// Reset retry attempt
|
||||||
// Analytics.ADIadsLoaded(adUnitId, GetAdsLoadDuration(ref _iadsLoadStartTime), _iadsCategory);
|
// Analytics.ADIadsLoaded(adUnitId, GetAdsLoadDuration(ref _iadsLoadStartTime), _iadsCategory);
|
||||||
Analytics.ADIadsLoaded(AdParams.Build(adUnitId,
|
Analytics.TrackAdIadsLoaded(BuildIadsLoadedData(adInfo, adUnitId));
|
||||||
duration: GetActionDuration(_iadsLoadStartTime), category: _iadsCategory));
|
|
||||||
_interstitialRetryAttempt = 0;
|
_interstitialRetryAttempt = 0;
|
||||||
|
|
||||||
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
|
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
|
||||||
|
|
||||||
OnInterstitialLoaded?.Invoke();
|
OnInterstitialLoaded?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -542,11 +515,7 @@ namespace Guru
|
||||||
float retryDelay = GetRetryDelaySeconds(_interstitialRetryAttempt);
|
float retryDelay = GetRetryDelaySeconds(_interstitialRetryAttempt);
|
||||||
DelayCall(retryDelay, RequestInterstitialAD);
|
DelayCall(retryDelay, RequestInterstitialAD);
|
||||||
// Analytics.ADIadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _iadsLoadStartTime), _iadsCategory);
|
// Analytics.ADIadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _iadsLoadStartTime), _iadsCategory);
|
||||||
if(string.IsNullOrEmpty(_iadsCategory)) _iadsCategory = "not_set";
|
Analytics.TrackAdIadsFailed(BuildIadsFailedData(adUnitId, errorInfo));
|
||||||
Analytics.ADIadsFailed(AdParams.Build(adUnitId,
|
|
||||||
duration: GetActionDuration(_iadsLoadStartTime), category: _iadsCategory,
|
|
||||||
errorCode: (int)errorInfo.Code,
|
|
||||||
waterfallName: errorInfo?.WaterfallInfo?.Name ?? ""));
|
|
||||||
|
|
||||||
OnInterstitialFailed?.Invoke();
|
OnInterstitialFailed?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
@ -558,10 +527,7 @@ namespace Guru
|
||||||
this.LogError(
|
this.LogError(
|
||||||
$"InterstitialFailedToDisplayEvent AdLoadFailureInfo:{errorInfo.AdLoadFailureInfo}, Message: {errorInfo.Message}");
|
$"InterstitialFailedToDisplayEvent AdLoadFailureInfo:{errorInfo.AdLoadFailureInfo}, Message: {errorInfo.Message}");
|
||||||
// Analytics.ADIadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _iadsLoadStartTime), _iadsCategory);
|
// Analytics.ADIadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _iadsLoadStartTime), _iadsCategory);
|
||||||
Analytics.ADIadsFailed(AdParams.Build(adUnitId,
|
Analytics.TrackAdIadsFailed(BuildIadsFailedData(adUnitId, errorInfo));
|
||||||
duration: GetActionDuration(_iadsDisplayStartTime), category: _iadsCategory,
|
|
||||||
errorCode: (int)errorInfo.Code,
|
|
||||||
waterfallName: errorInfo.WaterfallInfo?.Name ?? ""));
|
|
||||||
DelayCall(2.0f, RequestInterstitialAD);
|
DelayCall(2.0f, RequestInterstitialAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -569,16 +535,13 @@ namespace Guru
|
||||||
protected virtual void OnInterstitialDisplayEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
protected virtual void OnInterstitialDisplayEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||||
{
|
{
|
||||||
// Analytics.ADIadsImp(adUnitId, _iadsCategory);
|
// Analytics.ADIadsImp(adUnitId, _iadsCategory);
|
||||||
AppendImpressionData(adInfo, eventName:Analytics.EventIadsImp, itemCategory:_iadsCategory);
|
Analytics.TrackAdIadsImp(BuildIadsImpData(adInfo, adUnitId));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnInterstitialClickEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
protected virtual void OnInterstitialClickEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||||
{
|
{
|
||||||
// Analytics.ADIadsClick(adUnitId, _iadsCategory);
|
// Analytics.ADIadsClick(adUnitId, _iadsCategory);
|
||||||
if(string.IsNullOrEmpty(_iadsCategory)) _iadsCategory = "not_set";
|
Analytics.TrackAdIadsClick(BuildIadsClickData(adInfo, adUnitId));
|
||||||
AppendImpressionData(adInfo,
|
|
||||||
eventName:Analytics.EventIadsClick,
|
|
||||||
itemCategory:_iadsCategory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close
|
// Close
|
||||||
|
|
@ -588,13 +551,7 @@ namespace Guru
|
||||||
_interCloseAction?.Invoke();
|
_interCloseAction?.Invoke();
|
||||||
OnInterstitialClosed?.Invoke();
|
OnInterstitialClosed?.Invoke();
|
||||||
// Analytics.ADIadsClose(adUnitId, _iadsCategory);
|
// Analytics.ADIadsClose(adUnitId, _iadsCategory);
|
||||||
Analytics.ADIadsClose(new Dictionary<string, object>()
|
Analytics.TrackAdIadsClose(BuildIadsCloseData(adInfo, adUnitId));
|
||||||
{
|
|
||||||
[Analytics.ParameterItemCategory] = _iadsCategory,
|
|
||||||
[Analytics.ParameterDuration] = GetActionDuration(_iadsDisplayStartTime),
|
|
||||||
});
|
|
||||||
|
|
||||||
_impressionDriver.CleanCreativeId(adInfo.CreativeIdentifier);
|
|
||||||
|
|
||||||
//延时加载下一个广告
|
//延时加载下一个广告
|
||||||
DelayCall(2.0f, RequestInterstitialAD);
|
DelayCall(2.0f, RequestInterstitialAD);
|
||||||
|
|
@ -602,7 +559,9 @@ namespace Guru
|
||||||
|
|
||||||
private void OnInterstitialPaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
private void OnInterstitialPaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||||
{
|
{
|
||||||
AppendImpressionData(adInfo, eventName:Analytics.EventIadsPaid, itemCategory: _iadsCategory);
|
var p = AdParams.Build(adInfo, adUnitId, category:_iadsCategory);
|
||||||
|
Analytics.TrackAdIadsPaid(p.ToAdPaidData());
|
||||||
|
ReportAdsRevenue(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -610,14 +569,14 @@ namespace Guru
|
||||||
|
|
||||||
#region Rewarded Ads
|
#region Rewarded Ads
|
||||||
|
|
||||||
private string _rewardCategory = "main";
|
private string _radsCategory = "main";
|
||||||
private int _rewardRetryAttempt;
|
private int _rewardRetryAttempt;
|
||||||
protected DateTime _radsLoadStartTime;
|
protected DateTime _radsLoadStartTime;
|
||||||
protected DateTime _radsShowStartTime;
|
private DateTime _radsDisplayStartTime;
|
||||||
private Action _rvRewardAction;
|
private Action _rvRewardAction;
|
||||||
private Action<string> _rvFailAction;
|
private Action<string> _rvFailAction;
|
||||||
private Action _rvDismissAction;
|
private Action _rvDismissAction;
|
||||||
protected bool _isRadsLoading = false;
|
private bool _isRadsLoading = false;
|
||||||
public bool IsRadsLoading => _isRadsLoading;
|
public bool IsRadsLoading => _isRadsLoading;
|
||||||
|
|
||||||
public virtual void RequestRewardedAD()
|
public virtual void RequestRewardedAD()
|
||||||
|
|
@ -634,17 +593,17 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认加载 MAX 广告逻辑
|
/// 默认加载 MAX 广告逻辑
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected void LoadMaxRewardAd(string unitId = "")
|
private void LoadMaxRewardAd()
|
||||||
{
|
{
|
||||||
if (IsRadsLoading) return;
|
if (IsRadsLoading) return;
|
||||||
|
|
||||||
OnLoadRads();
|
OnLoadRads();
|
||||||
var id = GetRewardedID();
|
var adUnitId = GetRewardedID();
|
||||||
Analytics.ADRadsLoad(AdParams.Build(id)); // 上报打点
|
Analytics.TrackAdRadsLoad(AdParams.Build(adUnitId:adUnitId).ToAdLoadData()); // 上报打点
|
||||||
MaxSdk.LoadRewardedAd(id);
|
MaxSdk.LoadRewardedAd(adUnitId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLoadRads()
|
private void OnLoadRads()
|
||||||
{
|
{
|
||||||
_radsLoadStartTime = DateTime.UtcNow;
|
_radsLoadStartTime = DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
|
|
@ -661,7 +620,8 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 显示激励视频广告
|
/// 显示激励视频广告
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rewardAction">广告奖励回调</param>
|
/// <param name="category">广告奖励回调</param>
|
||||||
|
/// <param name="rewardAction">广告失败回调</param>
|
||||||
/// <param name="failAction">广告失败回调</param>
|
/// <param name="failAction">广告失败回调</param>
|
||||||
/// <param name="dismissAction">广告界面关闭回调</param>
|
/// <param name="dismissAction">广告界面关闭回调</param>
|
||||||
public virtual void ShowRewardedAD(string category, Action rewardAction = null,
|
public virtual void ShowRewardedAD(string category, Action rewardAction = null,
|
||||||
|
|
@ -679,13 +639,13 @@ namespace Guru
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_rewardCategory = category;
|
_radsCategory = category;
|
||||||
_rvRewardAction = rewardAction;
|
_rvRewardAction = rewardAction;
|
||||||
_rvFailAction = failAction;
|
_rvFailAction = failAction;
|
||||||
_rvDismissAction = dismissAction;
|
_rvDismissAction = dismissAction;
|
||||||
MaxSdk.ShowRewardedAd(GetRewardedID());
|
MaxSdk.ShowRewardedAd(GetRewardedID());
|
||||||
|
|
||||||
_radsShowStartTime = DateTime.UtcNow;
|
_radsDisplayStartTime = DateTime.UtcNow;
|
||||||
|
|
||||||
// RequestRewardedAD();
|
// RequestRewardedAD();
|
||||||
}
|
}
|
||||||
|
|
@ -698,8 +658,7 @@ namespace Guru
|
||||||
// Reset retry attempt
|
// Reset retry attempt
|
||||||
// this.Log("OnRewardedAdLoadedEvent");
|
// this.Log("OnRewardedAdLoadedEvent");
|
||||||
// Analytics.ADRadsLoaded(adUnitId, GetAdsLoadDuration(ref _radsLoadStartTime), _rewardCategory);
|
// Analytics.ADRadsLoaded(adUnitId, GetAdsLoadDuration(ref _radsLoadStartTime), _rewardCategory);
|
||||||
Analytics.ADRadsLoaded(AdParams.Build(adUnitId,
|
Analytics.TrackAdRadsLoaded(BuildRadsLoadedData(adInfo, adUnitId));
|
||||||
duration: GetActionDuration(_radsLoadStartTime), category: _iadsCategory));
|
|
||||||
_rewardRetryAttempt = 0;
|
_rewardRetryAttempt = 0;
|
||||||
|
|
||||||
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
|
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
|
||||||
|
|
@ -716,10 +675,7 @@ namespace Guru
|
||||||
this.LogError(
|
this.LogError(
|
||||||
$"OnRewardedAdFailedEvent AdLoadFailureInfo:{errorInfo.AdLoadFailureInfo}, Message: {errorInfo.Message}");
|
$"OnRewardedAdFailedEvent AdLoadFailureInfo:{errorInfo.AdLoadFailureInfo}, Message: {errorInfo.Message}");
|
||||||
// Analytics.ADRadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _radsLoadStartTime), _rewardCategory);
|
// Analytics.ADRadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _radsLoadStartTime), _rewardCategory);
|
||||||
Analytics.ADRadsFailed(AdParams.Build(adUnitId,
|
Analytics.TrackAdRadsFailed(BuildRadsFailedData(adUnitId, errorInfo));
|
||||||
duration: GetActionDuration(_radsLoadStartTime), category: _rewardCategory,
|
|
||||||
errorCode: (int)errorInfo.Code,
|
|
||||||
waterfallName: errorInfo?.WaterfallInfo?.Name ?? ""));
|
|
||||||
_rewardRetryAttempt++;
|
_rewardRetryAttempt++;
|
||||||
float retryDelay = GetRetryDelaySeconds(_rewardRetryAttempt);
|
float retryDelay = GetRetryDelaySeconds(_rewardRetryAttempt);
|
||||||
DelayCall(retryDelay, RequestRewardedAD);
|
DelayCall(retryDelay, RequestRewardedAD);
|
||||||
|
|
@ -734,10 +690,7 @@ namespace Guru
|
||||||
this.LogError(
|
this.LogError(
|
||||||
$"OnRewardedAdFailedToDisplayEvent AdLoadFailureInfo:{errorInfo.AdLoadFailureInfo}, Message: {errorInfo.Message}");
|
$"OnRewardedAdFailedToDisplayEvent AdLoadFailureInfo:{errorInfo.AdLoadFailureInfo}, Message: {errorInfo.Message}");
|
||||||
// Analytics.ADRadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _radsLoadStartTime), _rewardCategory);
|
// Analytics.ADRadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _radsLoadStartTime), _rewardCategory);
|
||||||
Analytics.ADRadsFailed(AdParams.Build(adUnitId,
|
Analytics.TrackAdRadsFailed(BuildRadsFailedData(adUnitId, errorInfo));
|
||||||
duration: GetActionDuration(_radsShowStartTime), category: _rewardCategory,
|
|
||||||
errorCode: (int)errorInfo.Code,
|
|
||||||
waterfallName: errorInfo?.WaterfallInfo?.Name ?? ""));
|
|
||||||
_rvFailAction?.Invoke("OnRewardedAdFailedToDisplayEvent");
|
_rvFailAction?.Invoke("OnRewardedAdFailedToDisplayEvent");
|
||||||
DelayCall(2.0f, RequestRewardedAD);
|
DelayCall(2.0f, RequestRewardedAD);
|
||||||
|
|
||||||
|
|
@ -748,16 +701,17 @@ namespace Guru
|
||||||
{
|
{
|
||||||
this.Log("OnRewardedAdDisplayedEvent");
|
this.Log("OnRewardedAdDisplayedEvent");
|
||||||
// Analytics.ADRadsImp(adUnitId, _rewardCategory);
|
// Analytics.ADRadsImp(adUnitId, _rewardCategory);
|
||||||
AppendImpressionData(adInfo, eventName:Analytics.EventRadsImp, itemCategory: _rewardCategory);
|
Analytics.TrackAdRadsImp(BuildRadsImpData(adInfo, adUnitId));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnRewardedAdClickedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
protected virtual void OnRewardedAdClickedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||||
{
|
{
|
||||||
this.Log("OnRewardedAdClickedEvent");
|
this.Log("OnRewardedAdClickedEvent");
|
||||||
// Analytics.ADRadsClick(adUnitId, _rewardCategory);
|
// Analytics.ADRadsClick(adUnitId, _rewardCategory);
|
||||||
AppendImpressionData(adInfo, eventName:Analytics.EventRadsClick, itemCategory: _rewardCategory);
|
Analytics.TrackAdRadsClick(BuildRadsClickData(adInfo, adUnitId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// rads_close
|
// rads_close
|
||||||
protected virtual void OnRewardedAdDismissedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
protected virtual void OnRewardedAdDismissedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||||
{
|
{
|
||||||
|
|
@ -767,13 +721,7 @@ namespace Guru
|
||||||
OnRewardClosed?.Invoke();
|
OnRewardClosed?.Invoke();
|
||||||
|
|
||||||
// Analytics.ADRadsClose(adUnitId, _rewardCategory);
|
// Analytics.ADRadsClose(adUnitId, _rewardCategory);
|
||||||
Analytics.ADRadsClose(new Dictionary<string, object>()
|
Analytics.TrackAdRadsClose(BuildRadsCloseData(adInfo, adUnitId));
|
||||||
{
|
|
||||||
[Analytics.ParameterItemCategory] = _rewardCategory,
|
|
||||||
[Analytics.ParameterDuration] = GetActionDuration(_radsShowStartTime),
|
|
||||||
});
|
|
||||||
|
|
||||||
_impressionDriver.CleanCreativeId(adInfo.CreativeIdentifier);
|
|
||||||
|
|
||||||
//延时加载下一个广告
|
//延时加载下一个广告
|
||||||
DelayCall(2.0f, RequestRewardedAD);
|
DelayCall(2.0f, RequestRewardedAD);
|
||||||
|
|
@ -784,19 +732,18 @@ namespace Guru
|
||||||
MaxSdkBase.AdInfo adInfo)
|
MaxSdkBase.AdInfo adInfo)
|
||||||
{
|
{
|
||||||
this.Log("OnRewardedAdReceivedRewardEvent");
|
this.Log("OnRewardedAdReceivedRewardEvent");
|
||||||
// Analytics.ADRadsRewarded(adUnitId, _rewardCategory);
|
Analytics.TrackAdRadsRewarded(BuildRadsRewardedData(adInfo, adUnitId));
|
||||||
AppendImpressionData(adInfo, eventName:Analytics.EventRadsRewarded, itemCategory: _rewardCategory);
|
// Rewarded ad was displayed and user should receive the reward
|
||||||
_rvRewardAction?.Invoke();
|
_rvRewardAction?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
// rads_paid
|
// rads_paid
|
||||||
private void OnRewardedAdPaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
private void OnRewardedAdPaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||||
{
|
{
|
||||||
this.Log("OnRewardedAdReceivedRewardEvent");
|
var p = AdParams.Build(adInfo, adUnitId, category:_iadsCategory);
|
||||||
AppendImpressionData(adInfo, eventName:Analytics.EventRadsPaid, itemCategory: _rewardCategory);
|
Analytics.TrackAdRadsPaid(p.ToAdPaidData());
|
||||||
|
ReportAdsRevenue(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Ad Settings
|
#region Ad Settings
|
||||||
|
|
@ -822,8 +769,8 @@ namespace Guru
|
||||||
|
|
||||||
public void ShowMaxDebugPanel()
|
public void ShowMaxDebugPanel()
|
||||||
{
|
{
|
||||||
if (!IsInitialized) return;
|
|
||||||
#if !UNITY_EDITOR
|
#if !UNITY_EDITOR
|
||||||
|
if (!IsInitialized) return;
|
||||||
MaxSdk.ShowMediationDebugger();
|
MaxSdk.ShowMediationDebugger();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -839,86 +786,107 @@ namespace Guru
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ImpressionData
|
#region Build AdParams
|
||||||
|
|
||||||
const int MAX_BADS_CID_NUMBER = 6;
|
//---------- BADS Params --------------
|
||||||
private List<string> _badsCreativeIds = new List<string>(MAX_BADS_CID_NUMBER);
|
private Dictionary<string, object> BuildBadsImpData(string adUnitId)
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构建 Impression 数据
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="adInfo"></param>
|
|
||||||
/// <param name="reviewCreativeId"></param>
|
|
||||||
/// <param name="platform"></param>
|
|
||||||
/// <param name="eventName"></param>
|
|
||||||
/// <param name="itemCategory"></param>
|
|
||||||
/// <param name="duration"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private AdImpressionData CreateImpressionData(MaxSdkBase.AdInfo adInfo,
|
|
||||||
string reviewCreativeId = "", string platform = "",
|
|
||||||
string eventName = "", string itemCategory = "", int duration = 0)
|
|
||||||
{
|
{
|
||||||
var impression = AdImpressionDriver.Build(adInfo.Revenue, Analytics.USD, platform,
|
var p = AdParams.Build(adUnitId:adUnitId, category:_badsCategory);
|
||||||
adInfo.NetworkName,
|
return p.ToBadsImpData();
|
||||||
adInfo.AdFormat,
|
|
||||||
adInfo.AdUnitIdentifier,
|
|
||||||
adInfo.NetworkPlacement,
|
|
||||||
adInfo.CreativeIdentifier, reviewCreativeId,
|
|
||||||
eventName, itemCategory, duration);
|
|
||||||
|
|
||||||
return impression;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private Dictionary<string, object> BuildBadsFailedData(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
|
||||||
/// 添加一条ImpressionData 数据
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="adInfo"></param>
|
|
||||||
/// <param name="reviewCreativeId"></param>
|
|
||||||
/// <param name="platform"></param>
|
|
||||||
/// <param name="eventName"></param>
|
|
||||||
/// <param name="itemCategory"></param>
|
|
||||||
/// <param name="duration"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private void AppendImpressionData(MaxSdkBase.AdInfo adInfo, string reviewCreativeId = "", string platform = "", string eventName = "", string itemCategory = "", int duration = 0)
|
|
||||||
{
|
{
|
||||||
var data = CreateImpressionData(adInfo, reviewCreativeId, platform, eventName, itemCategory, duration);
|
int duration = GetActionDuration(_badsLoadStartTime);
|
||||||
_impressionDriver.Append(data);
|
int errorCode = (int)errorInfo.Code;
|
||||||
|
var p = AdParams.Build(adUnitId:adUnitId, errorCode:errorCode, duration:duration);
|
||||||
|
return p.ToAdFailedData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private Dictionary<string, object> BuildBadsClickData(MaxSdk.AdInfo adInfo, string adUnitId)
|
||||||
/// 获取 AdReviewCreativeId 后的回调
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="adUnitId"></param>
|
|
||||||
/// <param name="reviewCreativeId"></param>
|
|
||||||
/// <param name="adInfo"></param>
|
|
||||||
private void OnAdReviewCreativeIdGeneratedEvent(string adUnitId, string reviewCreativeId, MaxSdkBase.AdInfo adInfo)
|
|
||||||
{
|
{
|
||||||
Debug.Log($"{Tag} --- ReviewCreativeId:{reviewCreativeId} adUnitId: {adUnitId} Type:{adInfo?.AdFormat ?? "NULL"} CreativeId: {adInfo?.CreativeIdentifier ?? "NULL"} Revenue:{adInfo.Revenue}");
|
var p = AdParams.Build(adInfo, adUnitId, _badsCategory);
|
||||||
if (string.IsNullOrEmpty(adInfo.CreativeIdentifier))
|
return p.ToAdClickData();
|
||||||
{
|
|
||||||
Debug.LogError($"{Tag} --- Get ReviewCreativeId:{reviewCreativeId} but CreativeIdentifier is null");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_impressionDriver.SetReviewCreativeId(adInfo.CreativeIdentifier, reviewCreativeId); // 缓存 ReviewCreateId
|
|
||||||
|
|
||||||
if (adUnitId == GetBannerID() || adInfo.AdFormat.ToUpper().Contains("BANNER"))
|
//---------- IADS Params --------------
|
||||||
|
private Dictionary<string, object> BuildIadsLoadedData(MaxSdk.AdInfo adInfo, string adUnitId)
|
||||||
{
|
{
|
||||||
// 清理 BADS CID 缓存
|
int duration = GetActionDuration(_iadsLoadStartTime);
|
||||||
_badsCreativeIds.Add(adInfo.CreativeIdentifier);
|
var p = AdParams.Build(adInfo, adUnitId, duration:duration);
|
||||||
if (_badsCreativeIds.Count > MAX_BADS_CID_NUMBER)
|
return p.ToAdLoadedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> BuildIadsFailedData(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
|
||||||
{
|
{
|
||||||
var cid = _badsCreativeIds[0];
|
int duration = GetActionDuration(_iadsLoadStartTime);
|
||||||
_badsCreativeIds.Remove(cid);
|
int errorCode = (int)errorInfo.Code;
|
||||||
_impressionDriver.CleanCreativeId(cid);
|
var p = AdParams.Build(adUnitId:adUnitId, errorCode:errorCode, duration:duration);
|
||||||
|
return p.ToAdFailedData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> BuildIadsImpData(MaxSdk.AdInfo adInfo, string adUnitId)
|
||||||
|
{
|
||||||
|
var p = AdParams.Build(adInfo, adUnitId:adUnitId, category:_iadsCategory);
|
||||||
|
return p.ToAdImpData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> BuildIadsClickData(MaxSdk.AdInfo adInfo, string adUnitId)
|
||||||
|
{
|
||||||
|
var p = AdParams.Build(adInfo, adUnitId, category:_iadsCategory);
|
||||||
|
return p.ToAdClickData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> BuildIadsCloseData(MaxSdk.AdInfo adInfo, string adUnitId)
|
||||||
|
{
|
||||||
|
int duration = GetActionDuration(_iadsDisplayStartTime);
|
||||||
|
var p = AdParams.Build(adInfo, adUnitId, category:_iadsCategory, duration:duration);
|
||||||
|
return p.ToAdCloseData();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------- RADS Params --------------
|
||||||
|
private Dictionary<string, object> BuildRadsLoadedData(MaxSdk.AdInfo adInfo, string adUnitId)
|
||||||
|
{
|
||||||
|
int duration = GetActionDuration(_radsLoadStartTime);
|
||||||
|
var p = AdParams.Build(adInfo, adUnitId, duration:duration);
|
||||||
|
return p.ToAdLoadedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> BuildRadsFailedData(string adUnitId, MaxSdkBase.ErrorInfo errorInfo)
|
||||||
|
{
|
||||||
|
int duration = GetActionDuration(_radsLoadStartTime);
|
||||||
|
int errorCode = (int)errorInfo.Code;
|
||||||
|
var p = AdParams.Build(adUnitId:adUnitId, errorCode:errorCode, duration:duration);
|
||||||
|
return p.ToAdFailedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> BuildRadsImpData(MaxSdk.AdInfo adInfo, string adUnitId)
|
||||||
|
{
|
||||||
|
var p = AdParams.Build(adInfo, adUnitId:adUnitId, category:_radsCategory);
|
||||||
|
return p.ToAdLoadedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> BuildRadsClickData(MaxSdk.AdInfo adInfo, string adUnitId)
|
||||||
|
{
|
||||||
|
var p = AdParams.Build(adInfo, adUnitId, category:_radsCategory);
|
||||||
|
return p.ToAdClickData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> BuildRadsCloseData(MaxSdk.AdInfo adInfo, string adUnitId)
|
||||||
|
{
|
||||||
|
int duration = GetActionDuration(_radsDisplayStartTime);
|
||||||
|
var p = AdParams.Build(adInfo, adUnitId, category:_iadsCategory, duration:duration);
|
||||||
|
return p.ToAdCloseData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> BuildRadsRewardedData(MaxSdk.AdInfo adInfo, string adUnitId)
|
||||||
|
{
|
||||||
|
var p = AdParams.Build(adInfo, adUnitId, category:_iadsCategory);
|
||||||
|
return p.ToAdRewardedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -15,7 +15,7 @@ namespace Guru
|
||||||
|
|
||||||
|
|
||||||
public static AdsInitSpec Build(bool loadBanner = true, bool loadInterstitial = true, bool loadReward = true,
|
public static AdsInitSpec Build(bool loadBanner = true, bool loadInterstitial = true, bool loadReward = true,
|
||||||
bool autoLoad = true, bool isDebug = false, string bannerColorHex = "#00000000")
|
bool autoLoad = true, bool isDebug = false, string bannerColorHex = "#00000040")
|
||||||
{
|
{
|
||||||
return new AdsInitSpec
|
return new AdsInitSpec
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ namespace Guru
|
||||||
MaxSdk.SetBannerExtraParameter(MaxBADSSlotID, "adaptive_banner", "false");
|
MaxSdk.SetBannerExtraParameter(MaxBADSSlotID, "adaptive_banner", "false");
|
||||||
// Set background or background color for banners to be fully functional
|
// Set background or background color for banners to be fully functional
|
||||||
MaxSdk.SetBannerBackgroundColor(MaxBADSSlotID, _backColor);
|
MaxSdk.SetBannerBackgroundColor(MaxBADSSlotID, _backColor);
|
||||||
Analytics.ADBadsLoad(AdParams.Build(MaxBADSSlotID));
|
Analytics.TrackAdBadsLoad(AdParams.Build(adUnitId:MaxBADSSlotID).ToAdLoadData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBannerBackColor(string hex)
|
public void SetBannerBackColor(string hex)
|
||||||
|
|
@ -69,7 +69,7 @@ namespace Guru
|
||||||
public bool IsInterstitialRequestOver => true;
|
public bool IsInterstitialRequestOver => true;
|
||||||
public void LoadInterstitialAD()
|
public void LoadInterstitialAD()
|
||||||
{
|
{
|
||||||
Analytics.ADIadsLoad(AdParams.Build(MaxIADSSlotID)); // 上报打点
|
Analytics.TrackAdIadsLoad(AdParams.Build(adUnitId:MaxIADSSlotID).ToAdLoadData()); // 上报打点
|
||||||
MaxSdk.LoadInterstitial(MaxIADSSlotID);
|
MaxSdk.LoadInterstitial(MaxIADSSlotID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +80,7 @@ namespace Guru
|
||||||
public bool IsRewardRequestOver => true;
|
public bool IsRewardRequestOver => true;
|
||||||
public void LoadRewardAD()
|
public void LoadRewardAD()
|
||||||
{
|
{
|
||||||
Analytics.ADRadsLoad(AdParams.Build(MaxRADSSlotID)); // 上报打点
|
Analytics.TrackAdRadsLoad(AdParams.Build(adUnitId:MaxRADSSlotID).ToAdLoadData()); // 上报打点
|
||||||
MaxSdk.LoadRewardedAd(MaxRADSSlotID);
|
MaxSdk.LoadRewardedAd(MaxRADSSlotID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,185 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Guru.Ads
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// AdImpression 对象
|
|
||||||
/// </summary>
|
|
||||||
public class AdImpressionData
|
|
||||||
{
|
|
||||||
private const int MAX_VALUE_LENGTH = 96;
|
|
||||||
|
|
||||||
public double value;
|
|
||||||
public string currency = "USD";
|
|
||||||
public string ad_platform = "MAX";
|
|
||||||
public string ad_source;
|
|
||||||
public string ad_format;
|
|
||||||
public string ad_unit_name;
|
|
||||||
public string ad_placement;
|
|
||||||
public string ad_creative_id;
|
|
||||||
public string review_creative_id;
|
|
||||||
public string event_name;
|
|
||||||
public DateTime createTime;
|
|
||||||
public string item_category;
|
|
||||||
public int duration;
|
|
||||||
|
|
||||||
public AdImpressionData()
|
|
||||||
{
|
|
||||||
createTime = DateTime.UtcNow;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return $"[AdImpressionData] ad_unit_name:{ad_unit_name} value:{value} currency:{currency} ad_platform:{ad_platform} ad_source:{ad_source} ad_format:{ad_format} ad_placement:{ad_placement} ad_creative_id:{ad_creative_id} review_creative_id:{review_creative_id} event_name:{event_name} duration:{duration} item_category:{item_category}";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public bool EqualsCreativeId(string cid)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(cid)) return false;
|
|
||||||
return ad_creative_id.Equals(cid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool EqualsReviewCreativeId(string rcid)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(rcid)) return false;
|
|
||||||
return review_creative_id.Equals(rcid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置 CreativeId
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="creativeId"></param>
|
|
||||||
public void SetCreativeId(string creativeId)
|
|
||||||
{
|
|
||||||
ad_creative_id = FixStringLength(creativeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置 ReviewCreativeId
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="reviewCreativeId"></param>
|
|
||||||
public void SetReviewCreativeId(string reviewCreativeId)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(reviewCreativeId)) return;
|
|
||||||
review_creative_id = FixStringLength(reviewCreativeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 限制字符串长度为 96
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="source"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private string FixStringLength(string source)
|
|
||||||
{
|
|
||||||
return source.Length <= MAX_VALUE_LENGTH ? source : source.Substring(0, MAX_VALUE_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取自创建开始经过的秒数
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public double GetPassedSecond()
|
|
||||||
{
|
|
||||||
return (DateTime.UtcNow - createTime).TotalSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Dictionary<string, object> BuildEventData()
|
|
||||||
{
|
|
||||||
var data = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "value", value },
|
|
||||||
{ "currency", currency },
|
|
||||||
{ "ad_platform", ad_platform },
|
|
||||||
{ "ad_format", ad_format },
|
|
||||||
{ "ad_source", ad_source },
|
|
||||||
{ "ad_unit_name", ad_unit_name },
|
|
||||||
{ "ad_placement", ad_placement },
|
|
||||||
{ "ad_creative_id", ad_creative_id },
|
|
||||||
{ "review_creative_id", review_creative_id },
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Dictionary<string, object> BuildEventAdImpData()
|
|
||||||
{
|
|
||||||
var data = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "ad_platform", ad_platform },
|
|
||||||
{ "ad_source", ad_source },
|
|
||||||
{ "ad_unit_name", ad_unit_name },
|
|
||||||
{ "ad_placement", ad_placement },
|
|
||||||
{ "ad_creative_id", ad_creative_id },
|
|
||||||
{ "review_creative_id", review_creative_id },
|
|
||||||
{ "item_category", item_category}
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, object> BuildEventAdClickData()
|
|
||||||
{
|
|
||||||
var data = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "value", value },
|
|
||||||
{ "currency", currency },
|
|
||||||
{ "ad_platform", ad_platform },
|
|
||||||
{ "ad_source", ad_source },
|
|
||||||
{ "ad_unit_name", ad_unit_name },
|
|
||||||
{ "ad_placement", ad_placement },
|
|
||||||
{ "ad_creative_id", ad_creative_id },
|
|
||||||
{ "review_creative_id", review_creative_id },
|
|
||||||
{ "item_category", item_category}
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, object> BuildEventAdPaidData()
|
|
||||||
{
|
|
||||||
var data = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "value", value },
|
|
||||||
{ "currency", currency },
|
|
||||||
{ "ad_platform", ad_platform },
|
|
||||||
{ "ad_source", ad_source },
|
|
||||||
{ "ad_unit_name", ad_unit_name },
|
|
||||||
{ "ad_placement", ad_placement },
|
|
||||||
{ "ad_creative_id", ad_creative_id },
|
|
||||||
{ "review_creative_id", review_creative_id },
|
|
||||||
{ "item_category", item_category}
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, object> BuildEventAdRewardedData()
|
|
||||||
{
|
|
||||||
var data = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "value", value },
|
|
||||||
{ "currency", currency },
|
|
||||||
{ "ad_platform", ad_platform },
|
|
||||||
{ "ad_source", ad_source },
|
|
||||||
{ "ad_unit_name", ad_unit_name },
|
|
||||||
{ "ad_placement", ad_placement },
|
|
||||||
{ "ad_creative_id", ad_creative_id },
|
|
||||||
{ "review_creative_id", review_creative_id },
|
|
||||||
{ "item_category", item_category}
|
|
||||||
};
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 1aca2a4507b94dfe9f88040125708edb
|
|
||||||
timeCreated: 1721883318
|
|
||||||
|
|
@ -1,251 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
namespace Guru.Ads
|
|
||||||
{
|
|
||||||
// using System.Collections.Concurrent;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
|
|
||||||
public class AdImpressionDriver
|
|
||||||
{
|
|
||||||
private const string Tag = "[SDK][ADS]";
|
|
||||||
private const double NEED_FLUSH_TIME = 40.0; // 单条 Impression data 存在的最大间隔时间(秒)
|
|
||||||
private List<AdImpressionData> _impressionData; // 所有缓存待上报的 impression data
|
|
||||||
private Dictionary<string, string> _savedReviewCreativeIds;
|
|
||||||
|
|
||||||
private Action<AdImpressionData> _onReportAdsRevenue;
|
|
||||||
|
|
||||||
|
|
||||||
public static AdImpressionData Build(double value, string currency,
|
|
||||||
string adPlatform, string adSource, string adFormat,
|
|
||||||
string adUnitName, string adPlacement, string adCreativeID, string reviewCreativeID,
|
|
||||||
string eventName = "", string itemCategory = "", int duration = 0)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(adPlatform)) adPlatform = Analytics.AdMAX;
|
|
||||||
if (string.IsNullOrEmpty(itemCategory)) itemCategory = "not_set";
|
|
||||||
if (string.IsNullOrEmpty(eventName)) eventName = Analytics.EventAdImpression;
|
|
||||||
|
|
||||||
var data = new AdImpressionData()
|
|
||||||
{
|
|
||||||
value = value,
|
|
||||||
currency = currency,
|
|
||||||
ad_platform = adPlatform,
|
|
||||||
ad_source = adSource,
|
|
||||||
ad_format = adFormat,
|
|
||||||
ad_unit_name = adUnitName,
|
|
||||||
ad_placement = adPlacement,
|
|
||||||
ad_creative_id = adCreativeID,
|
|
||||||
event_name = eventName,
|
|
||||||
item_category = itemCategory,
|
|
||||||
duration = duration,
|
|
||||||
};
|
|
||||||
|
|
||||||
data.SetCreativeId(adCreativeID);
|
|
||||||
data.SetReviewCreativeId(reviewCreativeID);
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void Init(Action<AdImpressionData> onReportRevenue)
|
|
||||||
{
|
|
||||||
_impressionData = new List<AdImpressionData>(20);
|
|
||||||
_savedReviewCreativeIds = new Dictionary<string, string>(100);
|
|
||||||
|
|
||||||
_onReportAdsRevenue = onReportRevenue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public bool IsCreativeIdExists(string creativeId) => _savedReviewCreativeIds.ContainsKey(creativeId);
|
|
||||||
|
|
||||||
public void SetReviewCreativeId(string creativeId, string reviewCreativeId)
|
|
||||||
{
|
|
||||||
bool isCidExists = IsCreativeIdExists(creativeId);
|
|
||||||
_savedReviewCreativeIds[creativeId] = reviewCreativeId;
|
|
||||||
|
|
||||||
if (isCidExists && !string.IsNullOrEmpty(reviewCreativeId))
|
|
||||||
{
|
|
||||||
FlushAllImpressionData(creativeId, reviewCreativeId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 强制发送相关的数据
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="creativeId"></param>
|
|
||||||
public void CleanCreativeId(string creativeId)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(creativeId)) return;
|
|
||||||
|
|
||||||
if (IsCreativeIdExists(creativeId))
|
|
||||||
{
|
|
||||||
FlushAllImpressionData(creativeId, "", true);
|
|
||||||
}
|
|
||||||
RemoveCreativeId(creativeId); //清理对应的 createId
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private string GetReviewCreativeId(string creativeId)
|
|
||||||
{
|
|
||||||
if(string.IsNullOrEmpty(creativeId)) return "";
|
|
||||||
return _savedReviewCreativeIds.GetValueOrDefault(creativeId, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void RemoveCreativeId(string creativeId)
|
|
||||||
{
|
|
||||||
if (IsCreativeIdExists(creativeId))
|
|
||||||
{
|
|
||||||
_savedReviewCreativeIds.Remove(creativeId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 添加一条Impression数据
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="data"></param>
|
|
||||||
public void Append(AdImpressionData data)
|
|
||||||
{
|
|
||||||
if (CanFlushData(data))
|
|
||||||
{
|
|
||||||
// 立即触发数据
|
|
||||||
FlushImpressionData(data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!IsCreativeIdExists(data.ad_creative_id))
|
|
||||||
{
|
|
||||||
SetReviewCreativeId(data.ad_creative_id, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 缓存数据
|
|
||||||
PushImpressionData(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void PushImpressionData(AdImpressionData data)
|
|
||||||
{
|
|
||||||
_impressionData.Add(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private bool CanFlushData(AdImpressionData data)
|
|
||||||
{
|
|
||||||
// #1 如果超时, 强制上报
|
|
||||||
if (data.GetPassedSecond() > NEED_FLUSH_TIME) return true;
|
|
||||||
// #2 如果 cid 和 rcid 都赋值了 则上报
|
|
||||||
if (!string.IsNullOrEmpty(data.review_creative_id)) return true;
|
|
||||||
// #3 如果 rcid 为空, 但是可以找到,也上报
|
|
||||||
var rcid = GetReviewCreativeId(data.ad_creative_id);
|
|
||||||
if (!string.IsNullOrEmpty(rcid))
|
|
||||||
{
|
|
||||||
data.SetReviewCreativeId(rcid);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 触发所有相关的 cid 和 reviewCreateId
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="creativeId"></param>
|
|
||||||
/// <param name="reviewCreativeId"></param>
|
|
||||||
/// <param name="force">强制触发</param>
|
|
||||||
private void FlushAllImpressionData(string creativeId, string reviewCreativeId = "", bool force = false)
|
|
||||||
{
|
|
||||||
List<AdImpressionData> tmp = new List<AdImpressionData>(_impressionData.Count);
|
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(reviewCreativeId)) reviewCreativeId = GetReviewCreativeId(creativeId); //获取 reviewCreativeId
|
|
||||||
|
|
||||||
foreach(var data in _impressionData)
|
|
||||||
{
|
|
||||||
if (data.EqualsCreativeId(creativeId))
|
|
||||||
{
|
|
||||||
data.SetReviewCreativeId(reviewCreativeId);
|
|
||||||
if (CanFlushData(data) || force)
|
|
||||||
{
|
|
||||||
FlushImpressionData(data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmp.Add(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (CanFlushData(data))
|
|
||||||
{
|
|
||||||
FlushImpressionData(data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmp.Add(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_impressionData = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 输出一个 Impression 事件
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="data"></param>
|
|
||||||
private void FlushImpressionData(AdImpressionData data)
|
|
||||||
{
|
|
||||||
Debug.Log($"{Tag} --- FlushImpressionData: {data}");
|
|
||||||
switch (data.event_name)
|
|
||||||
{
|
|
||||||
case Analytics.EventBadsPaid:
|
|
||||||
// BADS 收入事件
|
|
||||||
// BADS 尚未统计 bads_paid 打点
|
|
||||||
_onReportAdsRevenue?.Invoke(data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Analytics.EventIadsImp:
|
|
||||||
Analytics.ADIadsImp(data.BuildEventAdImpData());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Analytics.EventIadsClick:
|
|
||||||
Analytics.ADIadsClick(data.BuildEventAdClickData());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Analytics.EventIadsPaid:
|
|
||||||
// IADS 收入事件
|
|
||||||
Analytics.ADIadsPaid(data.BuildEventAdPaidData());
|
|
||||||
_onReportAdsRevenue?.Invoke(data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Analytics.EventRadsImp:
|
|
||||||
Analytics.ADRadsImp(data.BuildEventAdImpData());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Analytics.EventRadsClick:
|
|
||||||
Analytics.ADRadsClick(data.BuildEventAdClickData());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Analytics.EventRadsRewarded:
|
|
||||||
Analytics.ADRadsRewarded(data.BuildEventAdRewardedData());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Analytics.EventRadsPaid:
|
|
||||||
// RADS 收入事件
|
|
||||||
Analytics.ADRadsPaid(data.BuildEventAdPaidData());
|
|
||||||
_onReportAdsRevenue?.Invoke(data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 7194cdd8ed1447508011264371e2c23d
|
|
||||||
timeCreated: 1722313472
|
|
||||||
|
|
@ -0,0 +1,254 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 广告打点上报参数
|
||||||
|
/// </summary>
|
||||||
|
public class AdParams
|
||||||
|
{
|
||||||
|
public double value;
|
||||||
|
public string currency;
|
||||||
|
public string category;
|
||||||
|
public string networkPlacement;
|
||||||
|
public string adPlatform;
|
||||||
|
public string adSource;
|
||||||
|
public string adFormat;
|
||||||
|
public string adUnitId;
|
||||||
|
public int errorCode = 0;
|
||||||
|
public int duration = 0;
|
||||||
|
public string creativeId;
|
||||||
|
public string reviewCreativeId;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造AD参数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="adInfo"></param>
|
||||||
|
/// <param name="adUnitId"></param>
|
||||||
|
/// <param name="category"></param>
|
||||||
|
/// <param name="duration"></param>
|
||||||
|
/// <param name="errorCode"></param>
|
||||||
|
/// <param name="reviewCreativeId"></param>
|
||||||
|
/// <param name="adPlatform"></param>
|
||||||
|
/// <param name="currency"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static AdParams Build(MaxSdkBase.AdInfo adInfo = null, string adUnitId = "", string category = "",
|
||||||
|
int duration = 0, int errorCode = 0, string reviewCreativeId = "", string adPlatform = "", string currency = "")
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(adUnitId) && adInfo != null) adUnitId = adInfo.AdUnitIdentifier;
|
||||||
|
var networkPlacement = "";
|
||||||
|
var creativeId = "";
|
||||||
|
var adSource = "";
|
||||||
|
var adFormart = "";
|
||||||
|
double value = 0;
|
||||||
|
string waterfallName = "";
|
||||||
|
|
||||||
|
if (adInfo != null)
|
||||||
|
{
|
||||||
|
value = adInfo.Revenue;
|
||||||
|
networkPlacement = adInfo.NetworkPlacement;
|
||||||
|
creativeId = adInfo.CreativeIdentifier;
|
||||||
|
adSource = adInfo.NetworkName;
|
||||||
|
adFormart = adInfo.AdFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(adPlatform)) adPlatform = Analytics.AdMAX;
|
||||||
|
if (string.IsNullOrEmpty(category)) category = "not_set";
|
||||||
|
if (string.IsNullOrEmpty(currency)) currency = Analytics.USD;
|
||||||
|
|
||||||
|
var p = new AdParams()
|
||||||
|
{
|
||||||
|
value = value,
|
||||||
|
currency = currency,
|
||||||
|
adUnitId = adUnitId,
|
||||||
|
adPlatform = adPlatform,
|
||||||
|
adSource = adSource,
|
||||||
|
adFormat = adFormart,
|
||||||
|
duration = duration,
|
||||||
|
networkPlacement = networkPlacement,
|
||||||
|
category = category,
|
||||||
|
errorCode = errorCode,
|
||||||
|
creativeId = creativeId,
|
||||||
|
reviewCreativeId = reviewCreativeId,
|
||||||
|
};
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转化为 AdImpression 事件数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Dictionary<string, object> ToAdImpressionData()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
[Analytics.ParameterValue] = value,
|
||||||
|
[Analytics.ParameterCurrency] = currency,
|
||||||
|
[Analytics.ParameterAdPlatform] = adPlatform,
|
||||||
|
[Analytics.ParameterAdSource] = adSource,
|
||||||
|
[Analytics.ParameterAdFormat] = adFormat,
|
||||||
|
[Analytics.ParameterAdUnitName] = adUnitId,
|
||||||
|
[Analytics.ParameterAdPlacement] = networkPlacement,
|
||||||
|
[Analytics.ParameterAdCreativeId] = creativeId,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(reviewCreativeId))
|
||||||
|
data[Analytics.ParameterReviewCreativeId] = reviewCreativeId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转化为 ads_imp 事件数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Dictionary<string, object> ToAdImpData()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
[Analytics.ParameterAdPlatform] = adPlatform,
|
||||||
|
[Analytics.ParameterAdSource] = adSource,
|
||||||
|
[Analytics.ParameterAdUnitName] = adUnitId,
|
||||||
|
[Analytics.ParameterAdPlacement] = networkPlacement,
|
||||||
|
[Analytics.ParameterAdCreativeId] = creativeId,
|
||||||
|
[Analytics.ParameterItemCategory] = category,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(reviewCreativeId))
|
||||||
|
data[Analytics.ParameterReviewCreativeId] = reviewCreativeId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转化为 ads_paid 通用事件数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Dictionary<string, object> ToAdPaidData()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
[Analytics.ParameterValue] = value,
|
||||||
|
[Analytics.ParameterCurrency] = currency,
|
||||||
|
[Analytics.ParameterAdPlatform] = adPlatform,
|
||||||
|
[Analytics.ParameterAdSource] = adSource,
|
||||||
|
[Analytics.ParameterAdUnitName] = adUnitId,
|
||||||
|
[Analytics.ParameterAdPlacement] = networkPlacement,
|
||||||
|
[Analytics.ParameterAdCreativeId] = creativeId,
|
||||||
|
[Analytics.ParameterItemCategory] = category,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(reviewCreativeId))
|
||||||
|
data[Analytics.ParameterReviewCreativeId] = reviewCreativeId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转化为 ads_paid 通用事件数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Dictionary<string, object> ToAdRewardedData()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
[Analytics.ParameterValue] = value,
|
||||||
|
[Analytics.ParameterCurrency] = currency,
|
||||||
|
[Analytics.ParameterAdPlatform] = adPlatform,
|
||||||
|
[Analytics.ParameterAdSource] = adSource,
|
||||||
|
[Analytics.ParameterAdUnitName] = adUnitId,
|
||||||
|
[Analytics.ParameterAdPlacement] = networkPlacement,
|
||||||
|
[Analytics.ParameterAdCreativeId] = creativeId,
|
||||||
|
[Analytics.ParameterItemCategory] = category,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(reviewCreativeId))
|
||||||
|
data[Analytics.ParameterReviewCreativeId] = reviewCreativeId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, object> ToAdClickData()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
[Analytics.ParameterValue] = value,
|
||||||
|
[Analytics.ParameterCurrency] = currency,
|
||||||
|
[Analytics.ParameterAdPlatform] = adPlatform,
|
||||||
|
[Analytics.ParameterAdSource] = adSource,
|
||||||
|
[Analytics.ParameterAdUnitName] = adUnitId,
|
||||||
|
[Analytics.ParameterAdPlacement] = networkPlacement,
|
||||||
|
[Analytics.ParameterAdCreativeId] = creativeId,
|
||||||
|
[Analytics.ParameterItemCategory] = category,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(reviewCreativeId))
|
||||||
|
data[Analytics.ParameterReviewCreativeId] = reviewCreativeId;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, object> ToAdCloseData()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
[Analytics.ParameterItemCategory] = category,
|
||||||
|
[Analytics.ParameterDuration] = duration,
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 广告失败事件数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Dictionary<string, object> ToAdFailedData()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
[Analytics.ParameterItemCategory] = category,
|
||||||
|
[Analytics.ParameterItemName] = adUnitId,
|
||||||
|
[Analytics.ParameterErrorCode] = errorCode,
|
||||||
|
[Analytics.ParameterDuration] = duration,
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 广告加载成功事件数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Dictionary<string, object> ToAdLoadData()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
[Analytics.ParameterItemCategory] = category,
|
||||||
|
[Analytics.ParameterItemName] = adUnitId,
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 广告加载成功事件数据
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Dictionary<string, object> ToAdLoadedData()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
[Analytics.ParameterItemCategory] = category,
|
||||||
|
[Analytics.ParameterItemName] = adUnitId,
|
||||||
|
[Analytics.ParameterDuration] = duration,
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Dictionary<string, object> ToBadsImpData()
|
||||||
|
{
|
||||||
|
var data = new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
[Analytics.ParameterItemCategory] = category,
|
||||||
|
[Analytics.ParameterItemName] = adUnitId,
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0341a8c153f04535a4193ce32086315a
|
||||||
|
timeCreated: 1722396384
|
||||||
|
|
@ -1,17 +1,13 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
public static partial class Analytics
|
public static partial class Analytics
|
||||||
{
|
{
|
||||||
#region 广告属性
|
#region 广告属性
|
||||||
|
|
||||||
//------ 广告额外的参数 --------
|
|
||||||
private static readonly string ParameterNetworkName = "network_name"; //NetworkName
|
|
||||||
private static readonly string ParameterNetworkPlacement = "network_placement"; //NetworkPlacement
|
|
||||||
private static readonly string ParameterWaterfall = "waterfall"; //Waterfall
|
|
||||||
|
|
||||||
//------ 默认值 -------
|
//------ 默认值 -------
|
||||||
public const string DefaultCategory = "not_set";
|
public const string DefaultCategory = "not_set";
|
||||||
public const string DefaultWaterfall = "unknown";
|
public const string DefaultWaterfall = "unknown";
|
||||||
|
|
@ -21,89 +17,32 @@ namespace Guru
|
||||||
|
|
||||||
#region Ads
|
#region Ads
|
||||||
|
|
||||||
private static Dictionary<string, object> BuildAdEventData(AdParams adParams, Dictionary<string, object> extra = null)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(adParams.category))
|
|
||||||
adParams.category = DefaultCategory;
|
|
||||||
if (string.IsNullOrEmpty(adParams.waterfallName))
|
|
||||||
adParams.waterfallName = DefaultWaterfall;
|
|
||||||
|
|
||||||
var data = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ ParameterItemCategory, adParams.category },
|
|
||||||
{ ParameterItemName, adParams.adUnitId },
|
|
||||||
};
|
|
||||||
|
|
||||||
if (adParams.duration > 0)
|
|
||||||
data[ParameterDuration] = adParams.duration;
|
|
||||||
|
|
||||||
if (adParams.errorCode != 0)
|
|
||||||
data[ParameterErrorCode] = adParams.errorCode;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(adParams.networkName))
|
|
||||||
data[ParameterNetworkName] = adParams.networkName;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(adParams.networkPlacement))
|
|
||||||
{
|
|
||||||
data[ParameterNetworkPlacement] = adParams.networkPlacement;
|
|
||||||
data[ParameterAdPlacement] = adParams.networkPlacement;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(adParams.waterfallName))
|
|
||||||
data[ParameterWaterfall] = adParams.waterfallName;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(adParams.creativeId))
|
|
||||||
data[ParameterAdCreativeId] = adParams.creativeId;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(adParams.reviewCreativeId))
|
|
||||||
data[ParameterReviewCreativeId] = adParams.reviewCreativeId;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(adParams.adPlatform))
|
|
||||||
data[ParameterAdPlatform] = adParams.adPlatform;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(adParams.adSource))
|
|
||||||
data[ParameterAdSource] = adParams.adSource;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(adParams.adFormat))
|
|
||||||
data[ParameterAdFormat] = adParams.adFormat;
|
|
||||||
|
|
||||||
if (extra != null && extra.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (var k in extra.Keys)
|
|
||||||
{
|
|
||||||
data[k] = extra[k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------- BANNER -------------------------
|
//---------------------- BANNER -------------------------
|
||||||
public static void ADBadsLoad(AdParams adParams)
|
public static void TrackAdBadsLoad(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventBadsLoad, BuildAdEventData(adParams));
|
TrackEvent(EventBadsLoad, data);
|
||||||
}
|
}
|
||||||
public static void ADBadsLoaded(AdParams adParams)
|
public static void TrackAdBadsLoaded(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventBadsLoaded, BuildAdEventData(adParams));
|
TrackEvent(EventBadsLoaded, data);
|
||||||
}
|
}
|
||||||
public static void ADBadsFailed(AdParams adParams)
|
public static void TrackAdBadsFailed(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventBadsFailed, BuildAdEventData(adParams));
|
TrackEvent(EventBadsFailed, data);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告点击
|
/// 广告点击
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADBadsClick(AdParams adParams)
|
public static void TrackAdBadsClick(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventBadsClick, BuildAdEventData(adParams));
|
TrackEvent(EventBadsClick, data);
|
||||||
}
|
}
|
||||||
public static void ADBadsImp(AdParams adParams)
|
public static void TrackAdBadsImp(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventBadsImp, BuildAdEventData(adParams));
|
TrackEvent(EventBadsImp, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ADBadsHide( int loadedTimes, int failTimes)
|
public static void TrackAdBadsHide( int loadedTimes, int failTimes)
|
||||||
{
|
{
|
||||||
var dict = new Dictionary<string, object>()
|
var dict = new Dictionary<string, object>()
|
||||||
{
|
{
|
||||||
|
|
@ -116,36 +55,31 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告拉取
|
/// 广告拉取
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADIadsLoad(AdParams adParams)
|
public static void TrackAdIadsLoad(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventIadsLoad, BuildAdEventData(adParams));
|
TrackEvent(EventIadsLoad, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告拉取成功
|
/// 广告拉取成功
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADIadsLoaded(AdParams adParams)
|
public static void TrackAdIadsLoaded(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventIadsLoaded, BuildAdEventData(adParams));
|
TrackEvent(EventIadsLoaded, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告拉取失败
|
/// 广告拉取失败
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADIadsFailed(AdParams adParams)
|
public static void TrackAdIadsFailed(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventIadsFailed, BuildAdEventData(adParams));
|
TrackEvent(EventIadsFailed, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告展示
|
/// 广告展示
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADIadsImp(AdParams adParams)
|
public static void TrackAdIadsImp(Dictionary<string, dynamic> data)
|
||||||
{
|
|
||||||
ADIadsImp(BuildAdEventData(adParams));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ADIadsImp(Dictionary<string, dynamic> data)
|
|
||||||
{
|
{
|
||||||
TrackEvent(EventIadsImp, data);
|
TrackEvent(EventIadsImp, data);
|
||||||
}
|
}
|
||||||
|
|
@ -153,12 +87,7 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告点击
|
/// 广告点击
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADIadsClick(AdParams adParams)
|
public static void TrackAdIadsClick(Dictionary<string, object> data)
|
||||||
{
|
|
||||||
ADIadsClick(BuildAdEventData(adParams));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ADIadsClick(Dictionary<string, object> data)
|
|
||||||
{
|
{
|
||||||
TrackEvent(EventIadsClick, data);
|
TrackEvent(EventIadsClick, data);
|
||||||
}
|
}
|
||||||
|
|
@ -166,12 +95,7 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户关闭广告
|
/// 用户关闭广告
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADIadsClose(AdParams adParams)
|
public static void TrackAdIadsClose(Dictionary<string, object> data)
|
||||||
{
|
|
||||||
ADIadsClose(BuildAdEventData(adParams));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ADIadsClose(Dictionary<string, object> data)
|
|
||||||
{
|
{
|
||||||
TrackEvent(EventIadsClose, data);
|
TrackEvent(EventIadsClose, data);
|
||||||
}
|
}
|
||||||
|
|
@ -180,7 +104,7 @@ namespace Guru
|
||||||
/// 插屏广告收到奖励
|
/// 插屏广告收到奖励
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
public static void ADIadsPaid(Dictionary<string, object> data)
|
public static void TrackAdIadsPaid(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventIadsPaid, data);
|
TrackEvent(EventIadsPaid, data);
|
||||||
}
|
}
|
||||||
|
|
@ -189,33 +113,28 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告开始加载
|
/// 广告开始加载
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADRadsLoad(AdParams adParams)
|
public static void TrackAdRadsLoad(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventRadsLoad, BuildAdEventData(adParams));
|
TrackEvent(EventRadsLoad, data);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告拉取成功
|
/// 广告拉取成功
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADRadsLoaded(AdParams adParams)
|
public static void TrackAdRadsLoaded(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventRadsLoaded, BuildAdEventData(adParams));
|
TrackEvent(EventRadsLoaded, data);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告拉取失败
|
/// 广告拉取失败
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADRadsFailed(AdParams adParams)
|
public static void TrackAdRadsFailed(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventRadsFailed, BuildAdEventData(adParams));
|
TrackEvent(EventRadsFailed, data);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告展示
|
/// 广告展示
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADRadsImp(AdParams adParams)
|
public static void TrackAdRadsImp(Dictionary<string, dynamic> data)
|
||||||
{
|
|
||||||
ADRadsImp(BuildAdEventData(adParams));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ADRadsImp(Dictionary<string, dynamic> data)
|
|
||||||
{
|
{
|
||||||
TrackEvent(EventRadsImp, data);
|
TrackEvent(EventRadsImp, data);
|
||||||
}
|
}
|
||||||
|
|
@ -225,19 +144,14 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告完成观看发奖励
|
/// 广告完成观看发奖励
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADRadsRewarded(AdParams adParams)
|
public static void TrackAdRadsRewarded(Dictionary<string, object> data)
|
||||||
{
|
|
||||||
ADRadsRewarded(BuildAdEventData(adParams));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ADRadsRewarded(Dictionary<string, object> data)
|
|
||||||
{
|
{
|
||||||
TrackEvent(EventRadsRewarded, data);
|
TrackEvent(EventRadsRewarded, data);
|
||||||
|
|
||||||
if (RadsRewardCount == 0)
|
if (RadsRewardCount == 0)
|
||||||
{
|
{
|
||||||
RadsRewardCount = 1;
|
RadsRewardCount = 1;
|
||||||
ADRadsFirstRewarded(data);
|
TrackAdRadsFirstRewarded(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -245,12 +159,11 @@ namespace Guru
|
||||||
/// 插屏广告收到奖励
|
/// 插屏广告收到奖励
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
public static void ADRadsPaid(Dictionary<string, object> data)
|
public static void TrackAdRadsPaid(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventRadsPaid, data);
|
TrackEvent(EventRadsPaid, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static int RadsRewardCount
|
private static int RadsRewardCount
|
||||||
{
|
{
|
||||||
get => PlayerPrefs.GetInt(nameof(RadsRewardCount), 0);
|
get => PlayerPrefs.GetInt(nameof(RadsRewardCount), 0);
|
||||||
|
|
@ -260,7 +173,7 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户首次完成观看
|
/// 用户首次完成观看
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADRadsFirstRewarded(Dictionary<string, object> data)
|
private static void TrackAdRadsFirstRewarded(Dictionary<string, object> data)
|
||||||
{
|
{
|
||||||
TrackEvent(EventFirstRadsRewarded, data);
|
TrackEvent(EventFirstRadsRewarded, data);
|
||||||
}
|
}
|
||||||
|
|
@ -268,12 +181,7 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 广告点击
|
/// 广告点击
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADRadsClick(AdParams adParams)
|
public static void TrackAdRadsClick(Dictionary<string, object> data)
|
||||||
{
|
|
||||||
ADRadsClick(BuildAdEventData(adParams));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ADRadsClick(Dictionary<string, object> data)
|
|
||||||
{
|
{
|
||||||
TrackEvent(EventRadsClick, data);
|
TrackEvent(EventRadsClick, data);
|
||||||
}
|
}
|
||||||
|
|
@ -281,12 +189,7 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户关闭广告
|
/// 用户关闭广告
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void ADRadsClose(AdParams adParams)
|
public static void TrackAdRadsClose(Dictionary<string, dynamic> data)
|
||||||
{
|
|
||||||
ADRadsClose( BuildAdEventData(adParams));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ADRadsClose(Dictionary<string, dynamic> data)
|
|
||||||
{
|
{
|
||||||
TrackEvent(EventRadsClose, data);
|
TrackEvent(EventRadsClose, data);
|
||||||
}
|
}
|
||||||
|
|
@ -329,78 +232,6 @@ namespace Guru
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 广告打点上报参数
|
|
||||||
/// </summary>
|
|
||||||
public class AdParams
|
|
||||||
{
|
|
||||||
public string category;
|
|
||||||
public string networkName;
|
|
||||||
public string networkPlacement;
|
|
||||||
public string adPlatform;
|
|
||||||
public string adSource;
|
|
||||||
public string adFormat;
|
|
||||||
public string waterfallName;
|
|
||||||
public string adUnitId;
|
|
||||||
public int errorCode = 0;
|
|
||||||
public int duration = 0;
|
|
||||||
public string creativeId;
|
|
||||||
public string reviewCreativeId;
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构造AD参数
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="adInfo"></param>
|
|
||||||
/// <param name="adUnitId"></param>
|
|
||||||
/// <param name="category"></param>
|
|
||||||
/// <param name="duration"></param>
|
|
||||||
/// <param name="errorCode"></param>
|
|
||||||
/// <param name="waterfallName"></param>
|
|
||||||
/// <param name="reviewCreativeId"></param>
|
|
||||||
/// <param name="adPlatform"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static AdParams Build(string adUnitId, MaxSdkBase.AdInfo adInfo = null, string category = "",
|
|
||||||
int duration = 0, int errorCode = 0, string waterfallName = "", string reviewCreativeId = "", string adPlatform = "")
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(adUnitId) && adInfo != null) adUnitId = adInfo.AdUnitIdentifier;
|
|
||||||
var networkName = "";
|
|
||||||
var networkPlacement = "";
|
|
||||||
var creativeId = "";
|
|
||||||
var adSource = "";
|
|
||||||
var adFormart = "";
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(adPlatform)) adPlatform = Analytics.AdMAX;
|
|
||||||
if (adInfo != null)
|
|
||||||
{
|
|
||||||
networkName = adInfo.NetworkName;
|
|
||||||
networkPlacement = adInfo.NetworkPlacement;
|
|
||||||
creativeId = adInfo.CreativeIdentifier;
|
|
||||||
adSource = adInfo.NetworkName;
|
|
||||||
adFormart = adInfo.AdFormat;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(waterfallName))
|
|
||||||
waterfallName = adInfo.WaterfallInfo?.Name ?? "";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var p = new AdParams()
|
|
||||||
{
|
|
||||||
adUnitId = adUnitId,
|
|
||||||
adPlatform = adPlatform,
|
|
||||||
adSource = adSource,
|
|
||||||
adFormat = adFormart,
|
|
||||||
duration = duration,
|
|
||||||
networkName = networkName,
|
|
||||||
networkPlacement = networkPlacement,
|
|
||||||
waterfallName = waterfallName,
|
|
||||||
category = category,
|
|
||||||
errorCode = errorCode,
|
|
||||||
creativeId = creativeId,
|
|
||||||
reviewCreativeId = reviewCreativeId,
|
|
||||||
};
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ namespace Guru
|
||||||
fail,
|
fail,
|
||||||
timeout,
|
timeout,
|
||||||
exit,
|
exit,
|
||||||
|
replay
|
||||||
}
|
}
|
||||||
|
|
||||||
//打点常量定义
|
//打点常量定义
|
||||||
|
|
@ -124,6 +125,8 @@ namespace Guru
|
||||||
public const string PropertyNoAds = "no_ads"; // 玩家是否去广告
|
public const string PropertyNoAds = "no_ads"; // 玩家是否去广告
|
||||||
public const string PropertyATTStatus = "att_status"; // ATT 状态
|
public const string PropertyATTStatus = "att_status"; // ATT 状态
|
||||||
public const string PropertyGDPR = "gdpr"; // GDPR状态
|
public const string PropertyGDPR = "gdpr"; // GDPR状态
|
||||||
|
public const string PropertySignUpMethod = "sign_up_method"; // 用户登录方式
|
||||||
|
|
||||||
|
|
||||||
// 经济相关
|
// 经济相关
|
||||||
public const string ParameterBalance = "balance"; // 用于余额
|
public const string ParameterBalance = "balance"; // 用于余额
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Firebase.Analytics;
|
using Firebase.Analytics;
|
||||||
using Firebase.Crashlytics;
|
using Firebase.Crashlytics;
|
||||||
using Firebase.Extensions;
|
using Firebase.Extensions;
|
||||||
|
|
@ -20,32 +19,22 @@ namespace Guru
|
||||||
private static bool _hasGotUid; // 已取得UID
|
private static bool _hasGotUid; // 已取得UID
|
||||||
private static DateTime _lastReportRateDate; //上次上报信息的日期
|
private static DateTime _lastReportRateDate; //上次上报信息的日期
|
||||||
private static double _reportSuccessInterval; // 上报频率
|
private static double _reportSuccessInterval; // 上报频率
|
||||||
|
#if UNITY_IOS
|
||||||
private const string VALUE_NOT_FOR_IOS = "not_support_for_ios";
|
private const string VALUE_NOT_FOR_IOS = "not_support_for_ios";
|
||||||
private const string VALUE_ONLY_FOR_IOS = "idfa_only_for_ios";
|
#endif
|
||||||
|
// private const string VALUE_ONLY_FOR_IOS = "idfa_only_for_ios";
|
||||||
public static bool IsDebug { get; set; } = false;
|
|
||||||
|
|
||||||
private static bool _isGuruAnalyticInitOnce = false;
|
private static bool _isGuruAnalyticInitOnce = false;
|
||||||
|
|
||||||
/// <summary>
|
public static void InitGuruAnalyticService(string firebaseId)
|
||||||
/// 初始化Guru自打点系统 (请优先于 Firebase 初始化调用)
|
|
||||||
/// </summary>
|
|
||||||
public static void InstallGuruAnalytics(bool isDebug = false, bool enableErrorLog = false)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
if (_isGuruAnalyticInitOnce) return;
|
if (_isGuruAnalyticInitOnce) return;
|
||||||
|
_isGuruAnalyticInitOnce = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
|
||||||
IsDebug = true;
|
|
||||||
#else
|
|
||||||
IsDebug = isDebug;
|
|
||||||
#endif
|
|
||||||
string appId = IPMConfig.IPM_X_APP_ID;
|
string appId = IPMConfig.IPM_X_APP_ID;
|
||||||
string deviceInfo = new DeviceInfoData().ToString();
|
string deviceInfo = new DeviceInfoData().ToString();
|
||||||
GuruAnalytics.Init(appId, deviceInfo, OnGuruAnalyticsInitComplete, IsDebug, enableErrorLog); // 初始化(带Header)
|
|
||||||
|
|
||||||
_hasGotFirebaseId = false;
|
_hasGotFirebaseId = false;
|
||||||
_hasGotAdId = false;
|
_hasGotAdId = false;
|
||||||
|
|
@ -55,9 +44,15 @@ namespace Guru
|
||||||
_lastReportRateDate = DateTime.Now;
|
_lastReportRateDate = DateTime.Now;
|
||||||
_reportSuccessInterval = 120; // 2分钟上报一次
|
_reportSuccessInterval = 120; // 2分钟上报一次
|
||||||
|
|
||||||
UpdateAllValues();
|
if(!string.IsNullOrEmpty(firebaseId))
|
||||||
|
GuruAnalytics.Instance.SetFirebaseId(firebaseId); // 在自打点初始化之前, 需要调用一下设置 FirebaseId
|
||||||
|
|
||||||
_isGuruAnalyticInitOnce = true;
|
GuruAnalytics.Init(appId, deviceInfo, () =>
|
||||||
|
{
|
||||||
|
SetUserProperty(GuruAnalyticsConfigManager.KEY_GURU_ANALYTICS_EXP, GuruAnalytics.Instance.ExperimentGroupId);
|
||||||
|
OnGuruAnalyticsInitComplete();
|
||||||
|
}, IsDebug); // Android 初始化
|
||||||
|
UpdateAllUserProperties();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -65,6 +60,7 @@ namespace Guru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region 各ID上报信息
|
#region 各ID上报信息
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -246,10 +242,12 @@ namespace Guru
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取全部ID
|
/// 上报中台打点的用户属性
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static void UpdateAllValues()
|
private static void UpdateAllUserProperties()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Debug.Log($"{TAG} --- UpdateAllValues");
|
||||||
SetUid();
|
SetUid();
|
||||||
SetDeviceId();
|
SetDeviceId();
|
||||||
SetAdjustId();
|
SetAdjustId();
|
||||||
|
|
@ -295,34 +293,22 @@ namespace Guru
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GuruAnalytics.Instance.SetUserProperty(key, value);
|
GuruAnalytics.Instance.SetUserProperty(key, value);
|
||||||
UpdateAllValues(); // 同步所有的ID
|
UpdateAllUserProperties(); // 同步所有的ID
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Crashlytics.LogException(e);
|
if (IsFirebaseReady)
|
||||||
|
{
|
||||||
|
Crashlytics.LogException(ex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogException(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 自定义事件打点
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="key"></param>
|
|
||||||
/// <param name="data"></param>
|
|
||||||
private static void TrackEventGuru(string key, Dictionary<string, dynamic> data = null, int priority = -1)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (data == null) data = new Dictionary<string, dynamic>();
|
|
||||||
GuruAnalytics.Instance.LogEvent(key, data, priority);
|
|
||||||
UpdateAllValues(); // 同步所有的ID
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Crashlytics.LogException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置太极02阀值
|
/// 设置太极02阀值
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -342,9 +328,16 @@ namespace Guru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
if (IsFirebaseReady)
|
||||||
{
|
{
|
||||||
Crashlytics.LogException(e);
|
Crashlytics.LogException(e);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ namespace Guru
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Facebook.Unity;
|
using Facebook.Unity;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Guru.Ads;
|
|
||||||
|
|
||||||
//游戏通用模版打点定义
|
//游戏通用模版打点定义
|
||||||
public static partial class Analytics
|
public static partial class Analytics
|
||||||
|
|
@ -417,6 +416,15 @@ namespace Guru
|
||||||
/// Google ARO买量点
|
/// Google ARO买量点
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="impressionData">广告收入数据</param>
|
/// <param name="impressionData">广告收入数据</param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <param name="currency"></param>
|
||||||
|
/// <param name="adPlatform"></param>
|
||||||
|
/// <param name="adUnitId"></param>
|
||||||
|
/// <param name="adPlacement"></param>
|
||||||
|
/// <param name="adSource"></param>
|
||||||
|
/// <param name="adFormat"></param>
|
||||||
|
/// <param name="creativeId"></param>
|
||||||
|
/// <param name="reviewCreativeId"></param>
|
||||||
/// <a href="https://docs.google.com/spreadsheets/d/1lFWLeOGJgq34QDBTfl6OpNh7MoI37ehGrhdbxlOrJgs/edit#gid=983654222"></a>
|
/// <a href="https://docs.google.com/spreadsheets/d/1lFWLeOGJgq34QDBTfl6OpNh7MoI37ehGrhdbxlOrJgs/edit#gid=983654222"></a>
|
||||||
/// <li>
|
/// <li>
|
||||||
/// value double eg:0.002
|
/// value double eg:0.002
|
||||||
|
|
@ -427,22 +435,29 @@ namespace Guru
|
||||||
/// ad_unit_name string 广告位名称
|
/// ad_unit_name string 广告位名称
|
||||||
/// ad_creative_id string 广告素材id
|
/// ad_creative_id string 广告素材id
|
||||||
/// </li>
|
/// </li>
|
||||||
public static void ADImpression(AdImpressionData impressionData)
|
public static void ADImpression(double value, string currency = "USD", string adPlatform = "",
|
||||||
|
string adSource = "", string adFormat = "", string adUnitId = "", string adPlacement= "",
|
||||||
|
string creativeId = "", string reviewCreativeId = "")
|
||||||
{
|
{
|
||||||
TrackEvent(EventAdImpression, new Dictionary<string, dynamic>()
|
ADImpression(new Dictionary<string, dynamic>()
|
||||||
{
|
{
|
||||||
[ParameterValue] = impressionData.value,
|
[ParameterValue] = value,
|
||||||
[ParameterCurrency] = impressionData.currency,
|
[ParameterCurrency] = currency,
|
||||||
[ParameterAdPlatform] = impressionData.ad_platform,
|
[ParameterAdPlatform] = adPlatform,
|
||||||
[ParameterAdSource] = impressionData.ad_source,
|
[ParameterAdSource] = adSource,
|
||||||
[ParameterAdFormat] = impressionData.ad_format,
|
[ParameterAdFormat] = adFormat,
|
||||||
[ParameterAdUnitName] = impressionData.ad_unit_name,
|
[ParameterAdUnitName] = adUnitId,
|
||||||
[ParameterAdPlacement] = impressionData.ad_placement,
|
[ParameterAdPlacement] = adPlacement,
|
||||||
[ParameterAdCreativeId] = impressionData.ad_creative_id,
|
[ParameterAdCreativeId] = creativeId,
|
||||||
[ParameterReviewCreativeId] = impressionData.review_creative_id,
|
[ParameterReviewCreativeId] = reviewCreativeId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ADImpression(Dictionary<string, object> data)
|
||||||
|
{
|
||||||
|
TrackEvent(EventAdImpression, data);
|
||||||
|
}
|
||||||
|
|
||||||
public static void TchAdAbnormalEvent(double value)
|
public static void TchAdAbnormalEvent(double value)
|
||||||
{
|
{
|
||||||
TrackEvent(EventTchAdRevAbnormal, new Dictionary<string, dynamic>()
|
TrackEvent(EventTchAdRevAbnormal, new Dictionary<string, dynamic>()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
|
|
||||||
using System.Threading;
|
using System.Collections;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
|
|
@ -39,35 +40,14 @@ namespace Guru
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EventSetting DefaultEventSetting => EventSetting.GetDefaultSetting();
|
private static EventSetting DefaultEventSetting => EventSetting.GetDefaultSetting();
|
||||||
|
|
||||||
private static bool _isInitOnce; //Analytics是否初始化完成
|
private static bool _isInitOnce; //Analytics是否初始化完成
|
||||||
public static bool EnableDebugAnalytics; //允许Debug包上报打点
|
public static bool EnableDebugAnalytics; //允许Debug包上报打点
|
||||||
|
|
||||||
public static bool IsDebugMode => PlatformUtil.IsDebug();
|
private static bool IsDebug => PlatformUtil.IsDebug();
|
||||||
private static bool IsFirebaseReady => FirebaseUtil.IsFirebaseInitialized;
|
private static bool IsFirebaseReady => FirebaseUtil.IsFirebaseInitialized;
|
||||||
|
|
||||||
private static bool IsReady
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
//Analytics没有初始化不上报打点
|
|
||||||
if (!_isInitOnce) return false;
|
|
||||||
|
|
||||||
//Firebase服务没有初始化完成不上报打点
|
|
||||||
if (!IsFirebaseReady) return false;
|
|
||||||
|
|
||||||
#if !UNITY_EDITOR
|
|
||||||
//开发环境打点不上报
|
|
||||||
if (IsDebugMode && !EnableDebugAnalytics)
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static AdjustEventDriver _adjustEventDriver;
|
private static AdjustEventDriver _adjustEventDriver;
|
||||||
private static FBEventDriver _fbEventDriver;
|
private static FBEventDriver _fbEventDriver;
|
||||||
private static FirebaseEventDriver _firebaseEventDriver;
|
private static FirebaseEventDriver _firebaseEventDriver;
|
||||||
|
|
@ -76,7 +56,10 @@ namespace Guru
|
||||||
|
|
||||||
#region 初始化
|
#region 初始化
|
||||||
|
|
||||||
public static void InitAnalytics()
|
/// <summary>
|
||||||
|
/// 初始化打点模块
|
||||||
|
/// </summary>
|
||||||
|
public static void Init()
|
||||||
{
|
{
|
||||||
if (_isInitOnce) return;
|
if (_isInitOnce) return;
|
||||||
_isInitOnce = true;
|
_isInitOnce = true;
|
||||||
|
|
@ -85,22 +68,21 @@ namespace Guru
|
||||||
_fbEventDriver = new FBEventDriver();
|
_fbEventDriver = new FBEventDriver();
|
||||||
_firebaseEventDriver = new FirebaseEventDriver();
|
_firebaseEventDriver = new FirebaseEventDriver();
|
||||||
_guruEventDriver = new GuruEventDriver();
|
_guruEventDriver = new GuruEventDriver();
|
||||||
|
|
||||||
// ------- 初始化自打点 ----------
|
|
||||||
InstallGuruAnalytics(IsDebug);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 外部拉起 Firebase 初始化完成回调
|
||||||
|
/// </summary>
|
||||||
public static void OnFirebaseInitCompleted()
|
public static void OnFirebaseInitCompleted()
|
||||||
{
|
{
|
||||||
Debug.Log($"[SDK] --- Analytics Init After FirebaseReady:{IsFirebaseReady}");
|
Debug.Log($"[SDK] --- Analytics Init After FirebaseReady:{IsFirebaseReady}");
|
||||||
|
|
||||||
// -------- 初始化 Crashlytics ----------
|
// --- 初始化 Crashlytics ---
|
||||||
CrashlyticsAgent.Init();
|
CrashlyticsAgent.Init();
|
||||||
FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
|
FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
|
||||||
FirebaseAnalytics.SetSessionTimeoutDuration(new TimeSpan(0, 30, 0));
|
FirebaseAnalytics.SetSessionTimeoutDuration(new TimeSpan(0, 30, 0));
|
||||||
SetUserProperty(FirebaseAnalytics.UserPropertySignUpMethod, "Google");
|
|
||||||
|
// --- 上报用户事件 ---
|
||||||
SetUserProperty(PropertyDeviceID, IPMConfig.IPM_DEVICE_ID);
|
SetUserProperty(PropertyDeviceID, IPMConfig.IPM_DEVICE_ID);
|
||||||
// SetUserProperty(PropertyFirstOpenTime, FirstOpenTime);
|
// SetUserProperty(PropertyFirstOpenTime, FirstOpenTime);
|
||||||
|
|
||||||
|
|
@ -118,7 +100,7 @@ namespace Guru
|
||||||
_adjustEventDriver.TriggerFlush();
|
_adjustEventDriver.TriggerFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnGuruAnalyticsInitComplete()
|
public static void OnGuruAnalyticsInitComplete()
|
||||||
{
|
{
|
||||||
_guruEventDriver.TriggerFlush();
|
_guruEventDriver.TriggerFlush();
|
||||||
}
|
}
|
||||||
|
|
@ -152,13 +134,13 @@ namespace Guru
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Firebase上报用户ID
|
/// Firebase上报用户ID
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userID">通过Auth认证地用户ID</param>
|
/// <param name="uid">通过Auth认证地用户ID</param>
|
||||||
public static void SetUserIDProperty(string userID)
|
public static void SetFirebaseUserId(string uid)
|
||||||
{
|
{
|
||||||
Log.I(TAG,$"SetUserIDProperty -> userID:{userID}");
|
if (!IsFirebaseReady) return;
|
||||||
if (!IsReady) return;
|
Log.I(TAG,$"SetUserIDProperty -> userID:{uid}");
|
||||||
|
FirebaseAnalytics.SetUserId(uid);
|
||||||
FirebaseAnalytics.SetUserId(userID);
|
Crashlytics.SetUserId(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -168,7 +150,7 @@ namespace Guru
|
||||||
{
|
{
|
||||||
if (!_isInitOnce)
|
if (!_isInitOnce)
|
||||||
{
|
{
|
||||||
throw new Exception($"[{TAG}][SDK] Analytics did not initialized, Call <Analytics.{nameof(InitAnalytics)}()> first!");
|
throw new Exception($"[{TAG}][SDK] Analytics did not initialized, Call <Analytics.{nameof(Init)}()> first!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDebug && !EnableDebugAnalytics)
|
if (IsDebug && !EnableDebugAnalytics)
|
||||||
|
|
@ -200,6 +182,25 @@ namespace Guru
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Firebase 上报用户属性
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="propertyName"></param>
|
||||||
|
/// <param name="propertyValue"></param>
|
||||||
|
private static void FirebaseSetUserProperty(string propertyName, string propertyValue)
|
||||||
|
{
|
||||||
|
if (IsFirebaseReady)
|
||||||
|
{
|
||||||
|
FirebaseAnalytics.SetUserProperty(propertyName, propertyValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log($"{TAG} --- Firebase not ready, call Firebase Init first!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 打点上报
|
#region 打点上报
|
||||||
|
|
@ -217,7 +218,7 @@ namespace Guru
|
||||||
{
|
{
|
||||||
if (!_isInitOnce)
|
if (!_isInitOnce)
|
||||||
{
|
{
|
||||||
throw new Exception($"[{TAG}][SDK] Analytics did not initialized, Call <Analytics.{nameof(InitAnalytics)}()> first!");
|
throw new Exception($"[{TAG}][SDK] Analytics did not initialized, Call <Analytics.{nameof(Init)}()> first!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsDebug && !EnableDebugAnalytics)
|
if (IsDebug && !EnableDebugAnalytics)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 005347f128bb460f9312778f93e39a9b
|
|
||||||
timeCreated: 1679986193
|
|
||||||
|
|
@ -1,206 +0,0 @@
|
||||||
|
|
||||||
namespace Guru
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using System.Globalization;
|
|
||||||
using UnityEngine;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 应用的全局标准属性
|
|
||||||
/// </summary>
|
|
||||||
public static class StandardProperties
|
|
||||||
{
|
|
||||||
|
|
||||||
#region 初始化
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 全局属性初始化 需要在应用启动时调用一次
|
|
||||||
/// </summary>
|
|
||||||
public static void Init()
|
|
||||||
{
|
|
||||||
// 首次安装初始化各种参数
|
|
||||||
if (IsFirstInstall)
|
|
||||||
{
|
|
||||||
string key = "";
|
|
||||||
FirstInstallDate = DateTime.Now;
|
|
||||||
|
|
||||||
key = nameof(SoundEffectEnabled);
|
|
||||||
if (!HasKey(key)) SoundEffectEnabled = true;
|
|
||||||
|
|
||||||
key = nameof(VibrationEnabled);
|
|
||||||
if (!HasKey(key)) VibrationEnabled = true;
|
|
||||||
|
|
||||||
key = nameof(FirstInstallVersion);
|
|
||||||
if (!HasKey(key)) FirstInstallVersion = FullVersion;
|
|
||||||
|
|
||||||
Save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsFirstInstall => HasKey(nameof(FirstInstallDate));
|
|
||||||
|
|
||||||
private static bool HasKey(string key) => PlayerPrefs.HasKey(key);
|
|
||||||
|
|
||||||
private static void Save() => PlayerPrefs.Save();
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 标准属性值
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// FirebaseId
|
|
||||||
/// </summary>
|
|
||||||
public static string FirebaseId
|
|
||||||
{
|
|
||||||
get => PlayerPrefs.GetString(nameof(FirebaseId), "");
|
|
||||||
set {
|
|
||||||
if (!string.IsNullOrEmpty(value))
|
|
||||||
{
|
|
||||||
PlayerPrefs.SetString(nameof(FirebaseId), value);
|
|
||||||
GuruAnalytics.Instance.SetFirebaseId(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adjust ADID
|
|
||||||
/// </summary>
|
|
||||||
public static string AdjustId
|
|
||||||
{
|
|
||||||
get => PlayerPrefs.GetString(nameof(AdjustId), "");
|
|
||||||
set {
|
|
||||||
if (!string.IsNullOrEmpty(value))
|
|
||||||
{
|
|
||||||
PlayerPrefs.SetString(nameof(AdjustId), value);
|
|
||||||
GuruAnalytics.Instance.SetAdjustId(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Google ADID
|
|
||||||
/// </summary>
|
|
||||||
public static string GoogleAdId
|
|
||||||
{
|
|
||||||
get => PlayerPrefs.GetString(nameof(GoogleAdId), "");
|
|
||||||
set {
|
|
||||||
if (!string.IsNullOrEmpty(value))
|
|
||||||
{
|
|
||||||
PlayerPrefs.SetString(nameof(GoogleAdId), value);
|
|
||||||
GuruAnalytics.Instance.SetAdId(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 免费金币资源
|
|
||||||
/// </summary>
|
|
||||||
public static int Coin
|
|
||||||
{
|
|
||||||
get => PlayerPrefs.GetInt(nameof(Coin), 0);
|
|
||||||
set => PlayerPrefs.SetInt(nameof(Coin), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 付费金币资源
|
|
||||||
/// </summary>
|
|
||||||
public static int IAPCoin
|
|
||||||
{
|
|
||||||
get => PlayerPrefs.GetInt(nameof(IAPCoin), 0);
|
|
||||||
set => PlayerPrefs.SetInt(nameof(IAPCoin), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户累计购买次数
|
|
||||||
/// </summary>
|
|
||||||
public static int PurchaseCount
|
|
||||||
{
|
|
||||||
get => PlayerPrefs.GetInt(nameof(PurchaseCount), 0);
|
|
||||||
set => PlayerPrefs.SetInt(nameof(PurchaseCount), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 首次安装日期
|
|
||||||
/// </summary>
|
|
||||||
public static DateTime FirstInstallDate
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var key = nameof(FirstInstallDate);
|
|
||||||
if (PlayerPrefs.HasKey(key))
|
|
||||||
{
|
|
||||||
var value = PlayerPrefs.GetString(key, "");
|
|
||||||
if (!string.IsNullOrEmpty(value)) return DateTime.Parse(value);
|
|
||||||
}
|
|
||||||
var now = DateTime.Now.ToUniversalTime();
|
|
||||||
FirstInstallDate = now;
|
|
||||||
return now;
|
|
||||||
}
|
|
||||||
|
|
||||||
set => PlayerPrefs.SetString(nameof(FirstInstallDate),
|
|
||||||
value.ToUniversalTime().ToString(CultureInfo.InvariantCulture));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 首次安装版本号
|
|
||||||
/// </summary>
|
|
||||||
public static string FirstInstallVersion
|
|
||||||
{
|
|
||||||
get => PlayerPrefs.GetString(nameof(FirstInstallVersion), "");
|
|
||||||
set => PlayerPrefs.SetString(nameof(FirstInstallVersion), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当前应用的版本
|
|
||||||
/// </summary>
|
|
||||||
public static string AppVersion => Application.version;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当前应用的版本Code
|
|
||||||
/// </summary>
|
|
||||||
public static string VersionCode
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var path = $"{Application.streamingAssetsPath}/{GuruCore.VERSION_CODE_FILE}";
|
|
||||||
if (File.Exists(path)) return File.ReadAllText(path);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 完整版本号
|
|
||||||
/// </summary>
|
|
||||||
public static string FullVersion
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var code = VersionCode;
|
|
||||||
if (string.IsNullOrEmpty(code)) code = "unknown";
|
|
||||||
return $"{AppVersion}-{code}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 音效开关
|
|
||||||
/// </summary>
|
|
||||||
public static bool SoundEffectEnabled
|
|
||||||
{
|
|
||||||
get => PlayerPrefs.GetInt(nameof(SoundEffectEnabled), 0) == 1;
|
|
||||||
set => PlayerPrefs.SetInt(nameof(SoundEffectEnabled), value? 1: 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 震动开关
|
|
||||||
/// </summary>
|
|
||||||
public static bool VibrationEnabled
|
|
||||||
{
|
|
||||||
get => PlayerPrefs.GetInt(nameof(VibrationEnabled), 0) == 1;
|
|
||||||
set => PlayerPrefs.SetInt(nameof(VibrationEnabled), value? 1: 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 2b2215a925974a3593ff2c6db2cf02fc
|
|
||||||
timeCreated: 1679986312
|
|
||||||
|
|
@ -27,7 +27,7 @@ namespace Guru
|
||||||
return ((MonoBehaviour)this).StartDelayed(delay, callback);
|
return ((MonoBehaviour)this).StartDelayed(delay, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Coroutine StartDelayed(int framesOfDelay, Action callback)
|
public Coroutine StartDelayedWithFrame(int framesOfDelay, Action callback)
|
||||||
{
|
{
|
||||||
return ((MonoBehaviour)this).StartDelayed(framesOfDelay, callback);
|
return ((MonoBehaviour)this).StartDelayed(framesOfDelay, callback);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@ using UnityEngine;
|
||||||
|
|
||||||
public static class NetworkUtil
|
public static class NetworkUtil
|
||||||
{
|
{
|
||||||
public static bool IsNetAvaliable => Application.internetReachability != NetworkReachability.NotReachable;
|
public static bool IsNetAvailable => Application.internetReachability != NetworkReachability.NotReachable;
|
||||||
}
|
}
|
||||||
|
|
@ -1,36 +1,62 @@
|
||||||
using Firebase.Auth;
|
|
||||||
using Firebase.Extensions;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
|
using Firebase.Auth;
|
||||||
|
using Firebase.Extensions;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
public static partial class FirebaseUtil
|
public static partial class FirebaseUtil
|
||||||
{
|
{
|
||||||
public static FirebaseUser CurrentUser => FirebaseAuth.DefaultInstance.CurrentUser;
|
private static FirebaseUser FirebaseUser => FirebaseAuth.DefaultInstance.CurrentUser;
|
||||||
|
|
||||||
private static readonly WaitForSeconds _wait = new WaitForSeconds(10);
|
private const float LOGIN_RETRY_MAX_TIME = 60; // 最大请求间隔时间
|
||||||
|
private const float LOGIN_RETRY_INTERVAL = 10; // 最大请求间隔时间
|
||||||
|
private static float _retryDelayTime = 10; // 登录重试时间
|
||||||
|
|
||||||
public static void AuthUser(Action onSuccessHandler = null)
|
/// <summary>
|
||||||
|
/// 登录 Firebase 用户
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="authToken"></param>
|
||||||
|
/// <param name="onLoginResult"></param>
|
||||||
|
/// <param name="autoRetry"></param>
|
||||||
|
private static void LoginFirebaseWithToken(Action<bool> onLoginResult = null, string authToken = "", bool autoRetry = true)
|
||||||
{
|
{
|
||||||
//FirebaseAuth获取用户验证并同步用户数据
|
// #1 Firebase 已获取用户
|
||||||
if (CurrentUser != null)
|
if (FirebaseUser != null)
|
||||||
{
|
{
|
||||||
Log.I(LOG_TAG, $"[Auth] user exists,UserId:{CurrentUser.UserId}");
|
Log.I(LOG_TAG, $"[Auth] user exists,UserId:{FirebaseUser.UserId}");
|
||||||
OnFirebaseAuthResult?.Invoke(true);
|
onLoginResult?.Invoke(true);
|
||||||
onSuccessHandler?.Invoke();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string authToken = IPMConfig.IPM_FIREBASE_TOKEN;
|
if (string.IsNullOrEmpty(authToken)) authToken = IPMConfig.IPM_FIREBASE_TOKEN;
|
||||||
Log.I(LOG_TAG, $"[Auth] Firebase Token:{authToken}");
|
Log.I(LOG_TAG, $"[Auth] Firebase Token:{authToken}");
|
||||||
if (string.IsNullOrEmpty(authToken) || !NetworkUtil.IsNetAvaliable)
|
|
||||||
|
if (!string.IsNullOrEmpty(authToken) && NetworkUtil.IsNetAvailable)
|
||||||
{
|
{
|
||||||
CoroutineHelper.Instance.StartDelayed(_wait, ()=> AuthUser(onSuccessHandler));
|
|
||||||
OnFirebaseAuthResult?.Invoke(false);
|
LoginFirebase(authToken, autoRetry, onLoginResult);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Token 为空 或 网络不可用
|
||||||
|
if (autoRetry)
|
||||||
|
{
|
||||||
|
// 继续重试
|
||||||
|
DelayCallFirebaseLogin(Mathf.Min(_retryDelayTime, LOGIN_RETRY_MAX_TIME), onLoginResult, authToken);
|
||||||
|
_retryDelayTime += LOGIN_RETRY_INTERVAL; // 最大重试间隔 60s
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 不再重试
|
||||||
|
onLoginResult?.Invoke(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LoginFirebase(string authToken = "", bool autoRetry = true, Action<bool> onLoginResult = null)
|
||||||
|
{
|
||||||
FirebaseAuth.DefaultInstance.SignInWithCustomTokenAsync(authToken)
|
FirebaseAuth.DefaultInstance.SignInWithCustomTokenAsync(authToken)
|
||||||
.ContinueWithOnMainThread(task =>
|
.ContinueWithOnMainThread(task =>
|
||||||
{
|
{
|
||||||
|
|
@ -38,21 +64,36 @@ namespace Guru
|
||||||
if (task.IsCanceled || task.IsFaulted)
|
if (task.IsCanceled || task.IsFaulted)
|
||||||
{
|
{
|
||||||
Log.E(LOG_TAG,"[Auth] SignInWithCustomTokenAsync encountered an error: " + task.Exception);
|
Log.E(LOG_TAG,"[Auth] SignInWithCustomTokenAsync encountered an error: " + task.Exception);
|
||||||
OnFirebaseAuthResult?.Invoke(false);
|
if (autoRetry)
|
||||||
CoroutineHelper.Instance.StartDelayed(_wait, () => AuthUser(onSuccessHandler));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// ----- User is NULL -----
|
|
||||||
if (CurrentUser == null)
|
|
||||||
{
|
{
|
||||||
OnFirebaseAuthResult?.Invoke(false);
|
DelayCallFirebaseLogin(_retryDelayTime, onLoginResult, authToken); // 自动重试
|
||||||
CoroutineHelper.Instance.StartDelayed(_wait, ()=> AuthUser(onSuccessHandler));
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
onLoginResult?.Invoke(false); // 不再重试
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// ----- Success -----
|
// ----- Check Result -----
|
||||||
OnFirebaseAuthResult?.Invoke(true); // 最后判定是成功的
|
bool success = FirebaseUser != null;
|
||||||
onSuccessHandler?.Invoke();
|
onLoginResult?.Invoke(success);
|
||||||
|
_retryDelayTime = LOGIN_RETRY_INTERVAL;
|
||||||
|
Analytics.SetUserProperty(Analytics.PropertySignUpMethod, "google"); // 上报用户登录属性
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO:P0 协程不应该用在此场景
|
||||||
|
/// <summary>
|
||||||
|
/// 延迟调用 Firebase 登录请求
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="delaySeconds"></param>
|
||||||
|
/// <param name="callback"></param>
|
||||||
|
/// <param name="token"></param>
|
||||||
|
private static void DelayCallFirebaseLogin(float delaySeconds, Action<bool> callback, string token = "")
|
||||||
|
{
|
||||||
|
var delay = new WaitForSeconds(delaySeconds);
|
||||||
|
CoroutineHelper.Instance.StartDelayed(delay, ()=> LoginFirebaseWithToken(callback, token));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,6 +5,8 @@ namespace Guru
|
||||||
{
|
{
|
||||||
public static partial class FirebaseUtil
|
public static partial class FirebaseUtil
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public static void InitCrashlytics()
|
public static void InitCrashlytics()
|
||||||
{
|
{
|
||||||
if(!string.IsNullOrEmpty(IPMConfig.IPM_UID))
|
if(!string.IsNullOrEmpty(IPMConfig.IPM_UID))
|
||||||
|
|
@ -17,6 +19,7 @@ namespace Guru
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SetUserID(string userID)
|
public static void SetUserID(string userID)
|
||||||
{
|
{
|
||||||
|
if (!IsFirebaseInitialized) return;
|
||||||
Crashlytics.SetUserId(userID);
|
Crashlytics.SetUserId(userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -26,6 +29,7 @@ namespace Guru
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void SetCustomData(string key, string value)
|
public static void SetCustomData(string key, string value)
|
||||||
{
|
{
|
||||||
|
if (!IsFirebaseInitialized) return;
|
||||||
Crashlytics.SetCustomKey(key, value);
|
Crashlytics.SetCustomKey(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,6 +38,7 @@ namespace Guru
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogMessage(string message)
|
public static void LogMessage(string message)
|
||||||
{
|
{
|
||||||
|
if (!IsFirebaseInitialized) return;
|
||||||
Crashlytics.Log(message);
|
Crashlytics.Log(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,6 +47,7 @@ namespace Guru
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LogException(Exception exception)
|
public static void LogException(Exception exception)
|
||||||
{
|
{
|
||||||
|
if (!IsFirebaseInitialized) return;
|
||||||
Crashlytics.LogException(exception);
|
Crashlytics.LogException(exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
|
|
||||||
|
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using Firebase.Messaging;
|
using Firebase.Messaging;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Guru
|
|
||||||
{
|
|
||||||
public static partial class FirebaseUtil
|
public static partial class FirebaseUtil
|
||||||
{
|
{
|
||||||
private static int _messageRetry = 5;
|
private static int _messageRetry = 5;
|
||||||
|
|
@ -17,7 +19,7 @@ namespace Guru
|
||||||
_isAutoFetchFcmToken = value;
|
_isAutoFetchFcmToken = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InitializeMessage()
|
private static void InitializeMessage()
|
||||||
{
|
{
|
||||||
if (_isAutoFetchFcmToken)
|
if (_isAutoFetchFcmToken)
|
||||||
{
|
{
|
||||||
|
|
@ -48,7 +50,7 @@ namespace Guru
|
||||||
|
|
||||||
if (task.IsFaulted || task.IsCanceled)
|
if (task.IsFaulted || task.IsCanceled)
|
||||||
{
|
{
|
||||||
CoroutineHelper.Instance.StartDelayed(_wait, GetFCMToken);
|
CoroutineHelper.Instance.StartDelayed(10, GetFCMToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -63,7 +65,7 @@ namespace Guru
|
||||||
|
|
||||||
private static void UploadDeviceInfo()
|
private static void UploadDeviceInfo()
|
||||||
{
|
{
|
||||||
if (!NetworkUtil.IsNetAvaliable)
|
if (!NetworkUtil.IsNetAvailable)
|
||||||
{
|
{
|
||||||
double retryDelay = Math.Pow(2, _messageRetry);
|
double retryDelay = Math.Pow(2, _messageRetry);
|
||||||
_messageRetry++;
|
_messageRetry++;
|
||||||
|
|
@ -84,14 +86,14 @@ namespace Guru
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token)
|
private static void OnTokenReceived(object sender, TokenReceivedEventArgs token)
|
||||||
{
|
{
|
||||||
#if UNITY_IOS
|
#if UNITY_IOS
|
||||||
DeviceUtil.SetiOSBadge();
|
DeviceUtil.SetiOSBadge();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e)
|
public static void OnMessageReceived(object sender, MessageReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
#if UNITY_IOS
|
#if UNITY_IOS
|
||||||
DeviceUtil.SetiOSBadge();
|
DeviceUtil.SetiOSBadge();
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ namespace Guru
|
||||||
|| _remoteConfigInstance.Info.LastFetchStatus != LastFetchStatus.Success)
|
|| _remoteConfigInstance.Info.LastFetchStatus != LastFetchStatus.Success)
|
||||||
{
|
{
|
||||||
Log.E(LOG_TAG, "Firebase RemoteConfig Fetch Failure");
|
Log.E(LOG_TAG, "Firebase RemoteConfig Fetch Failure");
|
||||||
CoroutineHelper.Instance.StartDelayed(_wait, FetchRemoteValue);
|
CoroutineHelper.Instance.StartDelayed(10, FetchRemoteValue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,160 +1,214 @@
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
using System;
|
using System;
|
||||||
using Firebase;
|
using Firebase;
|
||||||
using Firebase.Analytics;
|
using Firebase.Analytics;
|
||||||
using Firebase.Extensions;
|
using Firebase.Extensions;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Guru
|
|
||||||
{
|
|
||||||
public static partial class FirebaseUtil
|
public static partial class FirebaseUtil
|
||||||
{
|
{
|
||||||
private static readonly string LOG_TAG = "Firebase";
|
private static readonly string LOG_TAG = "Firebase";
|
||||||
private static bool _isReady = false;
|
private static bool _isReady = false;
|
||||||
public static bool IsReady => _isReady;
|
public static bool IsReady => _isReady && IsFirebaseInitialized;
|
||||||
|
|
||||||
public static DependencyStatus DependencyStatus = DependencyStatus.UnavailableOther;
|
private static DependencyStatus DependencyStatus = DependencyStatus.UnavailableOther;
|
||||||
public static bool IsFirebaseInitialized => DependencyStatus == DependencyStatus.Available;
|
public static bool IsFirebaseInitialized => DependencyStatus == DependencyStatus.Available;
|
||||||
public static Action<bool> onInitComplete;
|
|
||||||
|
|
||||||
public static Action<bool> OnFirebaseAuthResult;
|
private static Action<bool> _onCheckAndFixDepsHandler;
|
||||||
public static Action<bool> OnUserAuthResult;
|
private static Action<string> _onGetFirebaseIdHandler;
|
||||||
// TODO: 需要从 FirebaseUtils 内拿走
|
private static Action<bool> _onGetGuruUIDHandler;
|
||||||
public static Action<string> OnAdjustDeeplinkCallback = null;
|
private static Action<bool> _onFirebaseLoginResult;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
public static void InitFirebase(Action callback)
|
/// 初始化 Firebase
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="onDepsCheckResult">Firebase 自身解决依赖结果回调</param>
|
||||||
|
/// <param name="onGetFirebaseId">异步获取到 FirebaseId 回调</param>
|
||||||
|
/// <param name="onGetGuruUIDResult">Firebase 授权回调</param>
|
||||||
|
/// <param name="onFirebaseLoginResult"></param>
|
||||||
|
public static void Init(Action<bool> onDepsCheckResult, Action<string> onGetFirebaseId = null,
|
||||||
|
Action<bool> onGetGuruUIDResult = null, Action<bool> onFirebaseLoginResult = null)
|
||||||
{
|
{
|
||||||
_isReady = false;
|
_isReady = false;
|
||||||
// Analytics.InitAnalytics(); // 打点提前初始化
|
_onCheckAndFixDepsHandler = onDepsCheckResult;
|
||||||
|
_onGetFirebaseIdHandler = onGetFirebaseId;
|
||||||
|
_onGetGuruUIDHandler = onGetGuruUIDResult;
|
||||||
|
_onFirebaseLoginResult = onFirebaseLoginResult;
|
||||||
|
|
||||||
// Loom.StartUp(); // 确保主线程开启
|
// 初始化 Firebase 依赖
|
||||||
|
|
||||||
// 初始化 Fireabse 依赖
|
|
||||||
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
|
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
|
||||||
DependencyStatus = task.Result;
|
DependencyStatus = task.Result;
|
||||||
if (DependencyStatus == DependencyStatus.Available)
|
if (DependencyStatus == DependencyStatus.Available)
|
||||||
{
|
{
|
||||||
_isReady = true;
|
_isReady = true;
|
||||||
InitializeFirebaseComp();
|
OnFirebaseDepsCheckSuccess(); // Deps 处理通过
|
||||||
callback?.Invoke();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.E(LOG_TAG, "Could not resolve all Firebase dependencies: " + DependencyStatus);
|
Log.E(LOG_TAG, "Could not resolve all Firebase dependencies: " + DependencyStatus);
|
||||||
}
|
}
|
||||||
onInitComplete?.Invoke(_isReady);
|
_onCheckAndFixDepsHandler?.Invoke(_isReady);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
private static void InitializeFirebaseComp()
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deps 处理通过
|
||||||
|
/// 初始化各模块
|
||||||
|
/// </summary>
|
||||||
|
private static void OnFirebaseDepsCheckSuccess()
|
||||||
{
|
{
|
||||||
InitCrashlytics(); // 老项目沿用此逻辑
|
InitCrashlytics(); // 老项目沿用此逻辑
|
||||||
InitRemoteConfig(); // 老项目沿用此逻辑
|
InitRemoteConfig(); // 老项目沿用此逻辑
|
||||||
// TODO: 需要从 FirebaseUtils 内拿走
|
InitializeMessage(); // 初始化 Messaging 服务
|
||||||
InitAdjustService(); // 初始化 adjust 服务
|
GetFirebaseIdAsync(); // 开始获取 FirebaseId
|
||||||
|
|
||||||
if (IPMConfig.IPM_UID.IsNullOrEmpty())
|
StartVerifyTokenAndAuthAsync(); //开始验证授权和Token
|
||||||
{
|
|
||||||
Log.I(LOG_TAG, "没有存储UID时,从中台获取匿名认证授权");
|
|
||||||
//没有存储UID时,从中台获取匿名认证授权
|
|
||||||
new AuthUserRequest()
|
|
||||||
.SetRetryTimes(-1)
|
|
||||||
.SetSuccessCallBack(() =>
|
|
||||||
{
|
|
||||||
OnUserAuthResult?.Invoke(true);
|
|
||||||
AuthUser(InitializeMessage);
|
|
||||||
}).SetFailCallBack(() =>
|
|
||||||
{
|
|
||||||
OnUserAuthResult?.Invoke(false);
|
|
||||||
})
|
|
||||||
.Send();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InitializeMessage();
|
|
||||||
int currentTimeStamp = TimeUtil.GetCurrentTimeStampSecond();
|
|
||||||
if(currentTimeStamp - IPMConfig.IPM_TOKEN_TIME >= IPMConfig.TOKEN_VALID_TIME)
|
|
||||||
{
|
|
||||||
//中台Token失效,从中台重新获取Token
|
|
||||||
new RefreshTokenRequest().SetRetryTimes(-1).Send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(currentTimeStamp - IPMConfig.IPM_FIREBASE_TOKEN_TIME >= IPMConfig.FIREBASE_TOKEN_VALID_TIME)
|
#region FirebaseId
|
||||||
{
|
|
||||||
//中台firebaseToken失效,从中台重新获取firebaseToken
|
|
||||||
new RefreshFirebaseTokenRequest()
|
|
||||||
.SetRetryTimes(-1)
|
|
||||||
.SetSuccessCallBack(()=> AuthUser(InitializeMessage))
|
|
||||||
.Send();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AuthUser(InitializeMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region 启动 Adjust 服务
|
private static void GetFirebaseIdAsync()
|
||||||
|
|
||||||
// TODO: 需要从 FirebaseUtils 内拿走
|
|
||||||
/// <summary>
|
|
||||||
/// 启动 Adjust 服务
|
|
||||||
/// </summary>
|
|
||||||
private static void InitAdjustService()
|
|
||||||
{
|
{
|
||||||
|
// 异步获取 FirebaseID
|
||||||
FirebaseAnalytics.GetAnalyticsInstanceIdAsync()
|
FirebaseAnalytics.GetAnalyticsInstanceIdAsync()
|
||||||
.ContinueWithOnMainThread(task =>
|
.ContinueWithOnMainThread(task =>
|
||||||
{
|
{
|
||||||
|
string fid = task.Result;
|
||||||
if (task.IsCompleted && !string.IsNullOrEmpty(task.Result))
|
if (task.IsCompleted && !string.IsNullOrEmpty(fid))
|
||||||
{
|
{
|
||||||
// 保存本地ID备份
|
// 保存本地ID备份
|
||||||
string fid = task.Result;
|
|
||||||
IPMConfig.FIREBASE_ID = fid; // 保存FirebaseID
|
IPMConfig.FIREBASE_ID = fid; // 保存FirebaseID
|
||||||
|
Debug.Log($"[SDK] --- Get FirebaseID: {fid}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UnityEngine.Debug.LogError($"Fetch FirebaseID failed on start!");
|
Debug.LogError($"[SDK] --- Fetch FirebaseID failed on start!");
|
||||||
}
|
}
|
||||||
|
_onGetFirebaseIdHandler?.Invoke(fid);
|
||||||
// 启动 AdjustService
|
|
||||||
string appToken = GuruSettings.Instance.AdjustSetting?.GetAppToken() ?? "";
|
|
||||||
string fbAppId = GuruSettings.Instance.IPMSetting.FacebookAppId;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ID))
|
|
||||||
ReportAdjustId(IPMConfig.ADJUST_ID); // 二次启动后,若有值则立即上报属性
|
|
||||||
|
|
||||||
AdjustService.StartService(appToken, fbAppId, OnGetAdjustId, OnAdjustDeeplinkCallback);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnGetAdjustId(string adjustId)
|
#endregion
|
||||||
|
|
||||||
|
#region Token and Auth
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步验证所有 Token 有效期
|
||||||
|
/// </summary>
|
||||||
|
private static void StartVerifyTokenAndAuthAsync()
|
||||||
{
|
{
|
||||||
// 获取 ADID
|
if (string.IsNullOrEmpty(IPMConfig.IPM_UID))
|
||||||
if (string.IsNullOrEmpty(adjustId))
|
|
||||||
{
|
{
|
||||||
adjustId = "not_set";
|
Log.I(LOG_TAG, "没有存储UID时,从中台获取匿名认证授权");
|
||||||
|
// 没有存储UID时,从中台获取匿名认证授权
|
||||||
|
StartGuruLoginWithDeviceId(success =>
|
||||||
|
{
|
||||||
|
_onGetGuruUIDHandler?.Invoke(success);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
// 用户 UID 不为空
|
||||||
|
StartLoginWithFirebase();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IPMConfig.ADJUST_ID = adjustId;
|
// 检查中台 Token 是否过期
|
||||||
}
|
if (IsGuruTokenExpired())
|
||||||
ReportAdjustId(adjustId);
|
|
||||||
|
|
||||||
Analytics.OnAdjustInitComplete();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static void ReportAdjustId(string adjustId)
|
|
||||||
{
|
{
|
||||||
FirebaseAnalytics.SetUserProperty("adjust_id", adjustId); // 仅上报 Firebase 用户属性
|
RefreshGuruToken();
|
||||||
Debug.Log($"[SDK] --- Firebase + Adjust ID: {adjustId}");
|
}
|
||||||
|
|
||||||
|
// 检查中台 Firebase Token 是否过期
|
||||||
|
if (IsFirebaseTokenExpired())
|
||||||
|
{
|
||||||
|
RefreshFirebaseToken(StartLoginWithFirebase); // 重新获取 Firebase Token
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StartLoginWithFirebase();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用设备 ID 进行中台匿名认证
|
||||||
|
/// </summary>
|
||||||
|
private static void StartGuruLoginWithDeviceId(Action<bool> onLoginResult = null)
|
||||||
|
{
|
||||||
|
// 没有存储UID时,从中台获取匿名认证授权
|
||||||
|
var request = new AuthUserRequest()
|
||||||
|
.SetRetryTimes(-1) // 不成功的话会一直请求
|
||||||
|
.SetSuccessCallBack(() =>
|
||||||
|
{
|
||||||
|
onLoginResult?.Invoke(true);
|
||||||
|
}).SetFailCallBack(() =>
|
||||||
|
{
|
||||||
|
onLoginResult?.Invoke(false);
|
||||||
|
});
|
||||||
|
request.Send();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Firebase Token 是否过期
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static bool IsFirebaseTokenExpired()
|
||||||
|
{
|
||||||
|
int currentTimeStamp = TimeUtil.GetCurrentTimeStampSecond();
|
||||||
|
return currentTimeStamp - IPMConfig.IPM_TOKEN_TIME >= IPMConfig.TOKEN_VALID_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RefreshFirebaseToken(Action onFirebaseTokenRefreshed = null)
|
||||||
|
{
|
||||||
|
//中台firebaseToken失效,从中台重新获取firebaseToken
|
||||||
|
var request = new RefreshFirebaseTokenRequest()
|
||||||
|
.SetRetryTimes(-1)
|
||||||
|
.SetSuccessCallBack(()=> onFirebaseTokenRefreshed?.Invoke());
|
||||||
|
request.Send();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Guru Token 是否过期
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static bool IsGuruTokenExpired()
|
||||||
|
{
|
||||||
|
int currentTimeStamp = TimeUtil.GetCurrentTimeStampSecond();
|
||||||
|
return currentTimeStamp - IPMConfig.IPM_FIREBASE_TOKEN_TIME >= IPMConfig.FIREBASE_TOKEN_VALID_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RefreshGuruToken()
|
||||||
|
{
|
||||||
|
//中台Token失效,从中台重新获取Token
|
||||||
|
var request = new RefreshTokenRequest()
|
||||||
|
.SetRetryWaitSeconds(10)
|
||||||
|
.SetRetryTimes(-1); // 不成功的话会一直请求
|
||||||
|
request.Send();
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Firebase 用户登录
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始登录 Firebase
|
||||||
|
/// </summary>
|
||||||
|
private static void StartLoginWithFirebase()
|
||||||
|
{
|
||||||
|
LoginFirebaseWithToken(OnFirebaseLoginComplete, IPMConfig.IPM_FIREBASE_TOKEN); // 成功后进行 Firebase 认证
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Firebase 认证用户完成
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="success"></param>
|
||||||
|
private static void OnFirebaseLoginComplete(bool success)
|
||||||
|
{
|
||||||
|
_onFirebaseLoginResult?.Invoke(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -44,8 +44,7 @@ namespace Guru
|
||||||
this.Log(response);
|
this.Log(response);
|
||||||
this.Log(responseData.data.ToString());
|
this.Log(responseData.data.ToString());
|
||||||
|
|
||||||
Analytics.SetUserIDProperty(responseData.data.uid);
|
Analytics.SetFirebaseUserId(responseData.data.uid);
|
||||||
Crashlytics.SetUserId(responseData.data.uid);
|
|
||||||
|
|
||||||
IPMConfig.IPM_UID = responseData.data.uid;
|
IPMConfig.IPM_UID = responseData.data.uid;
|
||||||
IPMConfig.IPM_UID_INT = responseData.data.uidInt;
|
IPMConfig.IPM_UID_INT = responseData.data.uidInt;
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,7 @@ namespace Guru
|
||||||
this.Log(responseData.data.ToString());
|
this.Log(responseData.data.ToString());
|
||||||
IPMConfig.IPM_TOKEN = responseData.data.token;
|
IPMConfig.IPM_TOKEN = responseData.data.token;
|
||||||
IPMConfig.IPM_TOKEN_TIME = TimeUtil.GetCurrentTimeStampSecond();
|
IPMConfig.IPM_TOKEN_TIME = TimeUtil.GetCurrentTimeStampSecond();
|
||||||
PlayerPrefs.SetString("IPM_TOKEN", responseData.data.token);
|
this.Log($"[SDK] --- RefreshTokenRequest Success: {responseData.data.token}");
|
||||||
this.Log("@@@ Send OK!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ namespace Guru
|
||||||
protected abstract UnityWebRequest CreateRequest();
|
protected abstract UnityWebRequest CreateRequest();
|
||||||
protected abstract void RequestSuccessCallBack(string response);
|
protected abstract void RequestSuccessCallBack(string response);
|
||||||
|
|
||||||
private readonly WaitForSeconds _waitTime = new WaitForSeconds(5);
|
private WaitForSeconds _waitTime = new WaitForSeconds(5);
|
||||||
|
|
||||||
private int _retryTimes = 3;
|
private int _retryTimes = 3;
|
||||||
private int _timeOut = 90;
|
private int _timeOut = 90;
|
||||||
|
|
@ -28,6 +28,12 @@ namespace Guru
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RequestBase SetRetryWaitSeconds(int waitSeconds)
|
||||||
|
{
|
||||||
|
_waitTime = new WaitForSeconds(waitSeconds);;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public RequestBase SetTimeOut(int timeOut)
|
public RequestBase SetTimeOut(int timeOut)
|
||||||
{
|
{
|
||||||
_timeOut = timeOut;
|
_timeOut = timeOut;
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,10 @@
|
||||||
|
|
||||||
namespace Guru
|
namespace Guru
|
||||||
{
|
{
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Consts=AdStatusConsts;
|
using Const=AdStatusConsts;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public partial class AdStatusPresenter
|
public partial class AdStatusPresenter
|
||||||
{
|
{
|
||||||
|
|
@ -104,12 +101,10 @@ namespace Guru
|
||||||
private StringBuilder _infoBuff;
|
private StringBuilder _infoBuff;
|
||||||
private string CreateMonitorInfo()
|
private string CreateMonitorInfo()
|
||||||
{
|
{
|
||||||
string msg = "";
|
string msg;
|
||||||
bool loaded = false;
|
|
||||||
|
|
||||||
if (ADService.Instance == null || !ADService.Instance.IsInitialized)
|
if (ADService.Instance == null || !ADService.Instance.IsInitialized)
|
||||||
{
|
{
|
||||||
msg = ColoredText("AdService not initialized...", Consts.ColorRed);
|
msg = ColoredText("AdService not initialized...", Const.ColorRed);
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,7 +113,7 @@ namespace Guru
|
||||||
|
|
||||||
if (_curBadsInfo == null)
|
if (_curBadsInfo == null)
|
||||||
{
|
{
|
||||||
msg = $"BADS: {ColoredText("not ready", Consts.ColorRed)}\n";
|
msg = $"BADS: {ColoredText("not ready", Const.ColorRed)}\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -126,25 +121,25 @@ namespace Guru
|
||||||
switch (_curBadsInfo.status)
|
switch (_curBadsInfo.status)
|
||||||
{
|
{
|
||||||
case AdStatusType.Loaded:
|
case AdStatusType.Loaded:
|
||||||
msg = $"BADS: {ColoredText("loaded", Consts.ColorGreen)}\n\tnetwork: {_curBadsInfo.network}\n\twaterfall: {_curBadsInfo.waterfall}\n";
|
msg = $"BADS: {ColoredText("loaded", Const.ColorGreen)}\n\tnetwork: {_curBadsInfo.network}\n\twaterfall: {_curBadsInfo.waterfall}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.LoadFailed:
|
case AdStatusType.LoadFailed:
|
||||||
msg = $"BADS: {ColoredText("loading failed", Consts.ColorRed)}\n\tmessage: {_curBadsInfo.info}\n";
|
msg = $"BADS: {ColoredText("loading failed", Const.ColorRed)}\n\tmessage: {_curBadsInfo.info}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.DisplayFailed:
|
case AdStatusType.DisplayFailed:
|
||||||
msg = $"BADS: {ColoredText("display failed", Consts.ColorRed)}\n\tmessage: {_curBadsInfo.info}\n";
|
msg = $"BADS: {ColoredText("display failed", Const.ColorRed)}\n\tmessage: {_curBadsInfo.info}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.Loading:
|
case AdStatusType.Loading:
|
||||||
msg = $"BADS: {ColoredText("loading...", Consts.ColorYellow)}\n\tformat: {_curBadsInfo.format}\n";
|
msg = $"BADS: {ColoredText("loading...", Const.ColorYellow)}\n\tformat: {_curBadsInfo.format}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.Paid:
|
case AdStatusType.Paid:
|
||||||
msg = $"BADS: {ColoredText("display", Consts.ColorGreen)}\n\tnetwork: {_curBadsInfo.network}\n\trevenue: {_curBadsInfo.revenue}\n";
|
msg = $"BADS: {ColoredText("display", Const.ColorGreen)}\n\tnetwork: {_curBadsInfo.network}\n\trevenue: {_curBadsInfo.revenue}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.NotReady:
|
case AdStatusType.NotReady:
|
||||||
msg = $"BADS: {ColoredText("not ready", Consts.ColorGray)}\n\t{ColoredText("---", Consts.ColorGray)}\n";
|
msg = $"BADS: {ColoredText("not ready", Const.ColorGray)}\n\t{ColoredText("---", Const.ColorGray)}\n";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
msg = $"BADS: {ColoredText("other", Consts.ColorGray)}\n\tstatus: {ColoredText($"{_curBadsInfo.status}", Consts.ColorYellow)}\n";
|
msg = $"BADS: {ColoredText("other", Const.ColorGray)}\n\tstatus: {ColoredText($"{_curBadsInfo.status}", Const.ColorYellow)}\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,32 +148,32 @@ namespace Guru
|
||||||
|
|
||||||
if (_curIadsInfo == null)
|
if (_curIadsInfo == null)
|
||||||
{
|
{
|
||||||
msg = $"IADS: {ColoredText("not ready", Consts.ColorRed)}\n";
|
msg = $"IADS: {ColoredText("not ready", Const.ColorRed)}\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (_curIadsInfo.status)
|
switch (_curIadsInfo.status)
|
||||||
{
|
{
|
||||||
case AdStatusType.Loaded:
|
case AdStatusType.Loaded:
|
||||||
msg = $"IADS: {ColoredText("loaded", Consts.ColorGreen)}\n\tnetwork: {_curIadsInfo.network}\n\twaterfall: {_curIadsInfo.waterfall}\n";
|
msg = $"IADS: {ColoredText("loaded", Const.ColorGreen)}\n\tnetwork: {_curIadsInfo.network}\n\twaterfall: {_curIadsInfo.waterfall}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.LoadFailed:
|
case AdStatusType.LoadFailed:
|
||||||
msg = $"IADS: {ColoredText("loading failed", Consts.ColorRed)}\n\tmessage: {_curIadsInfo.info}\n";
|
msg = $"IADS: {ColoredText("loading failed", Const.ColorRed)}\n\tmessage: {_curIadsInfo.info}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.DisplayFailed:
|
case AdStatusType.DisplayFailed:
|
||||||
msg = $"IADS: {ColoredText("display failed", Consts.ColorRed)}\n\tmessage: {_curIadsInfo.info}\n";
|
msg = $"IADS: {ColoredText("display failed", Const.ColorRed)}\n\tmessage: {_curIadsInfo.info}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.Loading:
|
case AdStatusType.Loading:
|
||||||
msg = $"IADS: {ColoredText("loading...", Consts.ColorYellow)}\n\tformat: {_curIadsInfo.format}\n";
|
msg = $"IADS: {ColoredText("loading...", Const.ColorYellow)}\n\tformat: {_curIadsInfo.format}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.Paid:
|
case AdStatusType.Paid:
|
||||||
msg = $"IADS: {ColoredText("get revenue", Consts.ColorGreen)}\n\trevenue: {_curIadsInfo.revenue}\n";
|
msg = $"IADS: {ColoredText("get revenue", Const.ColorGreen)}\n\trevenue: {_curIadsInfo.revenue}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.NotReady:
|
case AdStatusType.NotReady:
|
||||||
msg = $"IADS: {ColoredText("not ready", Consts.ColorGray)}\n\t{ColoredText("---", Consts.ColorGray)}\n";
|
msg = $"IADS: {ColoredText("not ready", Const.ColorGray)}\n\t{ColoredText("---", Const.ColorGray)}\n";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
msg = $"IADS: {ColoredText("other", Consts.ColorGray)}\n\tstatus: {ColoredText($"{_curIadsInfo.status}", Consts.ColorYellow)}\n";
|
msg = $"IADS: {ColoredText("other", Const.ColorGray)}\n\tstatus: {ColoredText($"{_curIadsInfo.status}", Const.ColorYellow)}\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -187,32 +182,32 @@ namespace Guru
|
||||||
|
|
||||||
if (_curRadsInfo == null)
|
if (_curRadsInfo == null)
|
||||||
{
|
{
|
||||||
msg = $"RADS: {ColoredText("not ready", Consts.ColorRed)}\n";
|
msg = $"RADS: {ColoredText("not ready", Const.ColorRed)}\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (_curRadsInfo.status)
|
switch (_curRadsInfo.status)
|
||||||
{
|
{
|
||||||
case AdStatusType.Loaded:
|
case AdStatusType.Loaded:
|
||||||
msg = $"RADS: {ColoredText("loaded", Consts.ColorGreen)}\n\tnetwork: {_curRadsInfo.network}\n\twaterfall: {_curRadsInfo.waterfall}\n";
|
msg = $"RADS: {ColoredText("loaded", Const.ColorGreen)}\n\tnetwork: {_curRadsInfo.network}\n\twaterfall: {_curRadsInfo.waterfall}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.LoadFailed:
|
case AdStatusType.LoadFailed:
|
||||||
msg = $"RADS: {ColoredText("loading failed", Consts.ColorRed)}\n\tmessage: {_curRadsInfo.info}\n";
|
msg = $"RADS: {ColoredText("loading failed", Const.ColorRed)}\n\tmessage: {_curRadsInfo.info}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.DisplayFailed:
|
case AdStatusType.DisplayFailed:
|
||||||
msg = $"RADS: {ColoredText("display failed", Consts.ColorRed)}\n\tmessage: {_curRadsInfo.info}\n";
|
msg = $"RADS: {ColoredText("display failed", Const.ColorRed)}\n\tmessage: {_curRadsInfo.info}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.Loading:
|
case AdStatusType.Loading:
|
||||||
msg = $"RADS: {ColoredText("loading...", Consts.ColorYellow)}\n\tformat: {_curRadsInfo.format}\n";
|
msg = $"RADS: {ColoredText("loading...", Const.ColorYellow)}\n\tformat: {_curRadsInfo.format}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.Paid:
|
case AdStatusType.Paid:
|
||||||
msg = $"RADS: {ColoredText("get revenue", Consts.ColorGreen)}\n\trevenue: {_curRadsInfo.revenue}\n";
|
msg = $"RADS: {ColoredText("get revenue", Const.ColorGreen)}\n\trevenue: {_curRadsInfo.revenue}\n";
|
||||||
break;
|
break;
|
||||||
case AdStatusType.NotReady:
|
case AdStatusType.NotReady:
|
||||||
msg = $"RADS: {ColoredText("not ready", Consts.ColorGray)}\n\t{ColoredText("---", Consts.ColorGray)}\n";
|
msg = $"RADS: {ColoredText("not ready", Const.ColorGray)}\n\t{ColoredText("---", Const.ColorGray)}\n";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
msg = $"RADS: {ColoredText("other", Consts.ColorGray)}\n\tstatus: {ColoredText($"{_curRadsInfo.status}", Consts.ColorYellow)}\n";
|
msg = $"RADS: {ColoredText("other", Const.ColorGray)}\n\tstatus: {ColoredText($"{_curRadsInfo.status}", Const.ColorYellow)}\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -247,13 +242,13 @@ namespace Guru
|
||||||
private void AddCallbacks()
|
private void AddCallbacks()
|
||||||
{
|
{
|
||||||
//----------------- Banner -----------------
|
//----------------- Banner -----------------
|
||||||
ADService.OnBannerStartLoad += OnBannerStartLoadEvent;
|
ADService.Instance.OnBannerStartLoad += OnBannerStartLoadEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdLoadedEvent += OnBannerAdLoadedEvent;
|
MaxSdkCallbacks.Banner.OnAdLoadedEvent += OnBannerAdLoadedEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdLoadFailedEvent += OnBannerAdLoadFailEvent;
|
MaxSdkCallbacks.Banner.OnAdLoadFailedEvent += OnBannerAdLoadFailEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent += OnBannerAdRevenuePaidEvent;
|
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent += OnBannerAdRevenuePaidEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdClickedEvent += OnBannerAdClickedEvent;
|
MaxSdkCallbacks.Banner.OnAdClickedEvent += OnBannerAdClickedEvent;
|
||||||
//----------------- Interstitials -----------------
|
//----------------- Interstitials -----------------
|
||||||
ADService.OnInterstitialStartLoad += OnInterStartLoadEvent;
|
ADService.Instance.OnInterstitialStartLoad += OnInterStartLoadEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdLoadedEvent += OnInterAdLoadedEvent;
|
MaxSdkCallbacks.Interstitial.OnAdLoadedEvent += OnInterAdLoadedEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent += OnInterAdLoadFailEvent;
|
MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent += OnInterAdLoadFailEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdDisplayFailedEvent += OnInterAdDisplayFailEvent;
|
MaxSdkCallbacks.Interstitial.OnAdDisplayFailedEvent += OnInterAdDisplayFailEvent;
|
||||||
|
|
@ -261,7 +256,7 @@ namespace Guru
|
||||||
MaxSdkCallbacks.Interstitial.OnAdClickedEvent += OnInterAdClickedEvent;
|
MaxSdkCallbacks.Interstitial.OnAdClickedEvent += OnInterAdClickedEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdHiddenEvent += OnInterAdHiddenEvent;
|
MaxSdkCallbacks.Interstitial.OnAdHiddenEvent += OnInterAdHiddenEvent;
|
||||||
//----------------- Reward -----------------
|
//----------------- Reward -----------------
|
||||||
ADService.OnRewardedStartLoad += OnRewardedStartLoad;
|
ADService.Instance.OnRewardedStartLoad += OnRewardedStartLoad;
|
||||||
MaxSdkCallbacks.Rewarded.OnAdLoadedEvent += OnRewardAdLoadedEvent;
|
MaxSdkCallbacks.Rewarded.OnAdLoadedEvent += OnRewardAdLoadedEvent;
|
||||||
MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent += OnRewardAdLoadFailEvent;
|
MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent += OnRewardAdLoadFailEvent;
|
||||||
MaxSdkCallbacks.Rewarded.OnAdDisplayFailedEvent += OnRewardAdDisplayFailEvent;
|
MaxSdkCallbacks.Rewarded.OnAdDisplayFailedEvent += OnRewardAdDisplayFailEvent;
|
||||||
|
|
@ -273,13 +268,13 @@ namespace Guru
|
||||||
private void RemoveCallbacks()
|
private void RemoveCallbacks()
|
||||||
{
|
{
|
||||||
//----------------- Banner -----------------
|
//----------------- Banner -----------------
|
||||||
ADService.OnBannerStartLoad -= OnBannerStartLoadEvent;
|
ADService.Instance.OnBannerStartLoad -= OnBannerStartLoadEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdLoadedEvent -= OnBannerAdLoadedEvent;
|
MaxSdkCallbacks.Banner.OnAdLoadedEvent -= OnBannerAdLoadedEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdLoadFailedEvent -= OnBannerAdLoadFailEvent;
|
MaxSdkCallbacks.Banner.OnAdLoadFailedEvent -= OnBannerAdLoadFailEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent -= OnBannerAdRevenuePaidEvent;
|
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent -= OnBannerAdRevenuePaidEvent;
|
||||||
MaxSdkCallbacks.Banner.OnAdClickedEvent -= OnBannerAdClickedEvent;
|
MaxSdkCallbacks.Banner.OnAdClickedEvent -= OnBannerAdClickedEvent;
|
||||||
//----------------- Interstitials -----------------
|
//----------------- Interstitials -----------------
|
||||||
ADService.OnInterstitialStartLoad -= OnInterStartLoadEvent;
|
ADService.Instance.OnInterstitialStartLoad -= OnInterStartLoadEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdLoadedEvent -= OnInterAdLoadedEvent;
|
MaxSdkCallbacks.Interstitial.OnAdLoadedEvent -= OnInterAdLoadedEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent -= OnInterAdLoadFailEvent;
|
MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent -= OnInterAdLoadFailEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdDisplayFailedEvent -= OnInterAdDisplayFailEvent;
|
MaxSdkCallbacks.Interstitial.OnAdDisplayFailedEvent -= OnInterAdDisplayFailEvent;
|
||||||
|
|
@ -287,7 +282,7 @@ namespace Guru
|
||||||
MaxSdkCallbacks.Interstitial.OnAdClickedEvent -= OnInterAdClickedEvent;
|
MaxSdkCallbacks.Interstitial.OnAdClickedEvent -= OnInterAdClickedEvent;
|
||||||
MaxSdkCallbacks.Interstitial.OnAdHiddenEvent -= OnInterAdHiddenEvent;
|
MaxSdkCallbacks.Interstitial.OnAdHiddenEvent -= OnInterAdHiddenEvent;
|
||||||
//----------------- Reward -----------------
|
//----------------- Reward -----------------
|
||||||
ADService.OnRewardedStartLoad -= OnRewardedStartLoad;
|
ADService.Instance.OnRewardedStartLoad -= OnRewardedStartLoad;
|
||||||
MaxSdkCallbacks.Rewarded.OnAdLoadedEvent -= OnRewardAdLoadedEvent;
|
MaxSdkCallbacks.Rewarded.OnAdLoadedEvent -= OnRewardAdLoadedEvent;
|
||||||
MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent -= OnRewardAdLoadFailEvent;
|
MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent -= OnRewardAdLoadFailEvent;
|
||||||
MaxSdkCallbacks.Rewarded.OnAdDisplayFailedEvent -= OnRewardAdDisplayFailEvent;
|
MaxSdkCallbacks.Rewarded.OnAdDisplayFailedEvent -= OnRewardAdDisplayFailEvent;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
|
|
||||||
|
|
||||||
namespace Guru.Network
|
namespace Guru.Network
|
||||||
{
|
{
|
||||||
using Guru;
|
using Guru;
|
||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
public class NetworkStatusMonitor
|
public class NetworkStatusMonitor
|
||||||
{
|
{
|
||||||
private const string Tag = "[NET]";
|
private const string Tag = "[NET]";
|
||||||
|
|
||||||
private const string NETWORK_STATUS_NONE = "none";
|
private const string NETWORK_STATUS_NONE = "none";
|
||||||
private const string NETWORK_STATUS_MOBILE = "mobile";
|
private const string NETWORK_STATUS_MOBILE = "mobile";
|
||||||
private const string NETWORK_STATUS_WIFI = "wifi";
|
private const string NETWORK_STATUS_WIFI = "wifi";
|
||||||
|
|
@ -17,21 +20,176 @@ namespace Guru.Network
|
||||||
private const string NETWORK_STATUS_BLUETOOTH = "bluetooth";
|
private const string NETWORK_STATUS_BLUETOOTH = "bluetooth";
|
||||||
private const string NETWORK_STATUS_OTHER = "other";
|
private const string NETWORK_STATUS_OTHER = "other";
|
||||||
|
|
||||||
|
private const int CHECK_STATUS_INTERVAL_SECOND = 10;
|
||||||
|
|
||||||
|
private DateTime LastTriggerDate
|
||||||
|
{
|
||||||
|
get => _saveData.LastReportDate;
|
||||||
|
set => _saveData.LastReportDate = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string LastNetworkStatus
|
||||||
|
{
|
||||||
|
get => _saveData.LastReportStatus;
|
||||||
|
set => _saveData.LastReportStatus = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Action<string> _onNetworkStatusChanged;
|
||||||
|
private readonly Action<string> _onFirstOfflineToday;
|
||||||
|
private readonly NetworkMonitorData _saveData;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="onNetworkStatusChanged"></param>
|
||||||
|
/// <param name="onFirstOfflineToday"></param>
|
||||||
|
public NetworkStatusMonitor(Action<string> onNetworkStatusChanged, Action<string> onFirstOfflineToday)
|
||||||
|
{
|
||||||
|
_onNetworkStatusChanged = onNetworkStatusChanged;
|
||||||
|
_onFirstOfflineToday = onFirstOfflineToday;
|
||||||
|
|
||||||
|
_saveData = new NetworkMonitorData(); // 读取数据
|
||||||
|
|
||||||
|
//TODO: 此处不应使用协程实现, 协程只用在 UI 上。
|
||||||
|
CoroutineHelper.Instance.StartCoroutine(OnCheckingNetworkStatus(CHECK_STATUS_INTERVAL_SECOND));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取网络状态
|
/// 获取网络状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public string GetNetworkStatus()
|
public string GetNetworkStatus()
|
||||||
{
|
{
|
||||||
switch (Application.internetReachability)
|
var internetReachability = Application.internetReachability;
|
||||||
|
switch (internetReachability)
|
||||||
{
|
{
|
||||||
case NetworkReachability.ReachableViaLocalAreaNetwork:
|
|
||||||
return NETWORK_STATUS_WIFI;
|
|
||||||
case NetworkReachability.ReachableViaCarrierDataNetwork:
|
case NetworkReachability.ReachableViaCarrierDataNetwork:
|
||||||
return NETWORK_STATUS_MOBILE;
|
return NETWORK_STATUS_MOBILE;
|
||||||
|
case NetworkReachability.ReachableViaLocalAreaNetwork:
|
||||||
|
return NETWORK_STATUS_WIFI;
|
||||||
}
|
}
|
||||||
return NETWORK_STATUS_NONE;
|
return NETWORK_STATUS_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户是否已经失去了链接
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private bool IsUserOffline() => Application.internetReachability == NetworkReachability.NotReachable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 当前是可以打点上报
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private bool IsSameDay(DateTime date) => DateTime.UtcNow.DayOfYear != date.DayOfYear && DateTime.UtcNow.Year != date.Year;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置打点时间
|
||||||
|
/// </summary>
|
||||||
|
private void SetTriggerFirstOfflineDate() => LastTriggerDate = DateTime.UtcNow;
|
||||||
|
|
||||||
|
private bool ShouldTriggerFirstOffline()
|
||||||
|
{
|
||||||
|
return IsUserOffline() && IsSameDay(LastTriggerDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateNetworkStatus()
|
||||||
|
{
|
||||||
|
var status = GetNetworkStatus();
|
||||||
|
#if DEBUG
|
||||||
|
Debug.Log($"{Tag} --- Update network status:{status}");
|
||||||
|
#endif
|
||||||
|
if (status != LastNetworkStatus)
|
||||||
|
{
|
||||||
|
_onNetworkStatusChanged(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ShouldTriggerFirstOffline())
|
||||||
|
{
|
||||||
|
Debug.Log($"{Tag} --- Report Offline: {LastNetworkStatus}");
|
||||||
|
_onFirstOfflineToday?.Invoke(LastNetworkStatus);
|
||||||
|
SetTriggerFirstOfflineDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
LastNetworkStatus = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 每隔一段时间检测一次网络状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="interval"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private IEnumerator OnCheckingNetworkStatus(float interval)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
UpdateNetworkStatus();
|
||||||
|
yield return new WaitForSeconds(interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
class NetworkMonitorData
|
||||||
|
{
|
||||||
|
private const string K_NETWORK_MONITOR_DATA = "guru_network_monitor_data";
|
||||||
|
private const string NETWORK_STATUS_NOT_SET = "not_set";
|
||||||
|
|
||||||
|
private DateTime _lastReportDate;
|
||||||
|
public DateTime LastReportDate
|
||||||
|
{
|
||||||
|
get => _lastReportDate;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_lastReportDate = value;
|
||||||
|
Save(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _lastReportStatus;
|
||||||
|
public string LastReportStatus
|
||||||
|
{
|
||||||
|
get => _lastReportStatus;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_lastReportStatus = value;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetworkMonitorData()
|
||||||
|
{
|
||||||
|
Load(); // 立即加载数据
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Load()
|
||||||
|
{
|
||||||
|
var raw = PlayerPrefs.GetString(K_NETWORK_MONITOR_DATA, "");
|
||||||
|
|
||||||
|
_lastReportStatus = NETWORK_STATUS_NOT_SET;
|
||||||
|
_lastReportDate = new DateTime(1970, 1, 1);
|
||||||
|
if (!string.IsNullOrEmpty(raw))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var arr = raw.Split("|");
|
||||||
|
if (arr.Length > 0) _lastReportStatus = arr[0];
|
||||||
|
if (arr.Length > 1) _lastReportDate = DateTime.Parse(arr[1]);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.LogError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save(bool force = false)
|
||||||
|
{
|
||||||
|
var buffer = $"{_lastReportStatus}|{_lastReportDate:g}";
|
||||||
|
PlayerPrefs.SetString(K_NETWORK_MONITOR_DATA, buffer);
|
||||||
|
if(force) PlayerPrefs.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue