Tracker.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. using System;
  2. using System.Collections.Generic;
  3. using TapSDK.Core.Standalone;
  4. using System.Threading.Tasks;
  5. using UnityEngine;
  6. using TapSDK.Core.Internal.Utils;
  7. using TapSDK.Core.Internal.Log;
  8. namespace TapSDK.Core.Standalone.Internal {
  9. public class Tracker {
  10. private Dictionary<string, object> customProps;
  11. private Dictionary<string, object> basicProps;
  12. private Dictionary<string, object> commonProps;
  13. private EventSender sender;
  14. private IDynamicProperties dynamicPropsDelegate;
  15. private static string session_uuid = generateUUID();
  16. public void Init() {
  17. basicProps = new Dictionary<string, object>();
  18. commonProps = new Dictionary<string, object>();
  19. var coreOptions = TapCoreStandalone.coreOptions;
  20. customProps = Json.Deserialize(coreOptions.propertiesJson) as Dictionary<string, object>;
  21. sender = new EventSender();
  22. InitBasicProps();
  23. Dictionary<string, object> props = new Dictionary<string, object>(basicProps);
  24. TrackEvent(Constants.DEVICE_LOGIN, props, true);
  25. }
  26. public void AddCommonProperty(string key, object value) {
  27. commonProps[key] = value;
  28. }
  29. public void AddCommon(Dictionary<string, object> properties) {
  30. foreach (KeyValuePair<string, object> kv in properties) {
  31. commonProps[kv.Key] = kv.Value;
  32. }
  33. }
  34. public void ClearCommonProperty(string key) {
  35. commonProps.Remove(key);
  36. }
  37. public void ClearCommonProperties(string[] keys) {
  38. foreach (string key in keys) {
  39. commonProps.Remove(key);
  40. }
  41. }
  42. public void ClearAllCommonProperties() {
  43. commonProps.Clear();
  44. }
  45. public void RegisterDynamicPropsDelegate(IDynamicProperties dynamicPropsDelegate) {
  46. this.dynamicPropsDelegate = dynamicPropsDelegate;
  47. }
  48. public void LogPurchasedEvent(string orderID, string productName, Int64 amount, string currencyType, string paymentMethod, string properties){
  49. var prop = Json.Deserialize(properties) as Dictionary<string, object>;
  50. var data = new Dictionary<string, object> {
  51. { "order_id", orderID },
  52. { "product", productName },
  53. { "amount", amount },
  54. { "currency_type", currencyType },
  55. { "payment", paymentMethod }
  56. };
  57. if (prop != null) {
  58. foreach (KeyValuePair<string, object> kv in prop) {
  59. data[kv.Key] = kv.Value;
  60. }
  61. }
  62. TrackEvent("charge", data);
  63. }
  64. /// <summary>
  65. /// 上报事件
  66. /// </summary>
  67. /// <param name="name"></param>
  68. /// <param name="properties"></param>
  69. /// <param name="isAutomationlly">是否为自动事件</param>
  70. public void TrackEvent(string name, Dictionary<string, object> properties = null, bool isAutomationlly = false) {
  71. Dictionary<string, object> props = new Dictionary<string, object>(basicProps);
  72. if (commonProps != null) {
  73. foreach (KeyValuePair<string, object> kv in commonProps) {
  74. props[kv.Key] = kv.Value;
  75. }
  76. }
  77. Dictionary<string, object> dynamicProps = dynamicPropsDelegate?.GetDynamicProperties();
  78. TapLog.Log("dynamicProps: " + dynamicProps);
  79. if (dynamicProps != null) {
  80. foreach (KeyValuePair<string, object> kv in dynamicProps) {
  81. props[kv.Key] = kv.Value;
  82. }
  83. }
  84. if (name == Constants.DEVICE_LOGIN) { // Device login 事件带上初始化时的自定义属性
  85. TapLog.Log("customProps: " + customProps);
  86. if (customProps != null) {
  87. foreach (KeyValuePair<string, object> kv in customProps) {
  88. props[kv.Key] = kv.Value;
  89. }
  90. }
  91. }
  92. props["t_log_id"] = generateUUID();
  93. // 时间戳,毫秒级
  94. props["timestamp"] = DateTimeOffset.Now.ToUnixTimeMilliseconds();
  95. var open_id = OpenID;
  96. if (!string.IsNullOrWhiteSpace(open_id)) {
  97. props["open_id"] = open_id;
  98. }
  99. TapLog.Log("properties: " + properties);
  100. if (properties != null) {
  101. foreach (KeyValuePair<string, object> kv in properties) {
  102. props[kv.Key] = kv.Value;
  103. }
  104. }
  105. props["is_automatically_log"] = isAutomationlly ? "true" : "false";
  106. var language = getServerLanguage();
  107. props["sdk_locale"] = language;
  108. props["lang_system"] = DeviceInfo.GetLanguage();
  109. Dictionary<string, object> data = new Dictionary<string, object> {
  110. { "client_id", TapCoreStandalone.coreOptions.clientId },
  111. { "type", "track" },
  112. { "name", name },
  113. { "device_id", Identity.DeviceId },
  114. { "properties", props },
  115. };
  116. if (!string.IsNullOrWhiteSpace(TapCoreStandalone.User.Id)) {
  117. data["user_id"] = TapCoreStandalone.User.Id;
  118. }
  119. sender.Send(data);
  120. }
  121. /// <summary>
  122. /// 上报设备属性变化
  123. /// </summary>
  124. /// <param name="type"></param>
  125. /// <param name="properties"></param>
  126. public void TrackDeviceProperties(string type, Dictionary<string, object> properties) {
  127. if (string.IsNullOrWhiteSpace(Identity.DeviceId)) {
  128. TapLog.Error("DeviceId is NULL.");
  129. return;
  130. }
  131. Dictionary<string, object> baseProps = new Dictionary<string, object> {
  132. { "device_id", Identity.DeviceId }
  133. };
  134. _ = TrackPropertiesAsync(type, baseProps, properties);
  135. }
  136. /// <summary>
  137. /// 上报玩家属性变化
  138. /// </summary>
  139. public void TrackUserProperties(string type, Dictionary<string, object> properties) {
  140. string userId = TapCoreStandalone.User.Id;
  141. if (string.IsNullOrWhiteSpace(userId)) {
  142. TapLog.Error("UserId is NULL.");
  143. return;
  144. }
  145. Dictionary<string, object> baseProps = new Dictionary<string, object> {
  146. { "user_id", userId }
  147. };
  148. _ = TrackPropertiesAsync(type, baseProps, properties);
  149. }
  150. private Task TrackPropertiesAsync(string type,
  151. Dictionary<string, object> basicProps, Dictionary<string, object> properties)
  152. {
  153. if (!IsInitialized) {
  154. return Task.CompletedTask;
  155. }
  156. if (properties == null) {
  157. properties = new Dictionary<string, object>();
  158. }
  159. properties["sdk_version"] = TapTapSDK.Version;
  160. Dictionary<string, object> data = new Dictionary<string, object>(basicProps) {
  161. { "client_id", TapCoreStandalone.coreOptions.clientId },
  162. { "type", type },
  163. { "properties", properties }
  164. };
  165. sender.Send(data);
  166. return Task.CompletedTask;
  167. }
  168. private void InitBasicProps() {
  169. DeviceInfo.GetMacAddress(out string macList, out string firstMac);
  170. basicProps = new Dictionary<string, object> {
  171. { "os", OS },
  172. { "md", SystemInfo.deviceModel },
  173. { "sv", SystemInfo.operatingSystem },
  174. { "pn", "TapSDK" },
  175. { "tapsdk_project", "TapSDKCore" },
  176. { "session_uuid", session_uuid },
  177. { "install_uuid", Identity.InstallationId },
  178. { "persist_uuid", Identity.PersistentId },
  179. { "ram", DeviceInfo.RAM },
  180. { "rom", "0" },
  181. { "width", Screen.currentResolution.width },
  182. { "height", Screen.currentResolution.height },
  183. { "provider", "unknown" },
  184. { "app_version", TapCoreStandalone.coreOptions.gameVersion ?? Application.version },
  185. { "sdk_version", TapTapSDK.Version },
  186. { "network_type", Network },
  187. { "channel", TapCoreStandalone.coreOptions.channel },
  188. { "mac_list", macList },
  189. { "first_mac", firstMac },
  190. { "device_id5", DeviceInfo.GetLaunchUniqueID() }
  191. };
  192. }
  193. private string OS {
  194. get {
  195. switch (SystemInfo.operatingSystemFamily) {
  196. case OperatingSystemFamily.Windows:
  197. return "Windows";
  198. case OperatingSystemFamily.MacOSX:
  199. return "Mac";
  200. case OperatingSystemFamily.Linux:
  201. return "Linux";
  202. default:
  203. return "Unknown";
  204. }
  205. }
  206. }
  207. public static string getServerLanguage() {
  208. // 将 TapCoreStandalone.coreOptions.preferredLanguage 转成 zh_TW/en/zh_CN/en_GB/jp/fil 等格式
  209. switch (TapCoreStandalone.coreOptions.preferredLanguage) {
  210. case TapTapLanguageType.zh_Hans:
  211. return "zh_CN";
  212. case TapTapLanguageType.zh_Hant:
  213. return "zh_TW";
  214. case TapTapLanguageType.en:
  215. return "en_US";
  216. case TapTapLanguageType.ja:
  217. return "ja_JP";
  218. case TapTapLanguageType.ko:
  219. return "ko_KR";
  220. case TapTapLanguageType.th:
  221. return "th_TH";
  222. case TapTapLanguageType.id:
  223. return "id_ID";
  224. case TapTapLanguageType.de:
  225. return "de";
  226. case TapTapLanguageType.es:
  227. return "es_ES";
  228. case TapTapLanguageType.fr:
  229. return "fr";
  230. case TapTapLanguageType.pt:
  231. return "pt_PT";
  232. case TapTapLanguageType.ru:
  233. return "ru";
  234. case TapTapLanguageType.tr:
  235. return "tr";
  236. case TapTapLanguageType.vi:
  237. return "vi_VN";
  238. default:
  239. // 默认cn返回简体中文,Overseas返回英文
  240. return TapCoreStandalone.coreOptions.region == TapTapRegionType.CN ? "zh_CN" : "en_US";
  241. }
  242. }
  243. private string Network {
  244. get {
  245. switch (Application.internetReachability) {
  246. case NetworkReachability.ReachableViaCarrierDataNetwork:
  247. return "3";
  248. case NetworkReachability.ReachableViaLocalAreaNetwork:
  249. return "2";
  250. default:
  251. return "Unknown";
  252. }
  253. }
  254. }
  255. private bool IsInitialized {
  256. get {
  257. if (string.IsNullOrWhiteSpace(TapCoreStandalone.coreOptions.clientId)) {
  258. TapLog.Error("MUST be initialized.");
  259. return false;
  260. }
  261. return true;
  262. }
  263. }
  264. private static string generateUUID() {
  265. return Guid.NewGuid().ToString();
  266. }
  267. private static string OpenID {
  268. get {
  269. IOpenIDProvider provider = BridgeUtils.CreateBridgeImplementation(typeof(IOpenIDProvider),
  270. "TapSDK.Login") as IOpenIDProvider;
  271. return provider?.GetOpenID();
  272. }
  273. }
  274. public interface IDynamicProperties {
  275. Dictionary<string, object> GetDynamicProperties();
  276. }
  277. }
  278. }