Compare commits

..

No commits in common. "85c8058158c39a193a2f551ffa5d34ad38d3f088" and "5c1f73fc1822ee07d4e8a5d0f73edf12c87ffa64" have entirely different histories.

43 changed files with 544 additions and 1033 deletions

View File

@ -72,7 +72,7 @@ namespace Guru
for (int i = 0; i < _params.Count; i++) for (int i = 0; i < _params.Count; i++)
{ {
// 上报实验AB属性 // 上报实验AB属性
GuruAnalytics.Instance.SetUserProperty(_params[i].id, _params[i].group); GuruAnalytics.SetUserProperty(_params[i].id, _params[i].group);
#if UNITY_EDITOR #if UNITY_EDITOR
Debug.Log($"[AB] --- Add AB Param <color=cyan>{_params[i].ToString()}</color>"); Debug.Log($"[AB] --- Add AB Param <color=cyan>{_params[i].ToString()}</color>");
#else #else

View File

@ -18,7 +18,7 @@ namespace Guru
public const string K_IAP_PURCHASE = "iap_purchase"; // 固定点位事件 public const string K_IAP_PURCHASE = "iap_purchase"; // 固定点位事件
public const string K_SUB_PURCHASE = "sub_purchase"; // 固定点位事件 public const string K_SUB_PURCHASE = "sub_purchase"; // 固定点位事件
private static Action<string> _onInitComplete; private static Action<string> _onSessionSuccessCallback;
private static string _adId = ""; private static string _adId = "";
@ -42,9 +42,6 @@ namespace Guru
return _adjustId; // Adjust AdId; return _adjustId; // Adjust AdId;
} }
} }
private static bool _isReady = false;
public static bool IsReady => _isReady;
#region 启动服务 #region 启动服务
@ -53,9 +50,7 @@ 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> public static void StartService(string appToken, string fbAppId = "", Action<string> onSessionSuccess = null)
/// <param name="onDeeplinkCallback"></param>
public static void StartService(string appToken, string fbAppId = "", Action<string> onInitComplete = null, Action<string> onDeeplinkCallback = null)
{ {
if (string.IsNullOrEmpty(appToken)) if (string.IsNullOrEmpty(appToken))
{ {
@ -63,7 +58,7 @@ namespace Guru
return; return;
} }
_onInitComplete = onInitComplete; _onSessionSuccessCallback = onSessionSuccess;
InstallEvent(IPMConfig.FIREBASE_ID, IPMConfig.IPM_DEVICE_ID); // 注入启动参数 InstallEvent(IPMConfig.FIREBASE_ID, IPMConfig.IPM_DEVICE_ID); // 注入启动参数
@ -71,12 +66,9 @@ namespace Guru
AdjustConfig config = new AdjustConfig(appToken, environment); AdjustConfig config = new AdjustConfig(appToken, environment);
config.setLogLevel(GetAdjustLogLevel()); config.setLogLevel(GetAdjustLogLevel());
config.setDelayStart(DelayTime); config.setDelayStart(DelayTime);
config.setPreinstallTrackingEnabled(true); // Adjust Preinstall config.setPreinstallTrackingEnabled(true); // Adjust Preinstall
config.setSessionSuccessDelegate(OnSessionSuccessCallback); // SessionSuccess config.setSessionSuccessDelegate(OnSessionSuccessCallback); // SessionSuccess
if(onDeeplinkCallback != null)
config.setDeferredDeeplinkDelegate(onDeeplinkCallback);
#if UNITY_ANDROID #if UNITY_ANDROID
if (!string.IsNullOrEmpty(fbAppId)) config.setFbAppId(fbAppId); // 注入 MIR ID if (!string.IsNullOrEmpty(fbAppId)) config.setFbAppId(fbAppId); // 注入 MIR ID
@ -87,6 +79,7 @@ namespace Guru
config.setLogDelegate(log => LogI(LOG_TAG, log)); config.setLogDelegate(log => LogI(LOG_TAG, log));
config.setEventSuccessDelegate(OnEventSuccessCallback); config.setEventSuccessDelegate(OnEventSuccessCallback);
config.setEventFailureDelegate(OnEventFailureCallback); config.setEventFailureDelegate(OnEventFailureCallback);
config.setSessionFailureDelegate(OnSessionFailureCallback); config.setSessionFailureDelegate(OnSessionFailureCallback);
config.setAttributionChangedDelegate(OnAttributionChangedCallback); config.setAttributionChangedDelegate(OnAttributionChangedCallback);
#endif #endif
@ -94,6 +87,9 @@ namespace Guru
SetupInstance(); SetupInstance();
Adjust.start(config); Adjust.start(config);
// 缓存标准属性
_adjustId = Adjust.getAdid(); // 获取AdjustID
// 异步加载AdId // 异步加载AdId
FetchGoogleAdId(); FetchGoogleAdId();
@ -164,22 +160,6 @@ namespace Guru
#endregion #endregion
#region 事件回调函数 #region 事件回调函数
/// <summary>
/// Session 启动后回调
/// 回调中可以获取实际的 AdjustID
/// </summary>
/// <param name="sessionSuccessData"></param>
private static void OnSessionSuccessCallback(AdjustSessionSuccess sessionSuccessData)
{
LogI(LOG_TAG,$"{LOG_TAG} --- Session tracked successfully!");
var adid = sessionSuccessData.Adid;
_adjustId = adid;
_isReady = true;
_onInitComplete?.Invoke(adid);
}
private static void OnAttributionChangedCallback(AdjustAttribution attributionData) private static void OnAttributionChangedCallback(AdjustAttribution attributionData)
{ {
@ -298,6 +278,14 @@ namespace Guru
LogI(LOG_TAG, "WillRetry: " + eventFailureData.WillRetry.ToString()); LogI(LOG_TAG, "WillRetry: " + eventFailureData.WillRetry.ToString());
} }
private static void OnSessionSuccessCallback(AdjustSessionSuccess sessionSuccessData)
{
LogI(LOG_TAG,$"{LOG_TAG} --- Session tracked successfully!");
var adid = sessionSuccessData.Adid;
_onSessionSuccessCallback?.Invoke(adid);
}
private static void OnSessionFailureCallback(AdjustSessionFailure sessionFailureData) private static void OnSessionFailureCallback(AdjustSessionFailure sessionFailureData)
{ {
LogI(LOG_TAG,"Session tracking failed!"); LogI(LOG_TAG,"Session tracking failed!");
@ -371,16 +359,16 @@ namespace Guru
/// 广告收入上报 (Adjust 特有的接口) /// 广告收入上报 (Adjust 特有的接口)
/// </summary> /// </summary>
/// <param name="adInfo"></param> /// <param name="adInfo"></param>
public static void TrackADRevenue(AdImpressionData impressionData) public static void TrackADRevenue(MaxSdkBase.AdInfo adInfo)
{ {
if (impressionData == null) if (adInfo == null)
return; return;
var adRevenue = new AdjustAdRevenue(AdjustConfig.AdjustAdRevenueSourceAppLovinMAX); var adRevenue = new AdjustAdRevenue(AdjustConfig.AdjustAdRevenueSourceAppLovinMAX);
adRevenue.setRevenue(impressionData.value, "USD"); adRevenue.setRevenue(adInfo.Revenue, "USD");
adRevenue.setAdRevenueNetwork(impressionData.ad_source); adRevenue.setAdRevenueNetwork(adInfo.NetworkName);
adRevenue.setAdRevenueUnit(impressionData.ad_unit_name); adRevenue.setAdRevenueUnit(adInfo.AdUnitIdentifier);
adRevenue.setAdRevenuePlacement(impressionData.ad_placement); adRevenue.setAdRevenuePlacement(adInfo.Placement);
Adjust.trackAdRevenue(adRevenue); Adjust.trackAdRevenue(adRevenue);
} }

View File

@ -14,60 +14,37 @@ namespace Guru
public class GuruAnalytics public class GuruAnalytics
{ {
// Plugin Version // Plugin Version
public const string Version = "1.11.1"; public const string Version = "1.10.5";
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";
private const int EventPriorityDefault = 10; internal const int EventPriorityDefault = 10;
private static GuruAnalytics _instance;
public static GuruAnalytics Instance
{
get
{
if (_instance == null)
{
throw new Exception("GuruAnalytics not initialized. Please call <Analytics.InitAnalytics()> first.");
}
return _instance;
}
}
private bool _isReady = false;
public bool IsReady => _isReady;
private IAnalyticsAgent _agent; private static IAnalyticsAgent _agent;
private IAnalyticsAgent Agent
public static IAnalyticsAgent Agent
{ {
get get
{ {
if (_agent == null) if (_agent == null)
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
_agent = new AnalyticsAgentMock(); _agent = new AnalyticsAgentStub();
#elif UNITY_ANDROID #elif UNITY_ANDROID
_agent = new AnalyticsAgentAndroid(); _agent = new AnalyticsAgentAndroid();
#elif UNITY_IOS #elif UNITY_IOS
_agent = new AnalyticsAgentIOS(); _agent = new AnalyticsAgentIOS();
#endif #endif
} }
if (_agent == null)
{
throw new NotImplementedException("You Should Implement IAnalyticsAgent on platform first.");
}
return _agent; return _agent;
} }
} }
private Dictionary<string, string> _userProperties; private static Dictionary<string, string> _userProperties;
/// <summary> /// <summary>
/// 用户属性缓存字典 /// 用户属性缓存字典
/// </summary> /// </summary>
private Dictionary<string, string> UserProperties public static Dictionary<string, string> UserProperties
{ {
get get
{ {
@ -82,13 +59,15 @@ namespace Guru
/// <summary> /// <summary>
/// 错误 code 表 /// 错误 code 表
/// </summary> /// </summary>
public List<int> ErrorCodeList = new List<int>(); public static List<int> ErrorCodeList = new List<int>();
private bool _enableErrorLog = false;
private static bool _autoSyncProperties = false;
private static bool _enableErrorLog = false;
/// <summary> /// <summary>
/// 启动日志错误上报 /// 启动日志错误上报
/// </summary> /// </summary>
public bool EnableErrorLog public static bool EnableErrorLog
{ {
get => _enableErrorLog; get => _enableErrorLog;
set set
@ -104,40 +83,37 @@ 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, bool isDebug = false,
bool enableErrorLog = false) bool enableErrorLog = false, bool syncProperties = false)
{ {
Debug.Log($"{Tag} --- Guru Analytics [{Version}] initialing..."); Debug.Log($"{Tag} --- Guru Analytics [{Version}] initialing...");
if (_instance == null) _autoSyncProperties = syncProperties;
{ _enableErrorLog = enableErrorLog;
_instance = new GuruAnalytics(); Agent?.Init(appId, deviceInfo, isDebug);
_instance.Agent.Init(appId, deviceInfo, onInitComplete, isDebug); if(_enableErrorLog) InitCallbacks(); // 激活错误日志回调
_instance.EnableErrorLog = enableErrorLog;
_instance._isReady = true;
}
} }
/// <summary> /// <summary>
/// 设置视图名称 /// 设置视图名称
/// </summary> /// </summary>
/// <param name="screenName"></param> /// <param name="screenName"></param>
public void SetScreen(string screenName) public static void SetScreen(string screenName)
{ {
if (string.IsNullOrEmpty(screenName)) return; if (string.IsNullOrEmpty(screenName)) return;
CacheUserProperty($"screen_name", screenName); CacheUserProperty($"screen_name", screenName);
Agent.SetScreen(screenName); Agent?.SetScreen(screenName);
} }
/// <summary> /// <summary>
/// 设置广告ID /// 设置广告ID
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
public void SetAdId(string id) public static void SetAdId(string id)
{ {
if (string.IsNullOrEmpty(id)) return; if (string.IsNullOrEmpty(id)) return;
CacheUserProperty($"ad_id", id); CacheUserProperty($"ad_id", id);
Agent.SetAdId(id); Agent?.SetAdId(id);
} }
/// <summary> /// <summary>
@ -145,59 +121,59 @@ namespace Guru
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="value"></param> /// <param name="value"></param>
public void SetUserProperty(string key, string value) public static void SetUserProperty(string key, string value)
{ {
if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value)) return; if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value)) return;
CacheUserProperty(key, value); // 添加用户属性 CacheUserProperty(key, value); // 添加用户属性
Agent.SetUserProperty(key, value); Agent?.SetUserProperty(key, value);
} }
/// <summary> /// <summary>
/// 设置Firebase ID /// 设置Firebase ID
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
public void SetFirebaseId(string id) public static void SetFirebaseId(string id)
{ {
if (string.IsNullOrEmpty(id)) return; if (string.IsNullOrEmpty(id)) return;
CacheUserProperty($"firebase_id", id); CacheUserProperty($"firebase_id", id);
Agent.SetFirebaseId(id); Agent?.SetFirebaseId(id);
} }
/// <summary> /// <summary>
/// 设置Adjust ID /// 设置Adjust ID
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
public void SetAdjustId(string id) public static void SetAdjustId(string id)
{ {
if (string.IsNullOrEmpty(id)) return; if (string.IsNullOrEmpty(id)) return;
CacheUserProperty($"adjust_id", id); CacheUserProperty($"adjust_id", id);
Agent.SetAdjustId(id); Agent?.SetAdjustId(id);
} }
/// <summary> /// <summary>
/// 设置设备ID /// 设置设备ID
/// </summary> /// </summary>
/// <param name="deviceId"></param> /// <param name="deviceId"></param>
public void SetDeviceId(string deviceId) public static void SetDeviceId(string deviceId)
{ {
if (string.IsNullOrEmpty(deviceId)) return; if (string.IsNullOrEmpty(deviceId)) return;
CacheUserProperty($"device_id", deviceId); CacheUserProperty($"device_id", deviceId);
Agent.SetDeviceId(deviceId); Agent?.SetDeviceId(deviceId);
} }
public void SetAndroidID(string androidId) public static void SetAndroidID(string androidId)
{ {
if (string.IsNullOrEmpty(androidId)) return; if (string.IsNullOrEmpty(androidId)) return;
CacheUserProperty(Analytics.PropertyAndroidID, androidId); CacheUserProperty(Analytics.PropertyAndroidID, androidId);
} }
public void SetIDFV(string idfv) public static void SetIDFV(string idfv)
{ {
if (string.IsNullOrEmpty(idfv)) return; if (string.IsNullOrEmpty(idfv)) return;
CacheUserProperty(Analytics.PropertyIDFV, idfv); CacheUserProperty(Analytics.PropertyIDFV, idfv);
} }
public void SetIDFA(string idfa) public static void SetIDFA(string idfa)
{ {
if (string.IsNullOrEmpty(idfa)) return; if (string.IsNullOrEmpty(idfa)) return;
CacheUserProperty(Analytics.PropertyIDFA, idfa); CacheUserProperty(Analytics.PropertyIDFA, idfa);
@ -208,17 +184,17 @@ namespace Guru
/// 设置用户ID /// 设置用户ID
/// </summary> /// </summary>
/// <param name="uid"></param> /// <param name="uid"></param>
public void SetUid(string uid) public static void SetUid(string uid)
{ {
if (string.IsNullOrEmpty(uid)) return; if (string.IsNullOrEmpty(uid)) return;
CacheUserProperty($"uid", uid); CacheUserProperty($"uid", uid);
Agent.SetUid(uid); Agent?.SetUid(uid);
} }
/// <summary> /// <summary>
/// 上报事件成功率 /// 上报事件成功率
/// </summary> /// </summary>
public void ReportEventSuccessRate() => Agent.ReportEventSuccessRate(); public static void ReportEventSuccessRate() => Agent?.ReportEventSuccessRate();
/// <summary> /// <summary>
/// 上报打点事件 /// 上报打点事件
@ -226,19 +202,21 @@ namespace Guru
/// <param name="eventName">事件名称</param> /// <param name="eventName">事件名称</param>
/// <param name="data">INT类型的值</param> /// <param name="data">INT类型的值</param>
/// <param name="priority"></param> /// <param name="priority"></param>
public void LogEvent(string eventName, Dictionary<string, dynamic> data = null, int priority = -1) public static void LogEvent(string eventName, Dictionary<string, dynamic> data = null, int priority = -1)
{ {
if(_autoSyncProperties)
UpdateAllUserProperties(); // 每次打点更新用户属性
string raw = ""; string raw = "";
if (data != null && data.Count > 0) if (data != null && data.Count > 0)
{ {
raw = BuildParamsJson(data); raw = BuildParamsJson(data);
} }
if (priority < 0) priority = EventPriorityDefault; if (priority < 0) priority = EventPriorityDefault;
Debug.Log($"{Tag} --- LogEvent GuruAnalytics:{eventName} | raw: {raw} | priority: {priority}"); Debug.Log($"{Tag} event:{eventName} | raw: {raw} | priority: {priority}");
Agent.LogEvent(eventName, raw, priority); Agent?.LogEvent(eventName, raw, priority);
} }
/*
private static string BuildParamsString(Dictionary<string, dynamic> data) private static string BuildParamsString(Dictionary<string, dynamic> data)
{ {
string raw = ""; string raw = "";
@ -250,9 +228,8 @@ namespace Guru
} }
return raw; return raw;
} }
*/
private string BuildParamsJson(Dictionary<string, dynamic> data) private static string BuildParamsJson(Dictionary<string, dynamic> data)
{ {
try try
{ {
@ -270,7 +247,6 @@ namespace Guru
return ""; return "";
} }
/*
/// <summary> /// <summary>
/// 构建带有类型格式的Str值 /// 构建带有类型格式的Str值
/// </summary> /// </summary>
@ -291,16 +267,15 @@ namespace Guru
return $"{kvp.Key}:s{kvp.Value}"; return $"{kvp.Key}:s{kvp.Value}";
} }
*/
/// <summary> /// <summary>
/// 设置太极02值 /// 设置太极02值
/// </summary> /// </summary>
/// <param name="value"></param> /// <param name="value"></param>
public void SetTch02Value(double value) public static void SetTch02Value(double value)
{ {
Debug.Log($"{Tag} set tch_02_value:{value}"); Debug.Log($"{Tag} set tch_02_value:{value}");
Agent.SetTch02Value(value); Agent?.SetTch02Value(value);
} }
#endregion #endregion
@ -321,19 +296,37 @@ namespace Guru
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="value"></param> /// <param name="value"></param>
private void CacheUserProperty(string key, string value) private static void CacheUserProperty(string key, string value)
{ {
// bool needUpdate = !UserProperties.ContainsKey(key) || UserProperties[key] != value; bool needUpdate = !UserProperties.ContainsKey(key) || UserProperties[key] != value;
UserProperties[key] = value; UserProperties[key] = value;
// if (needUpdate) UpdateAllUserProperties(); // if (needUpdate) UpdateAllUserProperties();
} }
private static void UpdateAllUserProperties()
{
if (UserProperties != null && UserProperties.Count > 0)
{
var keys = UserProperties.Keys.ToArray();
int i = 0;
string key = "";
while (i < keys.Length)
{
key = keys[i];
if(!string.IsNullOrEmpty(key)) SetUserProperty(key, UserProperties[key]);
i++;
}
keys = null;
}
}
#endregion #endregion
#region 日志回调 #region 日志回调
private void InitCallbacks() private static void InitCallbacks()
{ {
try try
{ {
@ -353,8 +346,8 @@ namespace Guru
/// <summary> /// <summary>
/// 获取SDK回调 /// 获取SDK回调
/// </summary> /// </summary>
/// <param name="raw"></param> /// <param name="msg"></param>
private void OnSDKCallback(string raw) private static void OnSDKCallback(string raw)
{ {
if (string.IsNullOrEmpty(raw)) return; if (string.IsNullOrEmpty(raw)) return;
if (!raw.Contains($"\"{ActionName}\"")) return; // 不对其他行为的日志进行过滤 if (!raw.Contains($"\"{ActionName}\"")) return; // 不对其他行为的日志进行过滤
@ -366,7 +359,7 @@ namespace Guru
/// </summary> /// </summary>
/// <param name="code"></param> /// <param name="code"></param>
/// <param name="errorInfo"></param> /// <param name="errorInfo"></param>
private void OnLoggerErrorEvent(int code, string errorInfo = "") private static void OnLoggerErrorEvent(int code, string errorInfo = "")
{ {
// Debug.Log($"{Tag} --- OnLoggerErrorEvent: code:{code}\tinfo:{errorInfo}"); // Debug.Log($"{Tag} --- OnLoggerErrorEvent: code:{code}\tinfo:{errorInfo}");
@ -395,13 +388,17 @@ namespace Guru
parameters["err"] = errorInfo; parameters["err"] = errorInfo;
Debug.Log($"{Tag} ------ ErrorLogInfo:: code:{codeString}\tinfo:{errorInfo}"); Debug.Log($"{Tag} ------ ErrorLogInfo:: code:{codeString}\tinfo:{errorInfo}");
#if !UNITY_EDITOR
// Only for firebase GA // Only for firebase GA
Analytics.TrackEvent("dev_audit", parameters, new Analytics.EventSetting() { EnableFirebaseAnalytics = true }); Analytics.LogEvent("dev_audit", parameters,
new Analytics.EventSetting() { EnableFirebaseAnalytics = true });
#endif
} }
private bool ParseWithJson(string json) private static bool ParseWithJson(string json)
{ {
Debug.Log($"{Tag} ------ ParseWithJson: json:\n{json}"); Debug.Log($"{Tag} ------ ParseWithJson: json:\n{json}");
@ -438,7 +435,7 @@ namespace Guru
{ {
string p = "\"msg\":\""; string p = "\"msg\":\"";
string m = json; string m = json;
if (json.Contains(p)) m = json.Substring(json.IndexOf(p, StringComparison.Ordinal) + p.Length); if (json.Contains(p)) m = json.Substring(json.IndexOf(p) + p.Length);
info = $"JsonEX:{m}"; info = $"JsonEX:{m}";
// Debug.Log($"{Tag} --- {info}"); // Debug.Log($"{Tag} --- {info}");
Analytics.LogCrashlytics(json, false); Analytics.LogCrashlytics(json, false);
@ -448,17 +445,22 @@ namespace Guru
return false; return false;
} }
/** private static void ParseWithRaw(string raw)
private void ParseWithRaw(string raw)
{ {
var code = (int)AnalyticsCode.Unknown; int code = (int)AnalyticsCode.Unknown;
string info; string info = raw;
//------- message send to unity ---------- //------- message send to unity ----------
Debug.Log($"{Tag} get callback errorInfo:\n{raw}"); Debug.Log($"{Tag} get callback errorInfo:\n{raw}");
string patten = "";
string patten2 = "";
int idx = 0;
int idx2 = 0;
int len = 0;
var patten = "msg\":\"";
patten = "msg\":\"";
if (raw.Contains(patten)) if (raw.Contains(patten))
{ {
@ -481,16 +483,16 @@ namespace Guru
try try
{ {
var idx = raw.IndexOf(patten, StringComparison.Ordinal) + patten.Length; idx = raw.IndexOf(patten, StringComparison.Ordinal) + patten.Length;
string act = raw.Substring(idx, ActionName.Length); string act = raw.Substring(idx, ActionName.Length);
if (act == ActionName) if (act == ActionName)
{ {
patten = "code\":"; patten = "code\":";
var patten2 = ",\"msg"; patten2 = ",\"msg";
idx = raw.IndexOf(patten, StringComparison.Ordinal); idx = raw.IndexOf(patten);
var idx2 = raw.IndexOf(patten2, StringComparison.Ordinal); idx2 = raw.IndexOf(patten2);
var len = idx2 - (idx + patten.Length); len = idx2 - (idx + patten.Length);
if (len > 0) if (len > 0)
{ {
string c = raw.Substring(idx + patten.Length, len); string c = raw.Substring(idx + patten.Length, len);
@ -529,12 +531,12 @@ namespace Guru
{ {
Analytics.LogCrashlytics(raw, false); Analytics.LogCrashlytics(raw, false);
Analytics.LogCrashlytics($"{Tag} --- format error:{raw}"); Analytics.LogCrashlytics($"{Tag} --- format error:{raw}");
OnLoggerErrorEvent(code, raw.Substring(raw.IndexOf("msg\":", StringComparison.Ordinal) + 5)); OnLoggerErrorEvent(code, raw.Substring(raw.IndexOf("msg\":" ) + 5));
} }
} }
**/
private void ReportCodeInfo(int code, string info)
private static void ReportCodeInfo(int code, string info)
{ {
var ac = (AnalyticsCode)code; var ac = (AnalyticsCode)code;
Debug.Log($"{Tag} ------ Get Code And Info: code:{code}[{ac}] \tinfo:{info}"); Debug.Log($"{Tag} ------ Get Code And Info: code:{code}[{ac}] \tinfo:{info}");
@ -590,7 +592,7 @@ namespace Guru
public static void TestOnCallback(string msg) public static void TestOnCallback(string msg)
{ {
Instance.OnSDKCallback(msg); OnSDKCallback(msg);
} }
#endif #endif

View File

@ -1,13 +1,11 @@
namespace Guru namespace Guru
{ {
using System;
/// <summary> /// <summary>
/// 自打点代理接口 /// 自打点代理接口
/// </summary> /// </summary>
public interface IAnalyticsAgent public interface IAnalyticsAgent
{ {
void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false); void Init(string appId, string deviceInfo, bool isDebug = false);
void SetScreen(string screenName); void SetScreen(string screenName);
void SetAdId(string id); void SetAdId(string id);
void SetUserProperty(string key, string value); void SetUserProperty(string key, string value);

View File

@ -1,7 +1,5 @@
using System.Threading.Tasks;
namespace Guru namespace Guru
{ {
using System; using System;
@ -78,16 +76,12 @@ namespace Guru
#region 接口实现 #region 接口实现
public async void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false) public void Init(string appId, string deviceInfo, 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) // public static void init(String appId, String deviceInfo, String bundleId, boolean isDebug, boolean useWorker, boolean useCronet, String baseUrl)
// TODO: 将来把 CallStatic 转为异步实现
CallStatic("init", appId, deviceInfo, bundleId, isDebug, UseWorker, UseCronet, BaseUrl); // 调用接口 CallStatic("init", appId, deviceInfo, bundleId, isDebug, UseWorker, UseCronet, BaseUrl); // 调用接口
onInitComplete?.Invoke();
} }
public void SetScreen(string screenName) public void SetScreen(string screenName)

View File

@ -1,9 +1,7 @@
using System.Runtime.InteropServices;
namespace Guru namespace Guru
{ {
using System;
using System.Runtime.InteropServices;
public class AnalyticsAgentIOS: IAnalyticsAgent public class AnalyticsAgentIOS: IAnalyticsAgent
{ {
@ -57,14 +55,13 @@ namespace Guru
} }
public void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false) public void Init(string appId, string deviceInfo, bool isDebug = false)
{ {
_isDebug = isDebug; _isDebug = isDebug;
#if UNITY_IOS #if UNITY_IOS
unityInitAnalytics(appId, deviceInfo, isDebug); unityInitAnalytics(appId, deviceInfo, isDebug);
unityInitException(); // 初始化报错守护进程 unityInitException(); // 初始化报错守护进程
#endif #endif
onInitComplete?.Invoke();
} }
public void SetScreen(string screenName) public void SetScreen(string screenName)

View File

@ -1,12 +1,9 @@
using System.Text;
using UnityEngine;
namespace Guru namespace Guru
{ {
using System.Text; public class AnalyticsAgentStub: IAnalyticsAgent
using UnityEngine;
using System;
public class AnalyticsAgentMock: IAnalyticsAgent
{ {
public static readonly string TAG = "[EDT]"; public static readonly string TAG = "[EDT]";
@ -27,7 +24,7 @@ namespace Guru
} }
public void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false) public void Init(string appId, string deviceInfo, bool isDebug = false)
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
_isShowLog = true; _isShowLog = true;
@ -35,8 +32,6 @@ namespace Guru
_isDebug = isDebug; _isDebug = isDebug;
if(_isShowLog) if(_isShowLog)
Debug.Log($"{TAG} init with Debug: <color=orange>{isDebug}</color> appId:{appId} deviceInfo:{deviceInfo}"); Debug.Log($"{TAG} init with Debug: <color=orange>{isDebug}</color> appId:{appId} deviceInfo:{deviceInfo}");
onInitComplete?.Invoke();
} }
@ -132,7 +127,7 @@ namespace Guru
} }
} }
Debug.Log($"{TAG} LogEvent: GuruAnalytics:<color=orange>{eventName} ({priority})</color> Properties:\n{sb.ToString()}"); Debug.Log($"{TAG} LogEvent: event:<color=orange>{eventName} ({priority})</color> Properties:\n{sb.ToString()}");
} }
} }
} }

View File

@ -5,7 +5,7 @@ using UnityEngine.UI;
namespace Guru namespace Guru
{ {
public class GuruAnalyticsDemo: MonoBehaviour public class CuruAnalyticsDemo: MonoBehaviour
{ {
[SerializeField] private bool _isDebug = true; [SerializeField] private bool _isDebug = true;
[SerializeField] private Button _btnInitSDK; [SerializeField] private Button _btnInitSDK;
@ -54,22 +54,17 @@ namespace Guru
private void OnClickInit() private void OnClickInit()
{ {
Debug.Log($"---- [DEMO] Call Analytics init"); Debug.Log($"---- [DEMO] Call Analytics init");
GuruAnalytics.Init(AppID, DeviceInfo, OnGuruAnalyticsInitComplete, _isDebug); GuruAnalytics.Init(AppID, DeviceInfo, _isDebug);
} }
private void OnGuruAnalyticsInitComplete()
{
}
private void OnClickStatus() private void OnClickStatus()
{ {
Debug.Log($"---- [DEMO] Report Stats IDs: UID:{UID} DeviceID:{DeviceID} FirebaseID:{FirebaseID} AdID:{AdID} AdjustID:{AdjustID}"); Debug.Log($"---- [DEMO] Report Stats IDs: UID:{UID} DeviceID:{DeviceID} FirebaseID:{FirebaseID} AdID:{AdID} AdjustID:{AdjustID}");
GuruAnalytics.Instance.SetUid(UID); GuruAnalytics.SetUid(UID);
GuruAnalytics.Instance.SetDeviceId(DeviceID); GuruAnalytics.SetDeviceId(DeviceID);
GuruAnalytics.Instance.SetFirebaseId(FirebaseID); GuruAnalytics.SetFirebaseId(FirebaseID);
GuruAnalytics.Instance.SetAdId(AdID); GuruAnalytics.SetAdId(AdID);
GuruAnalytics.Instance.SetAdjustId(AdjustID); GuruAnalytics.SetAdjustId(AdjustID);
} }
private void OnClickUserProperties() private void OnClickUserProperties()
@ -77,14 +72,14 @@ namespace Guru
string item_category = "main"; string item_category = "main";
int level = 7; int level = 7;
Debug.Log($"---- [DEMO] Call SetUserProperty: item_category:{item_category} level:{level}"); Debug.Log($"---- [DEMO] Call SetUserProperty: item_category:{item_category} level:{level}");
GuruAnalytics.Instance.SetUserProperty("item_category", item_category); GuruAnalytics.SetUserProperty("item_category", item_category);
GuruAnalytics.Instance.SetUserProperty("level", level.ToString()); GuruAnalytics.SetUserProperty("level", level.ToString());
} }
private void OnClickEvents() private void OnClickEvents()
{ {
Debug.Log($"---- [DEMO] Report Screen: {ScreenName}"); Debug.Log($"---- [DEMO] Report Screen: {ScreenName}");
GuruAnalytics.Instance.SetScreen(ScreenName); GuruAnalytics.SetScreen(ScreenName);
string eventName = "user_get_coin"; string eventName = "user_get_coin";
Dictionary<string, dynamic> data = new Dictionary<string, dynamic>() Dictionary<string, dynamic> data = new Dictionary<string, dynamic>()
@ -104,19 +99,19 @@ namespace Guru
Debug.Log(s); Debug.Log(s);
Debug.Log($"---- [DEMO] Call LogEvent"); Debug.Log($"---- [DEMO] Call LogEvent");
GuruAnalytics.Instance.LogEvent(eventName, data); GuruAnalytics.LogEvent(eventName, data);
} }
private void OnClickEvents2() private void OnClickEvents2()
{ {
string eventName = "user_data_loaded"; string eventName = "user_data_loaded";
GuruAnalytics.Instance.LogEvent(eventName); GuruAnalytics.LogEvent(eventName);
} }
private void OnClickReport() private void OnClickReport()
{ {
GuruAnalytics.Instance.ReportEventSuccessRate(); GuruAnalytics.ReportEventSuccessRate();
} }

View File

@ -140,7 +140,7 @@ namespace Guru
DmaResult = result; DmaResult = result;
//----------- Guru Analytics report --------------- //----------- Guru Analytics report ---------------
Analytics.TrackEvent("dma_gg", new Dictionary<string, dynamic>() Analytics.LogEvent("dma_gg", new Dictionary<string, dynamic>()
{ {
{ "purpose", purposeStr }, { "purpose", purposeStr },
{ "result", result } { "result", result }

View File

@ -1,7 +1,5 @@
using System.Threading.Tasks;
namespace Guru namespace Guru
{ {
using UnityEngine; using UnityEngine;
@ -32,21 +30,6 @@ namespace Guru
Debug.Log($"{Tag} Consent Request -> deviceid: {deviceId} debugGeography: {debugGeography}"); Debug.Log($"{Tag} Consent Request -> deviceid: {deviceId} debugGeography: {debugGeography}");
#if UNITY_EDITOR #if UNITY_EDITOR
SendEditorCallback();
#endif
}
#if UNITY_EDITOR
#endif
/// <summary>
/// 延迟触发 Consent
/// </summary>
private async void SendEditorCallback()
{
await Task.Delay(2000);
string msg = callbackMsgFmt.Replace("$0", $"{DebugStatusCode}").Replace("$1",DebugMessage); string msg = callbackMsgFmt.Replace("$0", $"{DebugStatusCode}").Replace("$1",DebugMessage);
var go = GameObject.Find(_objName); var go = GameObject.Find(_objName);
if (go != null) if (go != null)
@ -57,10 +40,9 @@ namespace Guru
{ {
Debug.LogError($"{Tag} Can't find callback object"); Debug.LogError($"{Tag} Can't find callback object");
} }
#endif
} }
/// <summary> /// <summary>
/// 获取 DMA 字段 /// 获取 DMA 字段
/// </summary> /// </summary>

View File

@ -1,5 +1,3 @@
using System.Linq;
namespace Guru namespace Guru
{ {
using System; using System;
@ -20,7 +18,7 @@ namespace Guru
} }
} }
protected static readonly string Tag = "[SDK][ADS]"; protected static readonly string Tag = "[Ads]";
public bool IsInitialized => MaxSdk.IsInitialized() || _isServiceStarted; public bool IsInitialized => MaxSdk.IsInitialized() || _isServiceStarted;
protected bool IsNetworkEnabled => Application.internetReachability != NetworkReachability.NotReachable; protected bool IsNetworkEnabled => Application.internetReachability != NetworkReachability.NotReachable;
@ -42,10 +40,7 @@ namespace Guru
public static Action OnRewardLoaded; public static Action OnRewardLoaded;
public static Action OnRewardFailed; public static Action OnRewardFailed;
public static Action OnRewardClosed; public static Action OnRewardClosed;
private Dictionary<string, string> _reviewCreativeIds = new Dictionary<string, string>(10); // Creative ID 缓存: Cid : RCid
private Dictionary<string, AdImpressionData> _impressionCache = new Dictionary<string, AdImpressionData>(10);
protected AdsModel _model; protected AdsModel _model;
protected AdsInitSpec _initSpec = null; protected AdsInitSpec _initSpec = null;
@ -94,12 +89,10 @@ namespace Guru
MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent; MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent += OnBannerRevenuePaidEvent; MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent += OnBannerRevenuePaidEvent;
MaxSdkCallbacks.MRec.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent; MaxSdkCallbacks.MRec.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
//--------------- Banner 回调 ----------------- //--------------- Banner 回调 -----------------
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;
//--------------- IV 回调 ----------------- //--------------- IV 回调 -----------------
MaxSdkCallbacks.Interstitial.OnAdLoadedEvent += OnInterstitialLoadedEvent; MaxSdkCallbacks.Interstitial.OnAdLoadedEvent += OnInterstitialLoadedEvent;
MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent += OnInterstitialFailedEvent; MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent += OnInterstitialFailedEvent;
@ -107,7 +100,6 @@ namespace Guru
MaxSdkCallbacks.Interstitial.OnAdClickedEvent += OnInterstitialClickEvent; MaxSdkCallbacks.Interstitial.OnAdClickedEvent += OnInterstitialClickEvent;
MaxSdkCallbacks.Interstitial.OnAdDisplayedEvent += OnInterstitialDisplayEvent; MaxSdkCallbacks.Interstitial.OnAdDisplayedEvent += OnInterstitialDisplayEvent;
MaxSdkCallbacks.Interstitial.OnAdHiddenEvent += OnInterstitialDismissedEvent; MaxSdkCallbacks.Interstitial.OnAdHiddenEvent += OnInterstitialDismissedEvent;
MaxSdkCallbacks.Interstitial.OnAdReviewCreativeIdGeneratedEvent += OnAdReviewCreativeIdGeneratedEvent;
//--------------- RV 回调 ----------------- //--------------- RV 回调 -----------------
MaxSdkCallbacks.Rewarded.OnAdLoadedEvent += OnRewardedAdLoadedEvent; MaxSdkCallbacks.Rewarded.OnAdLoadedEvent += OnRewardedAdLoadedEvent;
MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent += OnRewardedAdFailedEvent; MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent += OnRewardedAdFailedEvent;
@ -116,12 +108,7 @@ namespace Guru
MaxSdkCallbacks.Rewarded.OnAdClickedEvent += OnRewardedAdClickedEvent; MaxSdkCallbacks.Rewarded.OnAdClickedEvent += OnRewardedAdClickedEvent;
MaxSdkCallbacks.Rewarded.OnAdHiddenEvent += OnRewardedAdDismissedEvent; MaxSdkCallbacks.Rewarded.OnAdHiddenEvent += OnRewardedAdDismissedEvent;
MaxSdkCallbacks.Rewarded.OnAdReceivedRewardEvent += OnRewardedAdReceivedRewardEvent; 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"); // 修复黑屏
} }
@ -187,7 +174,7 @@ namespace Guru
#endregion #endregion
#region 收益打点 #region ILRD
private double TchAD001RevValue private double TchAD001RevValue
{ {
@ -201,46 +188,25 @@ namespace Guru
set => _model.TchAD02RevValue = value; set => _model.TchAD02RevValue = value;
} }
/// <summary> public void OnAdRevenuePaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
/// 上报广告收益
/// </summary>
/// <param name="adInfo"></param>
/// <param name="reviewedCreativeId"></param>
private void ReportAdsRevenue(AdImpressionData impressionData)
{
// #1 ad_impression
Analytics.ADImpression(impressionData);
// #2 tch_001
double revenue = impressionData.value;
CalcTaichi001Value(revenue);
CalcTaichi02Value(revenue);
// #3 adjust_ad_revenue
AdjustService.TrackADRevenue(impressionData);
}
private void OnAdRevenuePaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
{ {
if (adInfo == null) return; if (adInfo == null) return;
Debug.Log( $"{Tag} --- [Revenue] > [{adInfo.AdFormat}] --- adUnitId:{adUnitId}: UnitID:{adInfo.AdUnitIdentifier} Revenue:{adInfo.Revenue} CreativeId:{adInfo.CreativeIdentifier}");
try try
{ {
if (_reviewCreativeIds.TryGetValue(adInfo.CreativeIdentifier, out var reviewCreativeId)) Log.I( $"[ADRevenue] - adUnitId:{adUnitId}, Revenue:{adInfo?.Revenue : 0}");
{
// 找到 RCid 的话则直接上报广告收益 // #1 ad_impression
TryReportImpression(adInfo, reviewCreativeId); OnAdImpression(adInfo);
}
else // #2 tch_001
{ double revenue = adInfo.Revenue;
// 找不到的话会缓存 adInfo, 等待获取 RCid CalcTaichi001Value(revenue);
_impressionCache[adInfo.CreativeIdentifier] = CreateImpressionData(adInfo, "", Analytics.AdMAX); CalcTaichi02Value(revenue);
}
// #3 adjust_ad_revenue
AdjustService.TrackADRevenue(adInfo);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -250,30 +216,13 @@ namespace Guru
} }
/// <summary> /// <summary>
/// 构建 Impression 数据 /// 广告ARO收益打点
/// </summary> /// </summary>
/// <param name="adInfo"></param> /// <param name="adInfo"></param>
/// <param name="reviewCreativeId"></param>
/// <param name="platform"></param> /// <param name="platform"></param>
/// <returns></returns> private void OnAdImpression(MaxSdkBase.AdInfo adInfo, string platform = "")
private AdImpressionData CreateImpressionData(MaxSdkBase.AdInfo adInfo, string reviewCreativeId = "", string platform = "")
{ {
if (string.IsNullOrEmpty(platform)) platform = Analytics.AdMAX; Analytics.ADImpression(adInfo, platform);
var impression = new AdImpressionData()
{
value = adInfo.Revenue,
currency = Analytics.USD,
ad_platform = platform,
ad_format = adInfo.AdFormat,
ad_unit_name = adInfo.AdUnitIdentifier,
ad_source = adInfo.NetworkName,
ad_placement = adInfo.NetworkPlacement,
ad_creative_id = adInfo.CreativeIdentifier,
review_creative_id = reviewCreativeId
};
return impression;
} }
@ -437,7 +386,6 @@ namespace Guru
// --- fixed by Yufei 2024-5-29 为 don't report bads_loaded any more. --- // --- fixed by Yufei 2024-5-29 为 don't report bads_loaded any more. ---
// Analytics.ADBadsLoaded(AdParams.Build(adUnitId, adInfo, // Analytics.ADBadsLoaded(AdParams.Build(adUnitId, adInfo,
// duration: GetAdsLoadDuration(ref _badsloadStartTime), category: _badsCategory)); // duration: GetAdsLoadDuration(ref _badsloadStartTime), category: _badsCategory));
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
OnBadsLoaded(); OnBadsLoaded();
} }
@ -561,8 +509,6 @@ namespace Guru
duration: GetAdsLoadDuration(ref _iadsLoadStartTime), category: _iadsCategory)); duration: GetAdsLoadDuration(ref _iadsLoadStartTime), category: _iadsCategory));
_interstitialRetryAttempt = 0; _interstitialRetryAttempt = 0;
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
OnInterstitialLoaded?.Invoke(); OnInterstitialLoaded?.Invoke();
} }
@ -714,8 +660,6 @@ namespace Guru
Analytics.ADRadsLoaded(AdParams.Build(adUnitId, Analytics.ADRadsLoaded(AdParams.Build(adUnitId,
duration: GetAdsLoadDuration(ref _radsLoadStartTime), category: _iadsCategory)); duration: GetAdsLoadDuration(ref _radsLoadStartTime), category: _iadsCategory));
_rewardRetryAttempt = 0; _rewardRetryAttempt = 0;
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
OnRewardLoaded?.Invoke(); OnRewardLoaded?.Invoke();
} }
@ -838,78 +782,5 @@ namespace Guru
} }
#endregion #endregion
#region CreativeID
/// <summary>
/// 获取 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}");
if (adInfo == null || string.IsNullOrEmpty(adInfo.CreativeIdentifier))
{
Debug.LogError($"{Tag} --- Get ReviewCreativeId:{reviewCreativeId} but CreativeIdentifier is null");
return;
}
if (_reviewCreativeIds == null) _reviewCreativeIds = new Dictionary<string, string>(10);
// 尝试直接上报广告收益 (可能存在异步上报的情况)
if (!TryReportImpression(adInfo, reviewCreativeId))
{
_reviewCreativeIds[adInfo.CreativeIdentifier] = reviewCreativeId; // 如果上报未成功, 则缓存reviewCreativeId
}
}
/// <summary>
/// 尝试上报数据
/// </summary>
/// <param name="adInfo"></param>
/// <param name="reviewCreativeId"></param>
/// <returns></returns>
private bool TryReportImpression(MaxSdk.AdInfo adInfo, string reviewCreativeId = "")
{
string creativeId = adInfo.CreativeIdentifier;
bool result = false;
List<string> removeList = new List<string>();
if (_impressionCache.TryGetValue(creativeId, out var impressionData))
{
if(string.IsNullOrEmpty(impressionData.review_creative_id))
impressionData.review_creative_id = reviewCreativeId;
ReportAdsRevenue(impressionData);
removeList.Add(creativeId);
result = true;
}
// 清理超过 3 秒未上报的数据
foreach (var imp in _impressionCache.Values)
{
if (imp.GetPassedSecond() > 3.0)
{
ReportAdsRevenue(imp);
removeList.Add(imp.ad_creative_id);
}
}
if (removeList.Count > 0)
{
foreach (var k in removeList)
{
_impressionCache.Remove(k);
_reviewCreativeIds.Remove(k);
}
}
return result;
}
#endregion
} }
} }

