com.guru.unity.sdk.core/Runtime/GuruCore/Runtime/Analytics/Analytics.TemplateDefine.cs

710 lines
24 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using JetBrains.Annotations;
namespace Guru
{
using System;
using System.Collections.Generic;
using Facebook.Unity;
using UnityEngine;
//游戏通用模版打点定义
public static partial class Analytics
{
#region 游戏通用打点
/// <summary>
/// 当玩家在游戏中升级时触发
/// </summary>
/// <param name="level">level 等级从1开始 标准点</param>
/// <param name="character">升级的角色,如果没有可不选</param>
/// <param name="extra"></param>
public static void LevelUp(int level, string character, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
{ ParameterLevel, level },
{ ParameterCharacter, character }
};
if (extra != null) dict.AddRange(extra, isOverride:true);
LogEvent(EventLevelUp, dict);
}
/// <summary>
/// 玩家已完成解锁成就时触发。
/// </summary>
/// <param name="achievementID">这里的成就ID值项目方自行定义</param>
public static void UnlockAchievement(string achievementID, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
{ ParameterAchievementId, achievementID },
};
if (extra != null) dict.AddRange(extra, isOverride:true);
LogEvent(EventUnlockAchievement, dict);
}
/// <summary>
/// 玩家已开始挑战某个关卡时触发。
/// </summary>
/// <param name="levelName">关卡名称</param>
/// <param name="level">关卡数</param>
[Obsolete("Obsolete method, please use <LogLevelStart> instead. will be discard in next version.")]
public static void LevelStart(int level)
{
LogEvent(EventLevelStart, new Dictionary<string, object>()
{
{ ParameterLevel, level },
{ ParameterItemCategory, "main" },
});
}
/// <summary>
/// 玩家已开始挑战某个关卡时触发。
/// </summary>
/// <param name="level">关卡数</param>
/// <param name="levelName">关卡名称</param>
/// <param name="levelType">关卡类型</param>
/// <param name="itemId">关卡配置表 ID</param>
/// <param name="startType">启动方式</param>
/// <param name="isReplay">是否是重玩</param>
/// <param name="extra">额外数据</param>
public static void LogLevelStart(int level, string levelName,
string levelType = "main", string itemId = "", string startType = "play", bool isReplay = false,
Dictionary<string, object> extra = null)
{
Dictionary<string, object> dict = new Dictionary<string, object>()
{
{ ParameterLevel, level },
{ ParameterLevelName, levelName },
{ ParameterItemCategory, levelType },
{ ParameterStartType, startType },
{ ParameterReplay, isReplay ? "true" : "false" },
};
if(!string.IsNullOrEmpty(itemId))
dict[ParameterItemId] = itemId;
if (extra != null)
{
dict.AddRange(extra, isOverride:true);
}
LogEvent(EventLevelStart, dict);
}
/// <summary>
/// 关卡结束(Firebase标准事件)
/// </summary>
/// <param name="level"></param>
/// <param name="result"></param>
/// <param name="levelName"></param>
/// <param name="levelType"></param>
/// <param name="itemId"></param>
/// <param name="duration"></param>
/// <param name="step"></param>
/// <param name="score"></param>
/// <param name="extra"></param>
public static void LogLevelEnd(int level, string result,
string levelName = "", string levelType = "main", string itemId = "",
int duration = 0, int? step = null, int? score = null, Dictionary<string, object> extra = null)
{
bool isSuccess = result.Equals("success");
var dict = new Dictionary<string, object>()
{
[ParameterLevel] = level,
[ParameterLevelName] = levelName,
[ParameterItemCategory] = levelType,
[ParameterSuccess] = isSuccess ? "true" : "false",
[ParameterResult] = result,
[ParameterDuration] = duration
};
if(!string.IsNullOrEmpty(itemId))
dict[ParameterItemId] = itemId;
if(step != null)
dict[ParameterStep] = step.Value;
if(score != null)
dict[ParameterScore] = score.Value;
if(extra != null) dict.AddRange(extra, isOverride:true);
LogEvent(EventLevelEnd, dict);
// if (isSuccess)
// {
// int lv = BPlay;
// if (lv == 0) lv = level;
// LevelEndSuccess(lv, levelType, itemId);
// }
}
/// <summary>
/// 新用户通过第几关仅记录前n关,根据项目自行确定,不区分关卡类型)[买量用]
/// </summary>
/// <param name="level">总计完成的管卡数 (b_play)</param>
/// <param name="extra"></param>
public static void LevelEndSuccess( int level, Dictionary<string, object> extra = null)
{
if (level > GuruSettings.Instance.AnalyticsSetting.LevelEndSuccessNum)
return;
string eventName = $"level_end_success_{level}";
if (extra == null)
{
extra = new Dictionary<string, object>()
{
["level"] = level,
};
}
LogEvent(eventName, extra, new EventSetting()
{
EnableFirebaseAnalytics = true,
EnableFacebookAnalytics = true,
EnableAdjustAnalytics = true
});
}
/// <summary>
/// 第一次通关打点
/// </summary>
public static void LevelFirstEnd(string levelType, string levelName, int level,
string result, int duration = 0, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
{ ParameterItemCategory, levelType },
{ ParameterLevelName, levelName },
{ ParameterLevel, level },
{ ParameterSuccess, result == "success" ? 1 : 0 },
{ ParameterResult, result },
};
if (duration > 0)
dict[ParameterDuration] = duration;
if (extra != null)
dict.AddRange(extra, isOverride: true);
LogEvent(EventLevelFirstEnd, dict);
}
#endregion
#region Coins
/// <summary>
/// 当用户获取了虚拟货币(金币、宝石、代币等)时触发
/// </summary>
/// <param name="virtual_currency_name">虚拟货币的名称</param>
/// <param name="value">虚拟货币的数量</param>
/// <param name="item_category">金币获取的方式通过IAP购买的方式固定使用<iap_buy>参数值,其余场景自行定义。</param>
/// <param name="balance">玩家当前剩余的虚拟货币数量</param>
/// <param name="sku">购买商品的product_id(购买时传参)</param>
public static void EarnVirtualCurrency(string virtual_currency_name, int value, string item_category,
int balance, string sku, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
[ParameterVirtualCurrencyName] = virtual_currency_name,
[ParameterValue] = value,
[ParameterItemCategory] = item_category,
["balance"] = balance,
["sku"] = sku,
};
if(extra != null) dict.AddRange(extra, isOverride: true);
LogEvent(EventEarnVirtualCurrency, dict);
}
/// <summary>
/// 当用户支出了虚拟货币(金币、宝石、代币等)时触发
/// </summary>
/// <param name="virtual_currency_name">虚拟货币的名称</param>
/// <param name="value">虚拟货币的数量</param>
/// <param name="item_category">虚拟货币花费场景</param>
/// <param name="balance">玩家当前剩余的虚拟货币数量</param>
public static void SpendVirtualCurrency(string virtual_currency_name, int value, string item_category,
int balance, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
[ParameterVirtualCurrencyName] = virtual_currency_name,
[ParameterValue] = value,
[ParameterItemCategory] = item_category,
["balance"] = balance,
};
if(extra != null) dict.AddRange(extra, isOverride: true);
LogEvent(EventSpendVirtualCurrency, dict);
}
#endregion
#region HP
/// <summary>
/// 体力变化时触发
/// </summary>
/// <param name="item_category">体力变化的场景</param>
/// <param name="hp_before">本次行为变化前体力</param>
/// <param name="hp">本次行为带来的体力</param>
/// <param name="hp_after">本次行为变化后体力</param>
public static void HitPoints(string item_category, int hp_before, int hp, int hp_after, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
[ParameterItemCategory] = item_category,
["hp_before"] = hp_before,
["hp"] = hp,
["hp_after"] = hp_after,
};
if(extra != null) dict.AddRange(extra, isOverride: true);
LogEvent("hit_points", dict);
}
#endregion
#region Tch 太极打点逻辑
private static double _tch001MaxValue = 5.0d; // 预设保护值, 如果大于这个值, 算作异常上报
private static double _tch001TargetValue = 0.01d;
public static double Tch001TargetValue => _tch001TargetValue; // 太极 001 设定值
private static double _tch02TargetValue = 0.20d;
public static double Tch02TargetValue => _tch02TargetValue; // 太极 02 设定值
public static string IAPPlatform
{
get
{
#if UNITY_IOS
return "appstore";
#endif
return "google_play";
}
}
public static bool EnableTch02Event { get; set; } = false; // 是否使用太极02事件(请手动开启)
/// <summary>
/// 太极001 IAP收入
/// 每发生一次iap收入触发一次该事件value值为本次iap的收入值
/// </summary>
/// <param name="value">中台返回地收入值</param>
/// <param name="productId"></param>
/// <param name="orderId"></param>
/// <param name="orderType"></param>
/// <param name="timestamp"></param>
public static void Tch001IAPRev(double value, string productId, string orderId, string orderType, string timestamp)
{
TchRevEvent(EventTchAdRev001Impression, IAPPlatform, value, orderType, productId, orderId, timestamp);
}
/// <summary>
/// 太极02 IAP 收入打点
/// 发生一次iap收入触发一次该事件value值为本次iap的收入值
/// </summary>
/// <param name="value"></param>
/// <param name="productId"></param>
/// <param name="orderId"></param>
/// <param name="orderType"></param>
/// <param name="timestamp"></param>
// public static void Tch02IAPRev(double value, string productId, string orderId, string orderType, string timestamp)
public static void Tch02IAPRev(double value, string productId, string orderId, string orderType, string timestamp)
{
if (!EnableTch02Event) return;
TchRevEvent(EventTchAdRev02Impression, IAPPlatform, value, orderType, productId, orderId, timestamp);
}
/// <summary>
/// "1.广告收入累计超过0.01美元,触发一次该事件,重新清零后,开始下一次累计计算;
/// </summary>
/// <param name="value"></param>
public static void Tch001ADRev(double value)
{
if (value > _tch001MaxValue)
{
TchAdAbnormalEvent(value); // 上报异常值
return;
}
// if (value < Tch001TargetValue) value = Tch001TargetValue; // TCH广告添加0值校验修复, 不得小于0.01
TchRevEvent(EventTchAdRev001Impression, AdMAX, value);
if(EnableTch02Event) return; // 如果使用了太极02 则不做FB上报
//FB标准购买事件
FBPurchase(value, USD, "ads", AdMAX);
}
/// <summary>
/// "1.5 广告收入累计超过0.2美元,触发一次该事件,重新清零后,开始下一次累计计算;
/// </summary>
/// <param name="value"></param>
public static void Tch02ADRev(double value)
{
if (!EnableTch02Event) return;
// if (value < Tch02TargetValue) value = Tch02TargetValue; // TCH广告添加0值校验修复
TchRevEvent(EventTchAdRev02Impression, AdMAX, value);
//FB标准购买事件
FBPurchase(value, USD, "ads", AdMAX);
}
/// <summary>
/// 太极事件点位上报
/// </summary>
/// <param name="evtName"></param>
/// <param name="platform"></param>
/// <param name="value"></param>
/// <param name="orderType"></param>
/// <param name="productId"></param>
/// <param name="orderId"></param>
/// <param name="timestamp"></param>
private static void TchRevEvent(string evtName, string platform, double value,
string orderType = "", string productId = "", string orderId = "", string timestamp = "")
{
var data = new Dictionary<string, dynamic>()
{
{ ParameterAdPlatform, platform },
{ ParameterValue, value },
{ ParameterCurrency, USD },
};
//--------- Extra data for IAP receipt ---------------
if(!string.IsNullOrEmpty(orderType)) data["order_type"] = orderType;
if(!string.IsNullOrEmpty(productId)) data["product_id"] = productId;
if(!string.IsNullOrEmpty(orderId)) data["order_id"] = orderId;
if(!string.IsNullOrEmpty(timestamp)) data["trans_ts"] = timestamp;
//--------- Extra data for IAP receipt ---------------
LogEvent(evtName, data);
}
/// <summary>
/// Facebook 支付上报
/// </summary>
/// <param name="revenue"></param>
/// <param name="currency"></param>
/// <param name="type"></param>
/// <param name="platfrom"></param>
public static void FBPurchase(float revenue, string currency, string type, string platfrom)
{
var data = new Dictionary<string, object>()
{
{ AppEventParameterName.Currency, USD },
{ AppEventParameterName.ContentType, type },
{ ParameterAdPlatform, platfrom },
};
FBService.LogPurchase(revenue, currency, data);
}
public static void FBPurchase(double revenue, string currency, string type, string platfrom)
=> FBPurchase((float)revenue, currency, type, platfrom);
/// <summary>
/// Google ARO买量点
/// </summary>
/// <param name="impressionData">广告收入数据</param>
/// <param name="platform">广告平台</param>
/// <a href="https://docs.google.com/spreadsheets/d/1lFWLeOGJgq34QDBTfl6OpNh7MoI37ehGrhdbxlOrJgs/edit#gid=983654222"></a>
/// <li>
/// value double eg0.002
/// currency string USD(只传美元)
/// ad_platform string "MAX | ADMOB | FACEBOOK"
/// ad_source string 广告来源
/// ad_format string 广告格式
/// ad_unit_name string 广告位名称
/// ad_creative_id string 广告素材id
/// </li>
public static void ADImpression(MaxSdkBase.AdInfo impressionData, string platform = "")
{
if (string.IsNullOrEmpty(platform)) platform = AdMAX;
double revenue = impressionData.Revenue;
LogEvent(EventAdImpression, new Dictionary<string, dynamic>()
{
[ParameterValue] = revenue,
[ParameterCurrency] = USD,
[ParameterAdPlatform] = platform,
[ParameterAdSource] = impressionData.NetworkName,
[ParameterAdFormat] = impressionData.AdFormat,
[ParameterAdUnitName] = impressionData.AdUnitIdentifier,
[ParameterAdCreativeId] = impressionData.CreativeIdentifier,
});
}
public static void TchAdAbnormalEvent(double value)
{
LogEvent(EventTchAdRevAbnormal, new Dictionary<string, dynamic>()
{
{ ParameterAdPlatform, AdMAX },
{ ParameterCurrency, USD },
{ ParameterValue, value },
});
}
#endregion
#region Analytics Game IAP 游戏内购打点
/// <summary>
/// 当付费页面打开时调用iap_imp
/// </summary>
/// <param name="scene">界面跳转的来源</param>
/// <param name="extra">扩展参数</param>
public static void IAPImp(string scene, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
{ ParameterItemCategory, scene },
};
if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra);
LogEvent(EventIAPImp, dict);
}
/// <summary>
/// 当付费页面关闭时调用iap_close
/// </summary>
/// <param name="scene"></param>
/// <param name="extra"></param>
public static void IAPClose(string scene, Dictionary<string, object> extra = null)
{
var dict = new Dictionary<string, object>()
{
{ ParameterItemCategory, scene },
};
if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra);
LogEvent(EventIAPClose, dict);
}
/// <summary>
/// 点击付费按钮时调用 (iap_clk)
/// </summary>
/// <param name="scene">支付场景</param>
/// <param name="productId">道具的 sku</param>
/// <param name="basePlanId">offer 的 basePlanId</param>
/// <param name="offerId">offer 的 offerId</param>
/// <param name="extra">扩展参数</param>
public static void IAPClick(string scene, string productId, string basePlanId = "", string offerId = "", Dictionary<string, object> extra = null)
{
string sku = productId;
if (!string.IsNullOrEmpty(offerId) && !string.IsNullOrEmpty(basePlanId))
{
sku = $"{productId}:{basePlanId}:{offerId}"; // 上报三连 ID
}
var dict = new Dictionary<string, object>()
{
{ ParameterItemCategory, scene },
{ ParameterItemName, sku },
};
if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra);
LogEvent(EventIAPClick, dict);
}
/// <summary>
/// "app 内弹出的付费引导IAP付费或试用成功打点"
/// </summary>
/// <param name="scene">界面跳转的来源</param>
/// <param name="productId">product id,多个产品用逗号分隔第一个商品id放主推商品id</param>
/// <param name="value">产品的价格</param>
/// <param name="currency">用户的付费币种</param>
/// <param name="orderId">订单 ID</param>
/// <param name="type">付费类型订阅/产品subscription/product</param>
/// <param name="isFree">是否为试用1试用0付费</param>
/// <param name="offerId">若存在 Offer 的话需要上报 OfferID</param>
internal static void IAPRetTrue(string scene, string productId, double value, string currency, string orderId, string type, bool isFree = false, string offerId = "")
{
var dict = new Dictionary<string, object>()
{
{ ParameterItemCategory, scene },
{ ParameterItemName, productId },
{ ParameterProductId, productId }, // new parameter, will replace with item_name
{ ParameterValue, value },
{ ParameterCurrency, currency },
{ "order_id", orderId },
{ "type", type },
{ "isfree", isFree ? 1 : 0 },
};
if(!string.IsNullOrEmpty(offerId))
dict["basePlan"] = offerId;
LogEvent(EventIAPReturnTrue, dict, new EventSetting()
{
EnableFirebaseAnalytics = true,
EnableAdjustAnalytics = true,
});
}
/// <summary>
/// "app 内弹出的付费引导IAP付费或试用失败打点"
/// </summary>
/// <param name="itemCategory">界面跳转的来源</param>
/// <param name="productId">product id,多个产品用逗号分隔第一个商品id放主推商品id</param>
/// <param name="failReason"></param>
internal static void IAPRetFalse(string itemCategory, string productId, string failReason)
{
LogEvent(EventIAPReturnFalse, new Dictionary<string, object>()
{
{ ParameterItemCategory, itemCategory },
{ ParameterItemName, productId },
{ ParameterProductId, productId },
{ ParameterResult, failReason }
});
}
/// <summary>
/// 新用户首次 IAP 付费成功上报 (仅限应用内付费商品,不包含订阅等其它情况)【买量打点】
/// </summary>
/// <param name="itemName">productId 商品ID</param>
/// <param name="value">付费总金额</param>
/// <param name="currency">币种</param>
public static void FirstIAP(string itemName, double value, string currency)
{
LogEvent(EventIAPFirst, new Dictionary<string, object>()
{
{ ParameterItemName, itemName },
{ ParameterValue, value },
{ ParameterCurrency, currency },
});
}
/// <summary>
/// 商品购买成功上报【买量打点】
/// </summary>
/// <param name="productName">商品名称商品ID一样</param>
/// <param name="itemName">productId 商品ID</param>
/// <param name="value">付费总金额</param>
/// <param name="currency">币种</param>
public static void ProductIAP(string productName, string itemName, double value, string currency)
{
// 替换SKU中的 "." -> "_", 比如: "do.a.iapc.coin.100" 转换为 "do_a_iapc_coin_100"
if (productName.Contains(".")) productName = productName.Replace(".", "_");
string eventName = $"iap_{productName}";
LogEvent(eventName, new Dictionary<string, object>()
{
{ ParameterItemName, itemName },
{ ParameterValue, value },
{ ParameterCurrency, currency },
});
}
/// <summary>
/// 支付成功后统一上报所有点位数据
/// </summary>
/// <param name="productId"></param>
/// <param name="usdPrice"></param>
/// <param name="userCurrency"></param>
/// <param name="payPrice"></param>
/// <param name="orderId"></param>
/// <param name="orderType"></param>
/// <param name="orderDate"></param>
/// <param name="scene"></param>
/// <param name="isFree"></param>
public static void ReportIAPSuccessEvent(double usdPrice, string productId, BaseOrderData orderData)
{
string userCurrency = orderData.userCurrency;
double payPrice = orderData.payPrice;
string orderType = orderData.OrderType();
string orderType2 = orderData.OrderTypeII();
string orderId = orderData.orderId;
string orderDate = orderData.payedDate;
string scene = orderData.scene;
bool isFree = orderData.isFree;
string offerId = orderData.offerId;
// TCH 001
Tch001IAPRev(usdPrice, productId, orderId, orderType, orderDate);
// TCH 020
Tch02IAPRev(usdPrice, productId, orderId, orderType, orderDate);
// Facebook Track IAP Purchase
FBPurchase(usdPrice, USD, "iap", IAPPlatform);
if (orderData.orderType == 1)
{
// sub_pruchase : Firebase + Guru + Adjust
SubPurchase(usdPrice, productId, orderId, orderDate);
}
else
{
// iap_purchase : Firebase + Guru + Adjust
IAPPurchase(usdPrice, productId, orderId, orderDate);
}
// IAP Ret true : Firebase + Guru + Adjust
IAPRetTrue(scene, productId, payPrice, userCurrency, orderId, orderType2, isFree, offerId);
}
#endregion
#region IAP_PURCHASE
/// <summary>
/// IAP 内购上报
/// </summary>
/// <param name="value"></param>
/// <param name="productId"></param>
/// <param name="orderId"></param>
/// <param name="orderDate"></param>
public static void IAPPurchase(double value, string productId, string orderId, string orderDate)
{
IAPPurchaseReport(EventIAPPurchase, value, productId, orderId, "IAP", orderDate);
}
public static void SubPurchase(double value, string productId, string orderId, string orderDate)
{
IAPPurchaseReport(EventSubPurchase, value, productId, orderId, "SUB", orderDate);
}
private static void IAPPurchaseReport(string eventName, double value, string productId, string orderId, string orderType, string orderDate)
{
LogEvent(eventName, new Dictionary<string, dynamic>()
{
[ParameterPlatform] = IAPPlatform,
[ParameterValue] = value,
[ParameterCurrency] = USD,
[ParameterProductId] = productId,
["order_id"] = orderId,
["order_type"] = orderType,
["trans_ts"] = orderDate
}, new EventSetting()
{
EnableFirebaseAnalytics = true,
EnableAdjustAnalytics = true,
});
}
#endregion
#region 中台异常打点
/// <summary>
/// 中台异常打点
/// </summary>
/// <param name="data"></param>
public static void LogDevAudit(Dictionary<string, dynamic> data)
{
if (data == null) return;
data["country"] = IPMConfig.IPM_COUNTRY_CODE;
data["network"] = Application.internetReachability.ToString();
LogEvent(EventDevAudit, data, new EventSetting() { EnableFirebaseAnalytics = true });
}
#endregion
}
}