View File

@ -1,40 +0,0 @@
namespace Guru
{
using System;
/// <summary>
/// AdImpression 对象
/// </summary>
public class AdImpressionData
{
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 DateTime createTime;
public AdImpressionData()
{
createTime = DateTime.UtcNow;
}
/// <summary>
/// 获取自创建开始经过的秒数
/// </summary>
/// <returns></returns>
public double GetPassedSecond()
{
return (DateTime.UtcNow - createTime).TotalSeconds;
}
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 1aca2a4507b94dfe9f88040125708edb
timeCreated: 1721883318

View File

@ -22,7 +22,7 @@ namespace Guru
} }
} }
internal static AdjustEvent CreateAdjustEvent(string eventName) private static AdjustEvent CreateAdjustEvent(string eventName)
{ {
string tokenID = GetAdjustEventToken(eventName); string tokenID = GetAdjustEventToken(eventName);
if (string.IsNullOrEmpty(tokenID)) if (string.IsNullOrEmpty(tokenID))

View File

@ -59,26 +59,26 @@ namespace Guru
//---------------------- BANNER ------------------------- //---------------------- BANNER -------------------------
public static void ADBadsLoad(AdParams adParams) public static void ADBadsLoad(AdParams adParams)
{ {
TrackEvent(EventBadsLoad, BuildAdEventData(adParams)); LogEvent(EventBadsLoad, BuildAdEventData(adParams));
} }
public static void ADBadsLoaded(AdParams adParams) public static void ADBadsLoaded(AdParams adParams)
{ {
TrackEvent(EventBadsLoaded, BuildAdEventData(adParams)); LogEvent(EventBadsLoaded, BuildAdEventData(adParams));
} }
public static void ADBadsFailed(AdParams adParams) public static void ADBadsFailed(AdParams adParams)
{ {
TrackEvent(EventBadsFailed, BuildAdEventData(adParams)); LogEvent(EventBadsFailed, BuildAdEventData(adParams));
} }
/// <summary> /// <summary>
/// 广告点击 /// 广告点击
/// </summary> /// </summary>
public static void ADBadsClick(AdParams adParams) public static void ADBadsClick(AdParams adParams)
{ {
TrackEvent(EventBadsClick, BuildAdEventData(adParams)); LogEvent(EventBadsClick, BuildAdEventData(adParams));
} }
public static void ADBadsImp(AdParams adParams) public static void ADBadsImp(AdParams adParams)
{ {
TrackEvent(EventBadsImp, BuildAdEventData(adParams)); LogEvent(EventBadsImp, BuildAdEventData(adParams));
} }
public static void ADBadsHide( int loadedTimes, int failTimes) public static void ADBadsHide( int loadedTimes, int failTimes)
@ -88,7 +88,7 @@ namespace Guru
["loaded_times"] = loadedTimes, ["loaded_times"] = loadedTimes,
["fail_times"] = failTimes ["fail_times"] = failTimes
}; };
TrackEvent(EventBadsHide, dict); LogEvent(EventBadsHide, dict);
} }
//---------------------- INTERSTITIAL ------------------------- //---------------------- INTERSTITIAL -------------------------
/// <summary> /// <summary>
@ -96,7 +96,7 @@ namespace Guru
/// </summary> /// </summary>
public static void ADIadsLoad(AdParams adParams) public static void ADIadsLoad(AdParams adParams)
{ {
TrackEvent(EventIadsLoad, BuildAdEventData(adParams)); LogEvent(EventIadsLoad, BuildAdEventData(adParams));
} }
/// <summary> /// <summary>
@ -104,7 +104,7 @@ namespace Guru
/// </summary> /// </summary>
public static void ADIadsLoaded(AdParams adParams) public static void ADIadsLoaded(AdParams adParams)
{ {
TrackEvent(EventIadsLoaded, BuildAdEventData(adParams)); LogEvent(EventIadsLoaded, BuildAdEventData(adParams));
} }
/// <summary> /// <summary>
@ -112,7 +112,7 @@ namespace Guru
/// </summary> /// </summary>
public static void ADIadsFailed(AdParams adParams) public static void ADIadsFailed(AdParams adParams)
{ {
TrackEvent(EventIadsFailed, BuildAdEventData(adParams)); LogEvent(EventIadsFailed, BuildAdEventData(adParams));
} }
/// <summary> /// <summary>
@ -120,7 +120,7 @@ namespace Guru
/// </summary> /// </summary>
public static void ADIadsImp(AdParams adParams) public static void ADIadsImp(AdParams adParams)
{ {
TrackEvent(EventIadsImp, BuildAdEventData(adParams)); LogEvent(EventIadsImp, BuildAdEventData(adParams));
} }
/// <summary> /// <summary>
@ -128,7 +128,7 @@ namespace Guru
/// </summary> /// </summary>
public static void ADIadsClick(AdParams adParams) public static void ADIadsClick(AdParams adParams)
{ {
TrackEvent(EventIadsClick, BuildAdEventData(adParams)); LogEvent(EventIadsClick, BuildAdEventData(adParams));
} }
/// <summary> /// <summary>
@ -136,7 +136,7 @@ namespace Guru
/// </summary> /// </summary>
public static void ADIadsClose(AdParams adParams) public static void ADIadsClose(AdParams adParams)
{ {
TrackEvent(EventIadsClose, BuildAdEventData(adParams)); LogEvent(EventIadsClose, BuildAdEventData(adParams));
} }
//---------------------- REWARDS ------------------------- //---------------------- REWARDS -------------------------
@ -145,28 +145,28 @@ namespace Guru
/// </summary> /// </summary>
public static void ADRadsLoad(AdParams adParams) public static void ADRadsLoad(AdParams adParams)
{ {
TrackEvent(EventRadsLoad, BuildAdEventData(adParams)); LogEvent(EventRadsLoad, BuildAdEventData(adParams));
} }
/// <summary> /// <summary>
/// 广告拉取成功 /// 广告拉取成功
/// </summary> /// </summary>
public static void ADRadsLoaded(AdParams adParams) public static void ADRadsLoaded(AdParams adParams)
{ {
TrackEvent(EventRadsLoaded, BuildAdEventData(adParams)); LogEvent(EventRadsLoaded, BuildAdEventData(adParams));
} }
/// <summary> /// <summary>
/// 广告拉取失败 /// 广告拉取失败
/// </summary> /// </summary>
public static void ADRadsFailed(AdParams adParams) public static void ADRadsFailed(AdParams adParams)
{ {
TrackEvent(EventRadsFailed, BuildAdEventData(adParams)); LogEvent(EventRadsFailed, BuildAdEventData(adParams));
} }
/// <summary> /// <summary>
/// 广告展示 /// 广告展示
/// </summary> /// </summary>
public static void ADRadsImp(AdParams adParams) public static void ADRadsImp(AdParams adParams)
{ {
TrackEvent(EventRadsImp, BuildAdEventData(adParams)); LogEvent(EventRadsImp, BuildAdEventData(adParams));
} }
/// <summary> /// <summary>
/// 广告完成观看发奖励 /// 广告完成观看发奖励
@ -174,7 +174,7 @@ namespace Guru
public static void ADRadsRewarded(AdParams adParams) public static void ADRadsRewarded(AdParams adParams)
{ {
var data = BuildAdEventData(adParams); var data = BuildAdEventData(adParams);
TrackEvent(EventRadsRewarded, data); LogEvent(EventRadsRewarded, data);
if (RadsRewardCount == 0) if (RadsRewardCount == 0)
{ {
@ -195,7 +195,7 @@ namespace Guru
/// </summary> /// </summary>
public static void ADRadsFirstRewarded(Dictionary<string, object> data) public static void ADRadsFirstRewarded(Dictionary<string, object> data)
{ {
TrackEvent(EventFirstRadsRewarded, data); LogEvent(EventFirstRadsRewarded, data);
} }
/// <summary> /// <summary>
@ -203,7 +203,7 @@ namespace Guru
/// </summary> /// </summary>
public static void ADRadsClick(AdParams adParams) public static void ADRadsClick(AdParams adParams)
{ {
TrackEvent(EventRadsClick, BuildAdEventData(adParams)); LogEvent(EventRadsClick, BuildAdEventData(adParams));
} }
/// <summary> /// <summary>
@ -211,7 +211,7 @@ namespace Guru
/// </summary> /// </summary>
public static void ADRadsClose(AdParams adParams) public static void ADRadsClose(AdParams adParams)
{ {
TrackEvent(EventRadsClose, BuildAdEventData(adParams)); LogEvent(EventRadsClose, BuildAdEventData(adParams));
} }
#endregion #endregion

View File

@ -16,7 +16,6 @@ namespace Guru
public static readonly string USD = "USD"; public static readonly string USD = "USD";
// 广告平台 // 广告平台
public static readonly string AdMAX = "MAX"; public static readonly string AdMAX = "MAX";
public static readonly string AdIronSource = "IronSource";
//IAP打点事件 //IAP打点事件
public static readonly string EventIAPFirst = "first_iap"; public static readonly string EventIAPFirst = "first_iap";
@ -43,7 +42,6 @@ namespace Guru
public static readonly string EventIadsFailed = "iads_failed"; public static readonly string EventIadsFailed = "iads_failed";
public static readonly string EventIadsImp = "iads_imp"; public static readonly string EventIadsImp = "iads_imp";
public static readonly string EventIadsClick = "iads_clk"; public static readonly string EventIadsClick = "iads_clk";
public static readonly string EventIadsPaid = "iads_paid";
public static readonly string EventIadsClose = "iads_close"; public static readonly string EventIadsClose = "iads_close";
//激励视频广告打点事件 //激励视频广告打点事件
@ -53,7 +51,6 @@ namespace Guru
public static readonly string EventRadsImp = "rads_imp"; public static readonly string EventRadsImp = "rads_imp";
public static readonly string EventRadsRewarded = "rads_rewarded"; public static readonly string EventRadsRewarded = "rads_rewarded";
public static readonly string EventRadsClick = "rads_clk"; public static readonly string EventRadsClick = "rads_clk";
public static readonly string EventRadsPaid = "rads_paid";
public static readonly string EventRadsClose = "rads_close"; public static readonly string EventRadsClose = "rads_close";
public static readonly string EventFirstRadsRewarded = "first_rads_rewarded"; public static readonly string EventFirstRadsRewarded = "first_rads_rewarded";
@ -81,10 +78,7 @@ namespace Guru
public static readonly string ParameterReplay = "replay"; // 游戏重玩 public static readonly string ParameterReplay = "replay"; // 游戏重玩
public static readonly string ParameterContinue = "continue"; // 游戏继续 public static readonly string ParameterContinue = "continue"; // 游戏继续
public static readonly string ParameterAdUnitName = "ad_unit_name"; public static readonly string ParameterAdUnitName = "ad_unit_name";
public static readonly string ParameterAdPlacement = "ad_placement";
public static readonly string ParameterAdCreativeId = "ad_creative_id"; public static readonly string ParameterAdCreativeId = "ad_creative_id";
public static readonly string ParameterReviewCreativeId = "review_creative_id";
// 评价参数 // 评价参数
public static readonly string EventRateImp = "rate_imp"; // 评价弹窗展示 public static readonly string EventRateImp = "rate_imp"; // 评价弹窗展示

View File

@ -26,7 +26,9 @@ namespace Guru
public static bool IsDebug { get; set; } = false; public static bool IsDebug { get; set; } = false;
private static bool _isGuruAnalyticInitOnce = false; private static bool _hasInited = false;
public static bool IsReady => _hasInited;
/// <summary> /// <summary>
/// 初始化Guru自打点系统 (请优先于 Firebase 初始化调用) /// 初始化Guru自打点系统 (请优先于 Firebase 初始化调用)
@ -34,7 +36,7 @@ namespace Guru
public static void InstallGuruAnalytics(bool isDebug = false, bool enableErrorLog = false) public static void InstallGuruAnalytics(bool isDebug = false, bool enableErrorLog = false)
{ {
if (_isGuruAnalyticInitOnce) return; if (_hasInited) return;
try try
{ {
@ -45,7 +47,7 @@ namespace Guru
#endif #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) GuruAnalytics.Init(appId, deviceInfo, IsDebug, enableErrorLog); // 初始化(带Header)
_hasGotFirebaseId = false; _hasGotFirebaseId = false;
_hasGotAdId = false; _hasGotAdId = false;
@ -57,7 +59,7 @@ namespace Guru
UpdateAllValues(); UpdateAllValues();
_isGuruAnalyticInitOnce = true; _hasInited = true;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -77,7 +79,7 @@ namespace Guru
if (!string.IsNullOrEmpty(IPMConfig.IPM_UID)) if (!string.IsNullOrEmpty(IPMConfig.IPM_UID))
{ {
Debug.Log($"---[ANA] UID: {IPMConfig.IPM_UID}"); Debug.Log($"---[ANA] UID: {IPMConfig.IPM_UID}");
GuruAnalytics.Instance.SetUid(IPMConfig.IPM_UID); GuruAnalytics.SetUid(IPMConfig.IPM_UID);
FirebaseAnalytics.SetUserProperty(PropertyUserID, IPMConfig.IPM_UID); FirebaseAnalytics.SetUserProperty(PropertyUserID, IPMConfig.IPM_UID);
_hasGotUid = true; _hasGotUid = true;
} }
@ -93,7 +95,7 @@ namespace Guru
if (!string.IsNullOrEmpty(IPMConfig.IPM_DEVICE_ID)) if (!string.IsNullOrEmpty(IPMConfig.IPM_DEVICE_ID))
{ {
GuruAnalytics.Instance.SetDeviceId(IPMConfig.IPM_DEVICE_ID); GuruAnalytics.SetDeviceId(IPMConfig.IPM_DEVICE_ID);
FirebaseAnalytics.SetUserProperty(PropertyDeviceID, IPMConfig.IPM_DEVICE_ID); FirebaseAnalytics.SetUserProperty(PropertyDeviceID, IPMConfig.IPM_DEVICE_ID);
_hasGotDeviceId = true; _hasGotDeviceId = true;
} }
@ -119,7 +121,7 @@ namespace Guru
if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ID)) if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ID))
{ {
GuruAnalytics.Instance.SetAdjustId(IPMConfig.ADJUST_ID); GuruAnalytics.SetAdjustId(IPMConfig.ADJUST_ID);
_hasGotAdjustId = true; _hasGotAdjustId = true;
} }
else else
@ -150,7 +152,7 @@ namespace Guru
if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ADID)) if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ADID))
{ {
GuruAnalytics.Instance.SetAdId(IPMConfig.ADJUST_ADID); GuruAnalytics.SetAdId(IPMConfig.ADJUST_ADID);
_hasGotAdId = true; _hasGotAdId = true;
} }
@ -169,7 +171,7 @@ namespace Guru
if (!string.IsNullOrEmpty(IPMConfig.FIREBASE_ID)) if (!string.IsNullOrEmpty(IPMConfig.FIREBASE_ID))
{ {
GuruAnalytics.Instance.SetFirebaseId(IPMConfig.FIREBASE_ID); GuruAnalytics.SetFirebaseId(IPMConfig.FIREBASE_ID);
_hasGotFirebaseId = true; _hasGotFirebaseId = true;
} }
else else
@ -183,8 +185,6 @@ namespace Guru
/// </summary> /// </summary>
private static void FetchFirebaseId() private static void FetchFirebaseId()
{ {
if (!IsFirebaseReady) return;
FirebaseAnalytics.GetAnalyticsInstanceIdAsync() FirebaseAnalytics.GetAnalyticsInstanceIdAsync()
.ContinueWithOnMainThread(task => .ContinueWithOnMainThread(task =>
{ {
@ -241,7 +241,7 @@ namespace Guru
/// </summary> /// </summary>
private static void SetAndroidId() private static void SetAndroidId()
{ {
GuruAnalytics.Instance.SetAndroidID(DeviceIDHelper.AndroidID); GuruAnalytics.SetAndroidID(DeviceIDHelper.AndroidID);
} }
#endif #endif
@ -276,7 +276,7 @@ namespace Guru
var interval = (DateTime.Now - _lastReportRateDate).TotalSeconds; var interval = (DateTime.Now - _lastReportRateDate).TotalSeconds;
if (interval > _reportSuccessInterval) if (interval > _reportSuccessInterval)
{ {
GuruAnalytics.Instance.ReportEventSuccessRate(); GuruAnalytics.ReportEventSuccessRate();
_lastReportRateDate = DateTime.Now; _lastReportRateDate = DateTime.Now;
} }
} }
@ -294,7 +294,7 @@ namespace Guru
{ {
try try
{ {
GuruAnalytics.Instance.SetUserProperty(key, value); GuruAnalytics.SetUserProperty(key, value);
UpdateAllValues(); // 同步所有的ID UpdateAllValues(); // 同步所有的ID
} }
catch (Exception e) catch (Exception e)
@ -309,12 +309,12 @@ namespace Guru
/// </summary> /// </summary>
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="data"></param> /// <param name="data"></param>
private static void TrackEventGuru(string key, Dictionary<string, dynamic> data = null, int priority = -1) private static void CustomLogEvent(string key, Dictionary<string, dynamic> data = null, int priority = -1)
{ {
try try
{ {
if (data == null) data = new Dictionary<string, dynamic>(); if (data == null) data = new Dictionary<string, dynamic>();
GuruAnalytics.Instance.LogEvent(key, data, priority); GuruAnalytics.LogEvent(key, data, priority);
UpdateAllValues(); // 同步所有的ID UpdateAllValues(); // 同步所有的ID
} }
catch (Exception e) catch (Exception e)
@ -337,7 +337,7 @@ namespace Guru
if (Math.Abs(_tch02TargetValue - value) > 0.001d) if (Math.Abs(_tch02TargetValue - value) > 0.001d)
{ {
_tch02TargetValue = value; _tch02TargetValue = value;
GuruAnalytics.Instance.SetTch02Value(value); GuruAnalytics.SetTch02Value(value);
} }
} }
} }

View File

@ -103,7 +103,7 @@ namespace Guru
if(!string.IsNullOrEmpty(scene)) data[ParameterScene] = scene; // 获取的虚拟货币或者道具的场景 if(!string.IsNullOrEmpty(scene)) data[ParameterScene] = scene; // 获取的虚拟货币或者道具的场景
if (extra != null) data.AddRange(extra, isOverride: true); if (extra != null) data.AddRange(extra, isOverride: true);
TrackEvent(EventEarnVirtualCurrency, data, new EventSetting() { EnableFirebaseAnalytics = true }); LogEvent(EventEarnVirtualCurrency, data, new EventSetting() { EnableFirebaseAnalytics = true });
// FB 上报收入点 // FB 上报收入点
FBService.LogEvent(EventEarnVirtualCurrency, value, data); FBService.LogEvent(EventEarnVirtualCurrency, value, data);
@ -131,7 +131,7 @@ namespace Guru
if(!string.IsNullOrEmpty(scene)) data[ParameterScene] = scene; // 获取的虚拟货币或者道具的场景 if(!string.IsNullOrEmpty(scene)) data[ParameterScene] = scene; // 获取的虚拟货币或者道具的场景
TrackEvent(EventSpendVirtualCurrency, data, new EventSetting() { EnableFirebaseAnalytics = true }); LogEvent(EventSpendVirtualCurrency, data, new EventSetting() { EnableFirebaseAnalytics = true });
// FB 上报消费点 // FB 上报消费点
FBService.LogEvent(EventSpendVirtualCurrency, value, data); FBService.LogEvent(EventSpendVirtualCurrency, value, data);

View File

@ -27,7 +27,7 @@ namespace Guru
}; };
if (extra != null) dict.AddRange(extra, isOverride:true); if (extra != null) dict.AddRange(extra, isOverride:true);
TrackEvent(EventLevelUp, dict); LogEvent(EventLevelUp, dict);
} }
/// <summary> /// <summary>
@ -42,7 +42,7 @@ namespace Guru
}; };
if (extra != null) dict.AddRange(extra, isOverride:true); if (extra != null) dict.AddRange(extra, isOverride:true);
TrackEvent(EventUnlockAchievement, dict); LogEvent(EventUnlockAchievement, dict);
} }
/// <summary> /// <summary>
@ -53,7 +53,7 @@ namespace Guru
[Obsolete("Obsolete method, please use <LogLevelStart> instead. will be discard in next version.")] [Obsolete("Obsolete method, please use <LogLevelStart> instead. will be discard in next version.")]
public static void LevelStart(int level) public static void LevelStart(int level)
{ {
TrackEvent(EventLevelStart, new Dictionary<string, object>() LogEvent(EventLevelStart, new Dictionary<string, object>()
{ {
{ ParameterLevel, level }, { ParameterLevel, level },
{ ParameterItemCategory, "main" }, { ParameterItemCategory, "main" },
@ -91,7 +91,7 @@ namespace Guru
dict.AddRange(extra, isOverride:true); dict.AddRange(extra, isOverride:true);
} }
TrackEvent(EventLevelStart, dict); LogEvent(EventLevelStart, dict);
} }
/// <summary> /// <summary>
@ -131,7 +131,7 @@ namespace Guru
if(extra != null) dict.AddRange(extra, isOverride:true); if(extra != null) dict.AddRange(extra, isOverride:true);
TrackEvent(EventLevelEnd, dict); LogEvent(EventLevelEnd, dict);
// if (isSuccess) // if (isSuccess)
// { // {
@ -160,7 +160,7 @@ namespace Guru
["level"] = level, ["level"] = level,
}; };
} }
TrackEvent(eventName, extra, new EventSetting() LogEvent(eventName, extra, new EventSetting()
{ {
EnableFirebaseAnalytics = true, EnableFirebaseAnalytics = true,
EnableFacebookAnalytics = true, EnableFacebookAnalytics = true,
@ -188,7 +188,7 @@ namespace Guru
if (extra != null) if (extra != null)
dict.AddRange(extra, isOverride: true); dict.AddRange(extra, isOverride: true);
TrackEvent(EventLevelFirstEnd, dict); LogEvent(EventLevelFirstEnd, dict);
} }
#endregion #endregion
@ -215,7 +215,7 @@ namespace Guru
}; };
if(extra != null) dict.AddRange(extra, isOverride: true); if(extra != null) dict.AddRange(extra, isOverride: true);
TrackEvent(EventEarnVirtualCurrency, dict); LogEvent(EventEarnVirtualCurrency, dict);
} }
/// <summary> /// <summary>
@ -237,7 +237,7 @@ namespace Guru
}; };
if(extra != null) dict.AddRange(extra, isOverride: true); if(extra != null) dict.AddRange(extra, isOverride: true);
TrackEvent(EventSpendVirtualCurrency, dict); LogEvent(EventSpendVirtualCurrency, dict);
} }
#endregion #endregion
@ -260,7 +260,7 @@ namespace Guru
}; };
if(extra != null) dict.AddRange(extra, isOverride: true); if(extra != null) dict.AddRange(extra, isOverride: true);
TrackEvent("hit_points", dict); LogEvent("hit_points", dict);
} }
#endregion #endregion
@ -387,7 +387,7 @@ namespace Guru
//--------- Extra data for IAP receipt --------------- //--------- Extra data for IAP receipt ---------------
TrackEvent(evtName, data); LogEvent(evtName, data);
} }
@ -416,6 +416,7 @@ namespace Guru
/// Google ARO买量点 /// Google ARO买量点
/// </summary> /// </summary>
/// <param name="impressionData">广告收入数据</param> /// <param name="impressionData">广告收入数据</param>
/// <param name="platform">广告平台</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 eg0.002 /// value double eg0.002
@ -426,25 +427,25 @@ 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(MaxSdkBase.AdInfo impressionData, string platform = "")
{ {
TrackEvent(EventAdImpression, new Dictionary<string, dynamic>() if (string.IsNullOrEmpty(platform)) platform = AdMAX;
double revenue = impressionData.Revenue;
LogEvent(EventAdImpression, new Dictionary<string, dynamic>()
{ {
[ParameterValue] = impressionData.value, [ParameterValue] = revenue,
[ParameterCurrency] = impressionData.currency, [ParameterCurrency] = USD,
[ParameterAdPlatform] = impressionData.ad_platform, [ParameterAdPlatform] = platform,
[ParameterAdSource] = impressionData.ad_source, [ParameterAdSource] = impressionData.NetworkName,
[ParameterAdFormat] = impressionData.ad_format, [ParameterAdFormat] = impressionData.AdFormat,
[ParameterAdUnitName] = impressionData.ad_unit_name, [ParameterAdUnitName] = impressionData.AdUnitIdentifier,
[ParameterAdPlacement] = impressionData.ad_placement, [ParameterAdCreativeId] = impressionData.CreativeIdentifier,
[ParameterAdCreativeId] = impressionData.ad_creative_id,
[ParameterReviewCreativeId] = impressionData.review_creative_id,
}); });
} }
public static void TchAdAbnormalEvent(double value) public static void TchAdAbnormalEvent(double value)
{ {
TrackEvent(EventTchAdRevAbnormal, new Dictionary<string, dynamic>() LogEvent(EventTchAdRevAbnormal, new Dictionary<string, dynamic>()
{ {
{ ParameterAdPlatform, AdMAX }, { ParameterAdPlatform, AdMAX },
{ ParameterCurrency, USD }, { ParameterCurrency, USD },
@ -469,7 +470,7 @@ namespace Guru
}; };
if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra); if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra);
TrackEvent(EventIAPImp, dict); LogEvent(EventIAPImp, dict);
} }
/// <summary> /// <summary>
@ -485,7 +486,7 @@ namespace Guru
}; };
if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra); if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra);
TrackEvent(EventIAPClose, dict); LogEvent(EventIAPClose, dict);
} }
/// <summary> /// <summary>
@ -511,7 +512,7 @@ namespace Guru
}; };
if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra); if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra);
TrackEvent(EventIAPClick, dict); LogEvent(EventIAPClick, dict);
} }
/// <summary> /// <summary>
@ -542,7 +543,7 @@ namespace Guru
if(!string.IsNullOrEmpty(offerId)) if(!string.IsNullOrEmpty(offerId))
dict["basePlan"] = offerId; dict["basePlan"] = offerId;
TrackEvent(EventIAPReturnTrue, dict, new EventSetting() LogEvent(EventIAPReturnTrue, dict, new EventSetting()
{ {
EnableFirebaseAnalytics = true, EnableFirebaseAnalytics = true,
EnableAdjustAnalytics = true, EnableAdjustAnalytics = true,
@ -558,7 +559,7 @@ namespace Guru
/// <param name="failReason"></param> /// <param name="failReason"></param>
internal static void IAPRetFalse(string itemCategory, string productId, string failReason) internal static void IAPRetFalse(string itemCategory, string productId, string failReason)
{ {
TrackEvent(EventIAPReturnFalse, new Dictionary<string, object>() LogEvent(EventIAPReturnFalse, new Dictionary<string, object>()
{ {
{ ParameterItemCategory, itemCategory }, { ParameterItemCategory, itemCategory },
{ ParameterItemName, productId }, { ParameterItemName, productId },
@ -575,7 +576,7 @@ namespace Guru
/// <param name="currency">币种</param> /// <param name="currency">币种</param>
public static void FirstIAP(string itemName, double value, string currency) public static void FirstIAP(string itemName, double value, string currency)
{ {
TrackEvent(EventIAPFirst, new Dictionary<string, object>() LogEvent(EventIAPFirst, new Dictionary<string, object>()
{ {
{ ParameterItemName, itemName }, { ParameterItemName, itemName },
{ ParameterValue, value }, { ParameterValue, value },
@ -596,7 +597,7 @@ namespace Guru
if (productName.Contains(".")) productName = productName.Replace(".", "_"); if (productName.Contains(".")) productName = productName.Replace(".", "_");
string eventName = $"iap_{productName}"; string eventName = $"iap_{productName}";
TrackEvent(eventName, new Dictionary<string, object>() LogEvent(eventName, new Dictionary<string, object>()
{ {
{ ParameterItemName, itemName }, { ParameterItemName, itemName },
{ ParameterValue, value }, { ParameterValue, value },
@ -723,8 +724,10 @@ namespace Guru
["sandbox"] = isSandbox? "true": "false" ["sandbox"] = isSandbox? "true": "false"
}; };
// 上报Firebase + 自打点 // 上报Firebase + 自打点
TrackEvent(eventName, dict, new EventSetting() { EnableFirebaseAnalytics = true }); LogEvent(eventName, dict, new EventSetting() { EnableFirebaseAnalytics = true });
// 上报 Adjust 支付事件 // 上报 Adjust 支付事件
LogAdjustRevenueEvent(eventName, value, productId, orderId, purchaseToken, receipt, dict); LogAdjustRevenueEvent(eventName, value, productId, orderId, purchaseToken, receipt, dict);
@ -743,7 +746,7 @@ namespace Guru
if (data == null) return; if (data == null) return;
data["country"] = IPMConfig.IPM_COUNTRY_CODE; data["country"] = IPMConfig.IPM_COUNTRY_CODE;
data["network"] = Application.internetReachability.ToString(); data["network"] = Application.internetReachability.ToString();
TrackEvent(EventDevAudit, data, new EventSetting() { EnableFirebaseAnalytics = true }); LogEvent(EventDevAudit, data, new EventSetting() { EnableFirebaseAnalytics = true });
} }
#endregion #endregion

View File

@ -1,7 +1,5 @@
using System.Threading;
namespace Guru namespace Guru
{ {
using System; using System;
@ -18,111 +16,82 @@ namespace Guru
{ {
public class EventSetting public class EventSetting
{ {
public bool EnableFirebaseAnalytics; public bool EnableFirebaseAnalytics = false;
public bool EnableAdjustAnalytics; public bool EnableAdjustAnalytics = false;
public bool EnableFacebookAnalytics; public bool EnableFacebookAnalytics = false;
public bool EnableGuruAnalytics;
public override string ToString()
{
return $"EvenSetting: firebase:{EnableFirebaseAnalytics}, adjust:{EnableAdjustAnalytics}, facebook:{EnableFacebookAnalytics}, guru:{EnableGuruAnalytics}";
}
public static EventSetting GetDefaultSetting()
{
return new EventSetting()
{
EnableFirebaseAnalytics = true,
EnableFacebookAnalytics = true,
EnableAdjustAnalytics = true,
EnableGuruAnalytics = true
};
}
} }
private static EventSetting DefaultEventSetting => EventSetting.GetDefaultSetting(); private static EventSetting _defaultEventSetting;
private static bool _isInitOnce; //Analytics是否初始化完成 private static bool _isInited; //Analytics是否初始化完成
public static bool EnableDebugAnalytics; //允许Debug包上报打点 public static bool EnableDebugAnalytics; //允许Debug包上报打点
public static bool IsDebugMode => PlatformUtil.IsDebug(); public static bool IsDebugMode => PlatformUtil.IsDebug();
private static bool IsFirebaseReady => FirebaseUtil.IsFirebaseInitialized;
private static bool IsReady private static bool IsEnable
{ {
get get
{ {
//Analytics没有初始化不上报打点
if (!_isInitOnce) return false;
//Firebase服务没有初始化完成不上报打点 //Firebase服务没有初始化完成不上报打点
if (!IsFirebaseReady) return false; if (!FirebaseUtil.IsFirebaseInitialized)
return false;
#if !UNITY_EDITOR //Analytics没有初始化不上报打点
if (!_isInited)
return false;
//开发环境打点不上报 //开发环境打点不上报
if (IsDebugMode && !EnableDebugAnalytics) if (IsDebugMode && !EnableDebugAnalytics)
return false; return false;
#endif
return true; return true;
} }
} }
private static AdjustEventDriver _adjustEventDriver;
private static FBEventDriver _fbEventDriver;
private static FirebaseEventDriver _firebaseEventDriver;
private static GuruEventDriver _guruEventDriver;
#region 初始化 #region 初始化
public static void InitAnalytics() public static void InitAnalytics()
{ {
if (_isInitOnce) return; if (_isInited) return;
_isInitOnce = true; _isInited = true;
_adjustEventDriver = new AdjustEventDriver(); // -------- 初始化 Exception ----------
_fbEventDriver = new FBEventDriver(); CrashlyticsAgent.Install();
_firebaseEventDriver = new FirebaseEventDriver();
_guruEventDriver = new GuruEventDriver();
// ------- 初始化自打点 ---------- // ------- 初始化自打点 ----------
InstallGuruAnalytics(IsDebug); InstallGuruAnalytics(IsDebug);
}
public static void OnFirebaseInitCompleted()
{
Debug.Log($"[SDK] --- Analytics Init After FirebaseReady:{IsFirebaseReady}");
// -------- 初始化 Crashlytics ---------- if (_defaultEventSetting == null)
CrashlyticsAgent.Init(); {
FirebaseAnalytics.SetAnalyticsCollectionEnabled(true); var analyticsSetting = GuruSettings.Instance.AnalyticsSetting;
FirebaseAnalytics.SetSessionTimeoutDuration(new TimeSpan(0, 30, 0)); _defaultEventSetting = new EventSetting
SetUserProperty(FirebaseAnalytics.UserPropertySignUpMethod, "Google"); {
SetUserProperty(PropertyDeviceID, IPMConfig.IPM_DEVICE_ID); EnableFirebaseAnalytics = analyticsSetting.EnalbeFirebaseAnalytics,
// SetUserProperty(PropertyFirstOpenTime, FirstOpenTime); EnableFacebookAnalytics = analyticsSetting.EnalbeFacebookAnalytics,
EnableAdjustAnalytics = analyticsSetting.EnalbeAdjustAnalytics
};
}
_firebaseEventDriver.TriggerFlush(); FirebaseUtil.onInitComplete += OnFirebaseCompleted;
}
public static void OnFBInitComplete()
{
_fbEventDriver.TriggerFlush();
} }
public static void OnAdjustInitComplete() private static void OnFirebaseCompleted(bool success)
{ {
_adjustEventDriver.TriggerFlush(); FirebaseUtil.onInitComplete -= OnFirebaseCompleted;
}
private static void OnGuruAnalyticsInitComplete()
{
_guruEventDriver.TriggerFlush();
}
if (success)
{
Crashlytics.IsCrashlyticsCollectionEnabled = true;
if (_defaultEventSetting.EnableFirebaseAnalytics)
{
FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
FirebaseAnalytics.SetSessionTimeoutDuration(new TimeSpan(0, 30, 0));
SetUserProperty(FirebaseAnalytics.UserPropertySignUpMethod, "Google");
SetUserProperty(PropertyDeviceID, IPMConfig.IPM_DEVICE_ID);
// SetUserProperty(PropertyFirstOpenTime, FirstOpenTime);
}
}
}
#endregion #endregion
@ -131,9 +100,9 @@ namespace Guru
public static void SetCurrentScreen(string screenName, string className) public static void SetCurrentScreen(string screenName, string className)
{ {
Log.I(TAG,$"SetCurrentScreen -> screenName:{screenName}, className:{className}"); Log.I(TAG,$"SetCurrentScreen -> screenName:{screenName}, className:{className}");
GuruAnalytics.Instance.SetScreen(screenName); GuruAnalytics.SetScreen(screenName);
if (!IsReady) return; if (!IsEnable) return;
FirebaseAnalytics.LogEvent(FirebaseAnalytics.EventScreenView, FirebaseAnalytics.LogEvent(FirebaseAnalytics.EventScreenView,
new Parameter(FirebaseAnalytics.ParameterScreenClass, className), new Parameter(FirebaseAnalytics.ParameterScreenClass, className),
new Parameter(FirebaseAnalytics.ParameterScreenName, screenName) new Parameter(FirebaseAnalytics.ParameterScreenName, screenName)
@ -151,7 +120,7 @@ namespace Guru
public static void SetUserIDProperty(string userID) public static void SetUserIDProperty(string userID)
{ {
Log.I(TAG,$"SetUserIDProperty -> userID:{userID}"); Log.I(TAG,$"SetUserIDProperty -> userID:{userID}");
if (!IsReady) return; if (!IsEnable) return;
FirebaseAnalytics.SetUserId(userID); FirebaseAnalytics.SetUserId(userID);
} }
@ -163,7 +132,7 @@ namespace Guru
{ {
Log.I(TAG,$"SetUserProperty -> propertyName:{propertyName}, propertyValue:{propertyValue}"); Log.I(TAG,$"SetUserProperty -> propertyName:{propertyName}, propertyValue:{propertyValue}");
if (!IsReady) if (!IsEnable)
return; return;
FirebaseAnalytics.SetUserProperty(propertyName, propertyValue); FirebaseAnalytics.SetUserProperty(propertyName, propertyValue);
@ -173,62 +142,112 @@ namespace Guru
#endregion #endregion
#region 打点上报 #region 打点上报
/// <summary>
/// 打点上报
/// </summary>
/// <param name="eventName"></param>
/// <param name="eventSetting"></param>
internal static void LogEvent(string eventName, EventSetting eventSetting = null, int priority = -1)
{
Log.I(TAG, $"eventName:{eventName}");
CustomLogEvent(eventName, null, priority); // 自定义打点上报
CheckLogCache(eventName, null, eventSetting); // log缓存和消费
if (!IsEnable) return;
eventSetting ??= _defaultEventSetting;
if (eventSetting.EnableFirebaseAnalytics)
{
FirebaseAnalytics.LogEvent(eventName);
}
if (eventSetting.EnableAdjustAnalytics)
{
Adjust.trackEvent(CreateAdjustEvent(eventName));
}
if (eventSetting.EnableFacebookAnalytics)
{
FBService.LogEvent(eventName);
}
}
/// <summary> /// <summary>
/// 打点上报 (带参数) /// 打点上报 (带参数)
/// </summary> /// </summary>
/// <param name="eventName"></param> /// <param name="eventName"></param>
/// <param name="data"></param> /// <param name="extras"></param>
/// <param name="eventSetting"></param> /// <param name="eventSetting"></param>
/// <param name="priority"></param> /// <param name="priority"></param>
internal static void TrackEvent(string eventName, Dictionary<string, dynamic> data, internal static void LogEvent(string eventName, Dictionary<string, dynamic> extras, EventSetting eventSetting = null, int priority = -1)
EventSetting eventSetting = null, int priority = -1)
{ {
if (!_isInitOnce) CustomLogEvent(eventName, extras, priority); // 自定义打点上报
{ CheckLogCache(eventName, extras, eventSetting); // log缓存和消费
throw new Exception($"【SDK] Analytics did not initialized, Call <Analytics.{nameof(InitAnalytics)}()> first!");
}
if (eventSetting == null) eventSetting = DefaultEventSetting;
var dataStr = "";
if (data != null) dataStr = JsonParser.ToJson(data);
Debug.Log($"{TAG} --- [SDK] TrackEvent: {eventName} | priority: {priority} | data:{dataStr} | eventSetting: {eventSetting}");
try if (!IsEnable) return;
if (extras == null)
{ {
// 填充相关的追踪事件 LogEvent(eventName, eventSetting, priority); // 防空判定
if (eventSetting.EnableGuruAnalytics) return;
}
string paramStr = string.Join(",", extras);
Log.I(TAG, $"eventName:{eventName}, params:{paramStr}");
if (eventSetting == null) eventSetting = _defaultEventSetting;
if (eventSetting.EnableFirebaseAnalytics)
{
List<Parameter> parameters = new List<Parameter>();
foreach (var kv in extras)
{ {
_guruEventDriver.Append(new TrackingEvent(eventName, data, eventSetting, priority)); if(kv.Value is string strValue)
parameters.Add(new Parameter(kv.Key, strValue));
else if (kv.Value is bool boolValue)
parameters.Add(new Parameter(kv.Key, boolValue ? "true" : "false"));
else if (kv.Value is int intValue)
parameters.Add(new Parameter(kv.Key, intValue));
else if (kv.Value is long longValue)
parameters.Add(new Parameter(kv.Key, longValue));
else if (kv.Value is float floatValue)
parameters.Add(new Parameter(kv.Key, floatValue));
else if (kv.Value is double doubleValue)
parameters.Add(new Parameter(kv.Key, doubleValue));
else if (kv.Value is decimal decimalValue)
parameters.Add(new Parameter(kv.Key, decimal.ToDouble(decimalValue)));
else
parameters.Add(new Parameter(kv.Key, kv.Value.ToString()));
} }
if (eventSetting.EnableFirebaseAnalytics)
FirebaseAnalytics.LogEvent(eventName, parameters.ToArray());
}
Dictionary<string, object> dict = new Dictionary<string, object>();
GuruSDKUtils.MergeDictionary(dict, extras);
if (eventSetting.EnableAdjustAnalytics)
{
AdjustEvent adjustEvent = Analytics.CreateAdjustEvent(eventName);
if (adjustEvent != null)
{ {
_firebaseEventDriver.Append(new TrackingEvent(eventName, data, eventSetting, priority)); if (dict.Count > 0)
} {
if (eventSetting.EnableAdjustAnalytics) foreach (var kv in dict)
{ {
_adjustEventDriver.Append(new TrackingEvent(eventName, data, eventSetting, priority)); adjustEvent.AddEventParameter(kv.Key, kv.Value.ToString());
} }
if (eventSetting.EnableFacebookAnalytics) }
{ Adjust.trackEvent(adjustEvent);
_fbEventDriver.Append(new TrackingEvent(eventName, data, eventSetting, priority));
} }
} }
catch (Exception ex)
if (eventSetting.EnableFacebookAnalytics)
{ {
if (FirebaseUtil.IsReady) FBService.LogEvent(eventName, null, dict);
{
Crashlytics.LogException(ex);
}
else
{
Debug.Log($"Catch Error: {ex}");
}
} }
} }
/// <summary> /// <summary>
/// 上报 Adjust 事件 /// 上报 Adjust 事件
@ -281,7 +300,14 @@ namespace Guru
/// <param name="priority"></param> /// <param name="priority"></param>
public static void Track(string key, Dictionary<string, dynamic> data = null, EventSetting setting = null, int priority = -1) public static void Track(string key, Dictionary<string, dynamic> data = null, EventSetting setting = null, int priority = -1)
{ {
TrackEvent(key, data, setting, priority); if (null != data)
{
LogEvent(key, data, setting, priority);
}
else
{
LogEvent(key, setting, priority);
}
} }
@ -292,7 +318,7 @@ namespace Guru
/// <param name="isException"></param> /// <param name="isException"></param>
public static void LogCrashlytics(string msg, bool isException = true) public static void LogCrashlytics(string msg, bool isException = true)
{ {
if (!_isInitOnce) return; if (!_isInited) return;
if (isException) if (isException)
{ {
LogCrashlytics(new Exception(msg)); LogCrashlytics(new Exception(msg));
@ -306,7 +332,7 @@ namespace Guru
public static void LogCrashlytics(Exception exp) public static void LogCrashlytics(Exception exp)
{ {
if (!_isInitOnce) return; if (!_isInited) return;
CrashlyticsAgent.LogException(exp); CrashlyticsAgent.LogException(exp);
} }
@ -314,58 +340,76 @@ namespace Guru
#region 打点缓存 #region 打点缓存
private static Queue<TrackingEvent> _savedLogs; private static Queue<SavedLog> _savedLogs;
internal static Queue<TrackingEvent> SavedLogs internal static Queue<SavedLog> SavedLogs
{ {
get get
{ {
if (_savedLogs == null) _savedLogs = new Queue<TrackingEvent>(20); if (_savedLogs == null) _savedLogs = new Queue<SavedLog>(20);
return _savedLogs; return _savedLogs;
} }
} }
private static void CheckLogCache(string key, Dictionary<string, dynamic> data = null, EventSetting setting = null, int priority = -1)
{
try
{
if (!_isInited)
{
if (data == null) data = new Dictionary<string, dynamic>();
data["log_stamp"] = TimeUtil.GetCurrentTimeStamp().ToString();
SavedLogs.Enqueue(new SavedLog(key, data, setting, priority));
}
else
{
int len = SavedLogs.Count;
if (len > 0)
{
while (SavedLogs.Count > 0)
{
var log = SavedLogs.Dequeue();
LogEvent(log.key, log.data, log.setting, log.priority);
}
}
}
}
catch (Exception ex)
{
Crashlytics.LogException(ex);
}
}
#endregion #endregion
} }
public class TrackingEvent internal class SavedLog
{ {
public string eventName; public string key;
public int priority; public int priority;
public Dictionary<string, dynamic> data; public Dictionary<string, dynamic> data;
public Analytics.EventSetting setting; public Analytics.EventSetting setting;
public TrackingEvent() public SavedLog()
{ {
} }
/// <summary> /// <summary>
/// 保存打点信息 /// 保存打点信息
/// </summary> /// </summary>
/// <param name="eventName"></param> /// <param name="_key"></param>
/// <param name="_data"></param> /// <param name="_data"></param>
/// <param name="_setting"></param> /// <param name="_setting"></param>
/// <param name="_priority"></param> /// <param name="_priority"></param>
public TrackingEvent(string eventName, Dictionary<string, dynamic> data = null, Analytics.EventSetting setting = null, int priority = -1) public SavedLog(string _key, Dictionary<string, dynamic> _data = null, Analytics.EventSetting _setting = null, int _priority = -1)
{ {
this.eventName = eventName; key = _key;
this.data = data; data = _data;
this.setting = setting; setting = _setting;
this.priority = priority; priority = _priority;
}
public void Flush()
{
Analytics.TrackEvent(eventName, data, setting, priority);
}
public override string ToString()
{
return $"eventName: {eventName}, data: {data}, setting: {setting}, priority: {priority}";
} }
} }
} }

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: d13f245a2ea24c8ebdb957ad4ba79ca4
timeCreated: 1721908201

View File

@ -1,46 +0,0 @@
namespace Guru
{
public abstract class AbstractEventDriver: IEventDriver
{
private GuruEventBuffer _buffer = new GuruEventBuffer();
// Firebase 是否可用
private bool _isDriverReady = false;
public void TriggerFlush()
{
_isDriverReady = true;
FlushAll();
}
public void Append(TrackingEvent trackingEvent)
{
if (_isDriverReady)
{
FlushTrackingEvent(trackingEvent);
}
else
{
_buffer.Push(trackingEvent);
}
}
private void FlushAll()
{
while(_buffer.Pop(out var trackingEvent))
{
FlushTrackingEvent(trackingEvent);
}
}
/// <summary>
/// 发送事件
/// </summary>
/// <param name="trackEvent"></param>
protected abstract void FlushTrackingEvent(TrackingEvent trackEvent);
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: fe02e66845f64aafa94654814822930a
timeCreated: 1721916181

View File

@ -1,35 +0,0 @@
using System.Collections.Generic;
namespace Guru
{
using com.adjust.sdk;
public class AdjustEventDriver : AbstractEventDriver
{
/// <summary>
/// 发送事件
/// </summary>
/// <param name="trackingEvent"></param>
protected override void FlushTrackingEvent(TrackingEvent trackingEvent)
{
var eventName = trackingEvent.eventName;
var data = trackingEvent.data;
AdjustEvent adjustEvent = Analytics.CreateAdjustEvent(eventName);
if (adjustEvent != null)
{
UnityEngine.Debug.Log($"[SDK] --- Adjust logEvent: {trackingEvent}");
if (data != null && data.Count > 0)
{
foreach (var kv in data)
{
adjustEvent.AddEventParameter(kv.Key, ((object)kv.Value).ToString());
}
}
Adjust.trackEvent(adjustEvent);
}
}
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: f064544085c8401d988b9eae91bd79b1
timeCreated: 1721910840

View File

@ -1,21 +0,0 @@
using System;
using UnityEngine;
namespace Guru
{
public class FBEventDriver: AbstractEventDriver
{
/// <summary>
/// 发送事件
/// </summary>
/// <param name="trackingEvent"></param>
protected override void FlushTrackingEvent(TrackingEvent trackingEvent)
{
var eventName = trackingEvent.eventName;
var data = trackingEvent.data;
Debug.Log($"[SDK] --- FB logEvent: {trackingEvent}");
FBService.LogEvent(eventName, null, data);
}
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 305a62f1c0fe4a16b7c9101264be523b
timeCreated: 1721910530

View File

@ -1,55 +0,0 @@
namespace Guru
{
using Firebase.Analytics;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Firebase 专用
/// </summary>
internal class FirebaseEventDriver : AbstractEventDriver
{
protected override void FlushTrackingEvent(TrackingEvent trackingEvent)
{
var eventName = trackingEvent.eventName;
var data = trackingEvent.data;
Debug.Log($"[SDK] --- Firebase logEvent: {trackingEvent}");
if (data != null)
{
List<Parameter> parameters = new List<Parameter>();
foreach (var kv in data)
{
if(kv.Value is string strValue)
parameters.Add(new Parameter(kv.Key, strValue));
else if (kv.Value is bool boolValue)
parameters.Add(new Parameter(kv.Key, boolValue ? "true" : "false"));
else if (kv.Value is int intValue)
parameters.Add(new Parameter(kv.Key, intValue));
else if (kv.Value is long longValue)
parameters.Add(new Parameter(kv.Key, longValue));
else if (kv.Value is float floatValue)
parameters.Add(new Parameter(kv.Key, floatValue));
else if (kv.Value is double doubleValue)
parameters.Add(new Parameter(kv.Key, doubleValue));
else if (kv.Value is decimal decimalValue)
parameters.Add(new Parameter(kv.Key, decimal.ToDouble(decimalValue)));
else
parameters.Add(new Parameter(kv.Key, kv.Value.ToString()));
}
FirebaseAnalytics.LogEvent(eventName, parameters.ToArray());
}
else
{
FirebaseAnalytics.LogEvent(eventName);
}
}
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 7a4c2262ab86431ba6d5961e7453d60f
timeCreated: 1721905429

View File

@ -1,55 +0,0 @@
using System.Collections.Generic;
namespace Guru
{
using System.Collections.Concurrent;
public class GuruEventBuffer
{
private ConcurrentQueue<TrackingEvent> _eventQueue;
public int Count => _eventQueue?.Count ?? -1;
/// <summary>
/// 构造函数
/// </summary>
public GuruEventBuffer()
{
_eventQueue = new ConcurrentQueue<TrackingEvent>();
}
/// <summary>
/// 入栈
/// </summary>
/// <param name="trackEvent"></param>
public void Push(TrackingEvent trackEvent)
{
_eventQueue.Enqueue(trackEvent);
}
/// <summary>
/// 出栈
/// </summary>
/// <param name="trackingEvent"></param>
/// <returns></returns>
public bool Pop(out TrackingEvent trackingEvent)
{
return _eventQueue.TryDequeue(out trackingEvent);
}
}
public interface IEventDriver
{
void TriggerFlush();
void Append(TrackingEvent trackingEvent);
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: f6dd65ae849944c59be2182eb64db34a
timeCreated: 1721899117

View File

@ -1,11 +0,0 @@
namespace Guru
{
public class GuruEventDriver: AbstractEventDriver
{
protected override void FlushTrackingEvent(TrackingEvent trackingEvent)
{
GuruAnalytics.Instance.LogEvent(trackingEvent.eventName, trackingEvent.data, trackingEvent.priority);
}
}
}

View File

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: d3fee5c262ca43c387ce76d52fb149c8
timeCreated: 1721908696

View File

@ -58,7 +58,7 @@ namespace Guru
if (!string.IsNullOrEmpty(value)) if (!string.IsNullOrEmpty(value))
{ {
PlayerPrefs.SetString(nameof(FirebaseId), value); PlayerPrefs.SetString(nameof(FirebaseId), value);
GuruAnalytics.Instance.SetFirebaseId(value); GuruAnalytics.SetFirebaseId(value);
} }
} }
} }
@ -73,7 +73,7 @@ namespace Guru
if (!string.IsNullOrEmpty(value)) if (!string.IsNullOrEmpty(value))
{ {
PlayerPrefs.SetString(nameof(AdjustId), value); PlayerPrefs.SetString(nameof(AdjustId), value);
GuruAnalytics.Instance.SetAdjustId(value); GuruAnalytics.SetAdjustId(value);
} }
} }
} }
@ -88,7 +88,7 @@ namespace Guru
if (!string.IsNullOrEmpty(value)) if (!string.IsNullOrEmpty(value))
{ {
PlayerPrefs.SetString(nameof(GoogleAdId), value); PlayerPrefs.SetString(nameof(GoogleAdId), value);
GuruAnalytics.Instance.SetAdId(value); GuruAnalytics.SetAdId(value);
} }
} }
} }

View File

@ -1,38 +1,44 @@
using System.Collections.Generic;
using Facebook.Unity;
using UnityEngine;
namespace Guru namespace Guru
{ {
using System;
using System.Collections.Generic;
using Facebook.Unity;
using UnityEngine;
[MonoSingleton(EMonoSingletonType.CreateOnNewGameObject, false)] [MonoSingleton(EMonoSingletonType.CreateOnNewGameObject, false)]
public class FBService : MonoSingleton<FBService> public class FBService : MonoSingleton<FBService>
{ {
private const string Tag = "[FB]"; public static readonly string LOG_TAG = "FB";
private bool _isInitOnce;
private Action _onInitComplete;
public void StartService(Action onInitComplete) public void StartService()
{ {
if(_isInitOnce) return; if (!FB.IsInitialized)
_isInitOnce = true; {
// Initialize the Facebook SDK
_onInitComplete = onInitComplete; FB.Init(InitCallback, OnHideUnity);
// Initialize the Facebook SDK }
FB.Init(InitCallback, OnHideUnity); else
{
// Already initialized, signal an app activation App Event
FB.ActivateApp();
}
} }
private void InitCallback() private void InitCallback()
{ {
if (FB.IsInitialized)
// Signal an app activation App Event {
FB.ActivateApp(); // Signal an app activation App Event
FB.Mobile.SetAdvertiserIDCollectionEnabled(true); FB.ActivateApp();
FB.Mobile.SetAutoLogAppEventsEnabled(false); // 关闭自动打点上报 FB.Mobile.SetAdvertiserIDCollectionEnabled(true);
FB.Mobile.SetAutoLogAppEventsEnabled(false); // 关闭自动打点上报
#if UNITY_IOS #if UNITY_IOS
FB.Mobile.SetAdvertiserTrackingEnabled(true); FB.Mobile.SetAdvertiserTrackingEnabled(true);
#endif #endif
_onInitComplete?.Invoke(); }
else
{
Log.E(LOG_TAG, "Failed to Initialize the Facebook SDK");
}
} }
private void OnHideUnity(bool isGameShown) private void OnHideUnity(bool isGameShown)
@ -75,13 +81,13 @@ namespace Guru
} }
public static bool IsAvailable private static bool IsAvailable
{ {
get get
{ {
if (!FB.IsInitialized) if (!FB.IsInitialized)
{ {
Debug.LogError($"{Tag} FB is not initialized, please call <FBService.StartService> first."); Debug.LogError("[FB] FB is not initialized, please call <FBService.StartService> first.");
return false; return false;
} }
return true; return true;

View File

@ -9,6 +9,7 @@ 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 _isDebug = false;
private static bool _isReady = false; private static bool _isReady = false;
public static bool IsReady => _isReady; public static bool IsReady => _isReady;
@ -18,13 +19,14 @@ namespace Guru
public static Action<bool> OnFirebaseAuthResult; public static Action<bool> OnFirebaseAuthResult;
public static Action<bool> OnUserAuthResult; public static Action<bool> OnUserAuthResult;
public static Action<string> OnAdjustDeeplinkCallback = null;
public static void InitFirebase(Action callback)
public static void InitFirebase(Action callback, bool isDebug = false)
{ {
_isReady = false; _isReady = false;
// Analytics.InitAnalytics(); // 打点提前初始化 _isDebug = isDebug;
Analytics.InitAnalytics(); // 打点提前初始化
// Loom.StartUp(); // 确保主线程开启 // Loom.StartUp(); // 确保主线程开启
@ -101,7 +103,6 @@ namespace Guru
FirebaseAnalytics.GetAnalyticsInstanceIdAsync() FirebaseAnalytics.GetAnalyticsInstanceIdAsync()
.ContinueWithOnMainThread(task => .ContinueWithOnMainThread(task =>
{ {
if (task.IsCompleted && !string.IsNullOrEmpty(task.Result)) if (task.IsCompleted && !string.IsNullOrEmpty(task.Result))
{ {
// 保存本地ID备份 // 保存本地ID备份
@ -118,29 +119,27 @@ namespace Guru
string fbAppId = GuruSettings.Instance.IPMSetting.FacebookAppId; string fbAppId = GuruSettings.Instance.IPMSetting.FacebookAppId;
if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ID)) if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ID))
{
ReportAdjustId(IPMConfig.ADJUST_ID); // 二次启动后,若有值则立即上报属性 ReportAdjustId(IPMConfig.ADJUST_ID); // 二次启动后,若有值则立即上报属性
}
AdjustService.StartService(appToken, fbAppId, adjustId =>
{
// 获取 ADID
if (string.IsNullOrEmpty(adjustId))
{
adjustId = "not_set";
}
else
{
IPMConfig.ADJUST_ID = adjustId;
}
ReportAdjustId(adjustId);
});
AdjustService.StartService(appToken, fbAppId, OnGetAdjustId, OnAdjustDeeplinkCallback);
}); });
} }
private static void OnGetAdjustId(string adjustId)
{
// 获取 ADID
if (string.IsNullOrEmpty(adjustId))
{
adjustId = "not_set";
}
else
{
IPMConfig.ADJUST_ID = adjustId;
}
ReportAdjustId(adjustId);
Analytics.OnAdjustInitComplete();
}
private static void ReportAdjustId(string adjustId) private static void ReportAdjustId(string adjustId)
{ {

View File

@ -9,8 +9,9 @@ namespace Guru
public static class CrashlyticsAgent public static class CrashlyticsAgent
{ {
private static bool _initOnce; private static bool _initOnce;
private static bool IsFirebaseReady => FirebaseUtil.IsFirebaseInitialized; private static bool _isReady;
private static Queue<Exception> _expCache;
private static bool _hasSetUser = false; private static bool _hasSetUser = false;
/// <summary> /// <summary>
@ -31,18 +32,45 @@ namespace Guru
LogType.Assert, LogType.Assert,
}; };
public static void Init() public static void Install()
{ {
if (_initOnce) return; if (_initOnce) return;
_initOnce = true; _initOnce = true;
_expCache = new Queue<Exception>(20);
Application.logMessageReceived -= OnReceivedMessage; Application.logMessageReceived -= OnReceivedMessage;
Application.logMessageReceived += OnReceivedMessage; Application.logMessageReceived += OnReceivedMessage;
Crashlytics.IsCrashlyticsCollectionEnabled = true; // Application.logMessageReceivedThreaded -= OnReceivedMessage;
// Application.logMessageReceivedThreaded += OnReceivedMessage;
if (FirebaseUtil.IsReady)
{
OnFirebaseComplete(true);
return;
}
FirebaseUtil.onInitComplete -= OnFirebaseComplete;
FirebaseUtil.onInitComplete += OnFirebaseComplete;
} }
private static void OnFirebaseComplete(bool success)
{
FirebaseUtil.onInitComplete -= OnFirebaseComplete;
if (success)
{
_isReady = true;
Crashlytics.IsCrashlyticsCollectionEnabled = true;
if (_expCache != null && _expCache.Count > 0)
{
while (_expCache.Count > 0)
{
LogException(_expCache.Dequeue());
}
_expCache.Clear();
}
}
}
private static string ToLogTypeString(LogType type) private static string ToLogTypeString(LogType type)
{ {
@ -73,8 +101,14 @@ namespace Guru
public static void LogException(Exception ex) public static void LogException(Exception ex)
{ {
if (!IsFirebaseReady) return; if (!_isReady)
{
Install();
_expCache.Enqueue(ex);
return;
}
Crashlytics.LogException(ex); Crashlytics.LogException(ex);
// CheckSetUser();
} }
public static void LogException(string msg) public static void LogException(string msg)
@ -84,14 +118,15 @@ namespace Guru
public static void Log(string msg) public static void Log(string msg)
{ {
if (!IsFirebaseReady) return; if (!_isReady) return;
Crashlytics.Log(msg); Crashlytics.Log(msg);
// CheckSetUser();
} }
public static void SetCustomKey(string key, string value) public static void SetCustomKey(string key, string value)
{ {
if (!IsFirebaseReady) return; if (!_isReady) return;
Crashlytics.SetCustomKey(key, value); Crashlytics.SetCustomKey(key, value);
} }

View File

@ -140,13 +140,9 @@ namespace Guru
public class AnalyticsSetting public class AnalyticsSetting
{ {
[SerializeField] private int levelEndSuccessNum = 50; [SerializeField] private int levelEndSuccessNum = 50;
[Obsolete("Will not use in next version", false)]
[SerializeField] private bool enalbeFirebaseAnalytics = true; [SerializeField] private bool enalbeFirebaseAnalytics = true;
[Obsolete("Will not use in next version", false)]
[SerializeField] private bool enalbeFacebookAnalytics = true; [SerializeField] private bool enalbeFacebookAnalytics = true;
[Obsolete("Will not use in next version", false)]
[SerializeField] private bool enalbeAdjustAnalytics = true; [SerializeField] private bool enalbeAdjustAnalytics = true;
[SerializeField] internal List<AdjustEvent> adjustEventList; [SerializeField] internal List<AdjustEvent> adjustEventList;
public int LevelEndSuccessNum => levelEndSuccessNum; public int LevelEndSuccessNum => levelEndSuccessNum;

View File

@ -1132,7 +1132,7 @@ namespace Guru
private void ReportGoogleOrderLost(GoogleOrderData data) private void ReportGoogleOrderLost(GoogleOrderData data)
{ {
Analytics.TrackEvent("google_order_lost", new Dictionary<string, dynamic>() Analytics.LogEvent("google_order_lost", new Dictionary<string, dynamic>()
{ {
["data"] = data.ToString(), ["data"] = data.ToString(),
}, new Analytics.EventSetting() }, new Analytics.EventSetting()
@ -1144,7 +1144,7 @@ namespace Guru
private void ReportAppleOrderLost(AppleOrderData data) private void ReportAppleOrderLost(AppleOrderData data)
{ {
Analytics.TrackEvent("apple_order_lost", new Dictionary<string, dynamic>() Analytics.LogEvent("apple_order_lost", new Dictionary<string, dynamic>()
{ {
["data"] = data.ToString(), ["data"] = data.ToString(),
}, new Analytics.EventSetting() }, new Analytics.EventSetting()

View File

@ -87,8 +87,6 @@ namespace Guru
MinimumFetchInternalInMilliseconds = (ulong)(_fetchIntervalHours * 60 * 60 * 1000) MinimumFetchInternalInMilliseconds = (ulong)(_fetchIntervalHours * 60 * 60 * 1000)
}); });
_firebaseRemote.OnConfigUpdateListener += OnConfigUpdatedHandler;
// 设置默认值 // 设置默认值
AppendDefaultValues(defaults); AppendDefaultValues(defaults);
_initOnce = true; _initOnce = true;
@ -96,8 +94,7 @@ namespace Guru
// 监听事件合集 // 监听事件合集
_changeEvents = new Dictionary<string, Action<string,string>>(30); _changeEvents = new Dictionary<string, Action<string,string>>(30);
// 立即拉取所有的配置 FetchAllConfigs();
FetchAllConfigsImmediately();
} }
private void AppendDefaultValues(Dictionary<string, object> defaults) private void AppendDefaultValues(Dictionary<string, object> defaults)
@ -121,122 +118,24 @@ namespace Guru
private void FetchAllConfigs(bool immediately = false) private void FetchAllConfigs(bool immediately = false)
{ {
var span = TimeSpan.FromHours(_fetchIntervalHours); var span = TimeSpan.FromHours(_fetchIntervalHours);
bool success = true; if(_isDebug || immediately) span = TimeSpan.Zero;
// if (_isDebug || immediately)
// {
// FetchAllConfigsImmediately();
// return;
// }
if (_isDebug || immediately)
{
span = TimeSpan.Zero;
}
_firebaseRemote.FetchAsync(span) _firebaseRemote.FetchAsync(span)
.ContinueWithOnMainThread(task => .ContinueWithOnMainThread(task =>
{ {
bool success = true;
if (task.IsFaulted || task.IsCanceled) if (task.IsFaulted || task.IsCanceled)
{ {
string res = task.IsFaulted? "Faulted" : "Canceled"; string res = task.IsFaulted? "Faulted" : "Canceled";
LogE($" --- Fetch AllConfigs fails: {res}"); LogE($" --- FetchAllConfigs fails: {res}");
success = false; success = false;
} }
if (success) if (success) OnFetchDataCompleted();
{
_firebaseRemote.ActivateAsync() OnFetchCompleted?.Invoke(success);
.ContinueWithOnMainThread(task =>
{
if (task.IsFaulted || task.IsCanceled)
{
success = false;
string res = task.IsFaulted? "Faulted" : "Canceled";
LogE($" --- Active AllConfigs fails: {res}");
}
else
{
success = true;
}
LogI($"[REMOTE] --- ActiveAsync success: {success}");
OnFetchDataCompleted();
OnFetchCompleted?.Invoke(success);
});
}
else
{
OnFetchDataCompleted();
OnFetchCompleted?.Invoke(success);
}
}); });
} }
/// <summary>
/// 立即拉取所有的配置
/// </summary>
private void FetchAllConfigsImmediately()
{
bool success = true;
_firebaseRemote.FetchAndActivateAsync()
.ContinueWithOnMainThread(task =>
{
if (task.IsFaulted || task.IsCanceled)
{
success = false;
string res = task.IsFaulted? "Faulted" : "Canceled";
LogE($" --- Fetch AllConfigs fails: {res}");
}
else
{
success = true;
LogI($"{Tag} --- FetchAndActivateAsync success");
}
LogI($"{Tag} --- FetchAndActivateAsync success: {success}");
OnFetchDataCompleted();
OnFetchCompleted?.Invoke(success);
});
}
/// <summary>
/// 获取值更新回调
/// </summary>
/// <param name="sender"></param>
/// <param name="updateEvent"></param>
private void OnConfigUpdatedHandler(object sender, ConfigUpdateEventArgs updateEvent)
{
if (updateEvent.Error != RemoteConfigError.None)
{
Debug.LogError($"{Tag} --- RemoteConfigError: {updateEvent.Error}");
}
else
{
_firebaseRemote.ActivateAsync().ContinueWithOnMainThread(task =>
{
if (task.IsCompleted)
{
if (updateEvent.UpdatedKeys != null)
{
var updateKeys = updateEvent.UpdatedKeys.ToArray();
string key = "";
int i = 0;
int count = updateEvent.UpdatedKeys.Count();
while (i < count)
{
key = updateEvent.UpdatedKeys.ElementAt(i);
if (_changeEvents.TryGetValue(updateKeys[i], out var callback))
{
callback?.Invoke(key, _firebaseRemote.GetValue(key).StringValue);
}
i++;
}
}
}
});
}
}
#endregion #endregion

View File

@ -1,7 +1,7 @@
{ {
"name": "com.guru.unity.sdk.core", "name": "com.guru.unity.sdk.core",
"displayName": "Guru SDK Core", "displayName": "Guru SDK Core",
"version": "1.1.0", "version": "2.3.1",
"description": "Guru SDK core for Unity developers", "description": "Guru SDK core for Unity developers",
"unity": "2021.3", "unity": "2021.3",
"author":{ "author":{
@ -14,6 +14,6 @@
"com.unity.editorcoroutines": "1.0.0", "com.unity.editorcoroutines": "1.0.0",
"com.unity.mobile.notifications": "2.2.2", "com.unity.mobile.notifications": "2.2.2",
"com.unity.mobile.android-logcat": "1.3.2", "com.unity.mobile.android-logcat": "1.3.2",
"com.unity.purchasing": "4.12.2" "com.unity.purchasing": "4.10.0"
} }
} }