Compare commits
25 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
7e499aa26c | |
|
|
a67185679b | |
|
|
23eb7ff7b4 | |
|
|
6d3e94cf2f | |
|
|
6b02f619ce | |
|
|
11002aaccd | |
|
|
88d29fe2f2 | |
|
|
15aa840061 | |
|
|
3b5a242f9f | |
|
|
561d351b73 | |
|
|
d1dba297a7 | |
|
|
67abd081c8 | |
|
|
400498af17 | |
|
|
50c5627ac2 | |
|
|
ef547caba9 | |
|
|
345b4ac971 | |
|
|
ff5f2df4c4 | |
|
|
85c8058158 | |
|
|
6d5bc2c3a4 | |
|
|
edf6214cea | |
|
|
c88de190a1 | |
|
|
dc991efbf3 | |
|
|
515c875ee8 | |
|
|
2aad845378 | |
|
|
c3b77622d9 |
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
|
||||
namespace Guru.Editor
|
||||
{
|
||||
using System.Linq;
|
||||
|
|
@ -14,17 +16,21 @@ namespace Guru.Editor
|
|||
/// </summary>
|
||||
public partial class AppBuilder
|
||||
{
|
||||
public static int AndroidTargetSdkVersion = 33;
|
||||
public static string IOSTargetOSVersion = "13.0";
|
||||
public static string GuruIOSTeamId = "39253T242A";
|
||||
public static string GuruKeystoreName => "guru_key.jks";
|
||||
public static string GuruKeystorePass => "guru0622";
|
||||
public static string GuruAliasName => "guru";
|
||||
public static string GuruAliasPass => "guru0622";
|
||||
public static string GuruKeystorePath => Application.dataPath + $"/Plugins/Android/{GuruKeystoreName}";
|
||||
public static string ProguardName => "proguard-user.txt";
|
||||
public static string ProguardPath => Application.dataPath + $"/Plugins/Android/{ProguardName}";
|
||||
public static string OutputDirName => "BuildOutput";
|
||||
private const int DefaultAndroidTargetSdkVersion = 34;
|
||||
private const string IOSTargetOSVersion = "13.0";
|
||||
private const string GuruIOSTeamId = "39253T242A";
|
||||
private const string GuruKeystoreName = "guru_key.jks";
|
||||
private const string GuruKeystorePass = "guru0622";
|
||||
private const string GuruAliasName = "guru";
|
||||
private const string GuruAliasPass = "guru0622";
|
||||
|
||||
private const string UnityGradlePath_2021_3_41 =
|
||||
"/Applications/Unity/Hub/Editor/2021.3.41f1/PlaybackEngines/AndroidPlayer/Tools/gradle";
|
||||
|
||||
private static string GuruKeystorePath => Application.dataPath + $"/Plugins/Android/{GuruKeystoreName}";
|
||||
private static string ProguardName => "proguard-user.txt";
|
||||
private static string ProguardPath => Application.dataPath + $"/Plugins/Android/{ProguardName}";
|
||||
private static string OutputDirName => "BuildOutput";
|
||||
|
||||
#region 构建接口
|
||||
|
||||
|
|
@ -70,11 +76,14 @@ namespace Guru.Editor
|
|||
SwitchBuildPlatform(BuildTarget.Android);
|
||||
// 打包通用设置
|
||||
ChangeBuildPlayerCommonSetting(buildParam, BuildTargetGroup.Android);
|
||||
// Set GradlePath
|
||||
SetGradlePath();
|
||||
|
||||
var isDebug = !buildParam.IsBuildRelease;
|
||||
var useMinify = buildParam.AndroidUseMinify;
|
||||
var buildNumber= GetBuildNumberString(BuildTarget.Android);
|
||||
if(buildParam.AutoSetBuildNumber) buildNumber = ChangeBuildNumber(BuildTarget.Android);
|
||||
var androidTargetVersion = buildParam.AndroidTargetVersion == 0 ? DefaultAndroidTargetSdkVersion : buildParam.AndroidTargetVersion;
|
||||
if (buildParam.AutoSetBuildNumber) buildNumber = ChangeBuildNumber(BuildTarget.Android);
|
||||
|
||||
// 保存版本信息
|
||||
SaveBuildVersion(buildParam.BuildVersion, buildNumber);
|
||||
|
|
@ -90,7 +99,6 @@ namespace Guru.Editor
|
|||
PlayerSettings.muteOtherAudioSources = false;
|
||||
// ---- 开启 Minify 后需要配置 proguard-user.txt 文件 ----
|
||||
if (useMinify) DeployProguardTxt();
|
||||
PlayerSettings.Android.minifyWithR8 = useMinify;
|
||||
PlayerSettings.Android.minifyRelease = useMinify;
|
||||
PlayerSettings.Android.minifyDebug = useMinify;
|
||||
// ---- 部署 Guru 专用的 Keystore ----
|
||||
|
|
@ -113,10 +121,9 @@ namespace Guru.Editor
|
|||
PlayerSettings.Android.keyaliasPass = buildParam.AndroidAliasPass;
|
||||
}
|
||||
|
||||
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARMv7 | AndroidArchitecture.ARM64; //只构建 armv7 和 arm64
|
||||
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARMv7 | AndroidArchitecture.ARM64; // 构建 armv7, arm64
|
||||
PlayerSettings.Android.minSdkVersion = AndroidSdkVersions.AndroidApiLevel22;
|
||||
if (buildParam.AndroidTargetVersion > 0) AndroidTargetSdkVersion = buildParam.AndroidTargetVersion;
|
||||
PlayerSettings.Android.targetSdkVersion = (AndroidSdkVersions)AndroidTargetSdkVersion; // 默认设置API为33
|
||||
PlayerSettings.Android.targetSdkVersion = (AndroidSdkVersions)androidTargetVersion; // 设置 API Version
|
||||
|
||||
//打包
|
||||
string symbolDefine = buildParam.IsBuildRelease ? GameDefine.MACRO_RELEASE : GameDefine.MACRO_DEBUG;
|
||||
|
|
@ -142,7 +149,18 @@ namespace Guru.Editor
|
|||
return apkPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
private static void SetGradlePath()
|
||||
{
|
||||
#if UNITY_ANDROID && UNITY_2021_3_41
|
||||
if (Directory.Exists(UnityGradlePath_2021_3_41))
|
||||
{
|
||||
UnityEditor.Android.AndroidExternalToolsSettings.gradlePath = UnityGradlePath_2021_3_41;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 部署 Guru 专用的 Keystore
|
||||
/// </summary>
|
||||
private static bool DeployAndroidKeystore()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
|
||||
#if UNITY_ANDROID
|
||||
namespace Guru
|
||||
{
|
||||
|
|
@ -13,7 +16,8 @@ namespace Guru
|
|||
/// Android混淆器内容填充
|
||||
/// 于应用构建前执行
|
||||
/// </summary>
|
||||
public class UserProguardHelper: IPreprocessBuildWithReport
|
||||
// public class UserProguardHelper: IPreprocessBuildWithReport
|
||||
public class UserProguardHelper
|
||||
{
|
||||
public int callbackOrder { get; } = 0;
|
||||
public void OnPreprocessBuild(BuildReport report)
|
||||
|
|
@ -27,7 +31,6 @@ namespace Guru
|
|||
string proguardPath = $"{Application.dataPath}/Plugins/Android/proguard-user.txt";
|
||||
if (File.Exists(proguardPath))
|
||||
{
|
||||
List<string> keeps = new List<string>();
|
||||
DirectoryInfo dir = new DirectoryInfo(Application.dataPath);
|
||||
string raw = File.ReadAllText(proguardPath);
|
||||
|
||||
|
|
@ -41,36 +44,40 @@ namespace Guru
|
|||
}
|
||||
|
||||
// Debug.Log($"--- Proguard Files: {files.Length}");
|
||||
|
||||
ProguardItemBuilder builder = new ProguardItemBuilder();
|
||||
|
||||
string[] lens = null;
|
||||
string l = "";
|
||||
var allItems = new List<ProguardItem>(30);
|
||||
|
||||
string[] lines = null;
|
||||
for (int i = 0; i < files.Count; i++)
|
||||
{
|
||||
lens = File.ReadAllLines(files[i].FullName);
|
||||
foreach (var s in lens)
|
||||
{
|
||||
l = s.TrimStart();
|
||||
if(string.IsNullOrEmpty(l)) continue;
|
||||
if(raw.Contains(l)) continue;
|
||||
keeps.Add(l);
|
||||
Debug.Log($"--- ✏️ Apply: [ {l} ]");
|
||||
}
|
||||
lines = File.ReadAllLines(files[i].FullName);
|
||||
var items = builder.BuildItemsFormLines(lines);
|
||||
if(items != null && items.Count > 0) allItems.AddRange(items);
|
||||
}
|
||||
|
||||
|
||||
List<string> finalLines = new List<string>(50);
|
||||
foreach (var item in allItems)
|
||||
{
|
||||
finalLines.AddRange(item.lines);
|
||||
}
|
||||
|
||||
File.WriteAllLines(proguardPath, finalLines.ToArray());
|
||||
Debug.Log($"--- Update proguard-user.txt done! ☀️ ---");
|
||||
}
|
||||
|
||||
if (keeps.Count == 0) return; // 无注入文件则退出
|
||||
|
||||
List<string> lines = File.ReadAllLines(proguardPath).ToList();
|
||||
lines.Add("");
|
||||
lines.AddRange(keeps);
|
||||
|
||||
File.WriteAllLines(proguardPath, lines.ToArray());
|
||||
Debug.Log($"--- Update proguard-user.txt done! ☀️ ---");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[MenuItem("Tools/Android/Add proguard-user")]
|
||||
private static void EditorAddProguardUser()
|
||||
{
|
||||
|
|
@ -78,6 +85,67 @@ namespace Guru
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
internal class ProguardItemBuilder
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public List<ProguardItem> BuildItemsFormLines(string[] lines)
|
||||
{
|
||||
List<ProguardItem> items = new List<ProguardItem>(30);
|
||||
|
||||
string line = "";
|
||||
ProguardItem curItem = null;
|
||||
|
||||
for(int i =0; i < lines.Length; i++)
|
||||
{
|
||||
line = lines[i];
|
||||
|
||||
if(string.IsNullOrEmpty(line)) continue;
|
||||
|
||||
if (curItem == null)
|
||||
{
|
||||
curItem = new ProguardItem();
|
||||
}
|
||||
|
||||
curItem.Append(line);
|
||||
|
||||
if(line.Contains("}"))
|
||||
{
|
||||
items.Add(curItem);
|
||||
curItem = null;
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal class ProguardItem
|
||||
{
|
||||
public List<string> lines = new List<string>();
|
||||
public string key = "";
|
||||
|
||||
public void Append(string line)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key) &&
|
||||
line.StartsWith("-"))
|
||||
{
|
||||
key = line;
|
||||
}
|
||||
|
||||
if (lines == null) lines = new List<string>(5);
|
||||
lines.Add(line);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f0cef2fc19b2407381c7163d3a87ddec
|
||||
timeCreated: 1722257668
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#if UNITY_ANDROID
|
||||
|
||||
namespace Guru.BuildTool
|
||||
{
|
||||
using System.IO;
|
||||
using UnityEditor.Android;
|
||||
using UnityEngine;
|
||||
|
||||
public class AndroidSettingsGradleFixer: IPostGenerateGradleAndroidProject
|
||||
{
|
||||
private const string SettingsGradleName= "settings.gradle";
|
||||
private const string K_LINE_UNITYPROJECT = "def unityProjectPath";
|
||||
|
||||
public int callbackOrder => 1;
|
||||
|
||||
public void OnPostGenerateGradleAndroidProject(string buildPath)
|
||||
{
|
||||
FixSettingsInAndroidProject(buildPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置项目中的 Settings 文件
|
||||
/// </summary>
|
||||
/// <param name="buildPath"></param>
|
||||
private void FixSettingsInAndroidProject(string buildPath)
|
||||
{
|
||||
var settingsPath = Path.GetFullPath($"{buildPath}/../{SettingsGradleName}");
|
||||
|
||||
if (File.Exists(settingsPath))
|
||||
{
|
||||
bool isDirty = false;
|
||||
var lines = File.ReadAllLines(settingsPath);
|
||||
string projectPath = Path.GetFullPath($"{Application.dataPath}/../").Replace("\\", "/"); // Unity project path
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (lines[i].Contains(K_LINE_UNITYPROJECT))
|
||||
{
|
||||
lines[i] = $" def unityProjectPath = $/file:////{projectPath}/$.replace(\"\\\\\", \"/\")";
|
||||
isDirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDirty)
|
||||
{
|
||||
File.WriteAllLines(settingsPath, lines);
|
||||
Debug.Log($"[SDK] --- Fix Unity Project Path at:{settingsPath}");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 125df18a1af243018be105c54ab9bb5b
|
||||
timeCreated: 1722257677
|
||||
|
|
@ -7,7 +7,9 @@ namespace Guru.Editor
|
|||
using UnityEditor.Callbacks;
|
||||
using UnityEditor.iOS.Xcode;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
// ----------- SKAdNetwork 更新版本日志: 2024-06-27 --------------------
|
||||
|
||||
/// <summary>
|
||||
/// SKAdNetwork 注入逻辑
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -596,6 +596,10 @@
|
|||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>k6y4y55b64.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>6yxyv74ff7.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>t6d3zquu66.skadnetwork</string>
|
||||
|
|
@ -608,6 +612,10 @@
|
|||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>h65wbv5k3f.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>tvvz7th9br.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>bvpn9ufa9b.skadnetwork</string>
|
||||
|
|
@ -616,21 +624,13 @@
|
|||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>hjevpa356n.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>6yxyv74ff7.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>mqn7fxpca7.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>7953jerfzd.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>qu637u8glc.skadnetwork</string>
|
||||
<string>vhf287vqwu.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
|
|
@ -638,7 +638,11 @@
|
|||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>ln5gz23vtd.skadnetwork</string>
|
||||
<string>ce8ybjwass.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>jk2fsx2rgz.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
|
|
@ -646,19 +650,7 @@
|
|||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>nu4557a4je.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>gvmwg8q7h5.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>pu4na253f3.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>yrqqpx2mcb.skadnetwork</string>
|
||||
<string>dt3cjx1a9i.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
|
|
@ -666,7 +658,67 @@
|
|||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>bd757ywx3.skadnetwork</string>
|
||||
<string>ln5gz23vtd.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>pu4na253f3.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>6rd35atwn8.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>gvmwg8q7h5.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>fz2k2k5tej.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>7953jerfzd.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>577p5t736z.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>tmhh9296z4.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>7fbxrn65az.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>r8lj5b58b5.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>qu637u8glc.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>7bxrt786m8.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>xga6mpmplv.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>55644vm79v.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>nu4557a4je.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>mj797d8u6f.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
|
|
@ -678,11 +730,11 @@
|
|||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>633vhxswh4.skadnetwork</string>
|
||||
<string>qwpu75vrh2.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>tmhh9296z4.skadnetwork</string>
|
||||
<string>633vhxswh4.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
|
|
@ -732,10 +784,6 @@
|
|||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>899vrgt9g8.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>mj797d8u6f.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>88k8774x49.skadnetwork</string>
|
||||
|
|
@ -768,10 +816,6 @@
|
|||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>t7ky8fmwkd.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>fz2k2k5tej.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>w28pnjg2k4.skadnetwork</string>
|
||||
|
|
@ -824,10 +868,6 @@
|
|||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>dmv22haz9p.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>7fbxrn65az.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>b55w3d8y8z.skadnetwork</string>
|
||||
|
|
@ -920,6 +960,18 @@
|
|||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>x2jnk7ly8j.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>yrqqpx2mcb.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>bd757ywx3.skadnetwork</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>SKAdNetworkIdentifier</key>
|
||||
<string>w7jznl3r6g.skadnetwork</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -72,7 +72,7 @@ namespace Guru
|
|||
for (int i = 0; i < _params.Count; i++)
|
||||
{
|
||||
// 上报实验AB属性
|
||||
GuruAnalytics.SetUserProperty(_params[i].id, _params[i].group);
|
||||
GuruAnalytics.Instance.SetUserProperty(_params[i].id, _params[i].group);
|
||||
#if UNITY_EDITOR
|
||||
Debug.Log($"[AB] --- Add AB Param <color=cyan>{_params[i].ToString()}</color>");
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace Guru
|
|||
public const string K_IAP_PURCHASE = "iap_purchase"; // 固定点位事件
|
||||
public const string K_SUB_PURCHASE = "sub_purchase"; // 固定点位事件
|
||||
|
||||
private static Action<string> _onSessionSuccessCallback;
|
||||
private static Action<string> _onInitComplete;
|
||||
|
||||
|
||||
private static string _adId = "";
|
||||
|
|
@ -42,6 +42,9 @@ namespace Guru
|
|||
return _adjustId; // Adjust AdId;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool _isReady = false;
|
||||
public static bool IsReady => _isReady;
|
||||
|
||||
#region 启动服务
|
||||
|
||||
|
|
@ -50,7 +53,9 @@ namespace Guru
|
|||
/// </summary>
|
||||
/// <param name="appToken"></param>
|
||||
/// <param name="fbAppId">MIR 追踪 AppID</param>
|
||||
public static void StartService(string appToken, string fbAppId = "", Action<string> onSessionSuccess = null)
|
||||
/// <param name="onInitComplete"></param>
|
||||
/// <param name="onDeeplinkCallback"></param>
|
||||
public static void StartService(string appToken, string fbAppId = "", Action<string> onInitComplete = null, Action<string> onDeeplinkCallback = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(appToken))
|
||||
{
|
||||
|
|
@ -58,7 +63,7 @@ namespace Guru
|
|||
return;
|
||||
}
|
||||
|
||||
_onSessionSuccessCallback = onSessionSuccess;
|
||||
_onInitComplete = onInitComplete;
|
||||
|
||||
InstallEvent(IPMConfig.FIREBASE_ID, IPMConfig.IPM_DEVICE_ID); // 注入启动参数
|
||||
|
||||
|
|
@ -66,9 +71,12 @@ namespace Guru
|
|||
AdjustConfig config = new AdjustConfig(appToken, environment);
|
||||
config.setLogLevel(GetAdjustLogLevel());
|
||||
config.setDelayStart(DelayTime);
|
||||
|
||||
config.setPreinstallTrackingEnabled(true); // Adjust Preinstall
|
||||
config.setSessionSuccessDelegate(OnSessionSuccessCallback); // SessionSuccess
|
||||
|
||||
if(onDeeplinkCallback != null)
|
||||
config.setDeferredDeeplinkDelegate(onDeeplinkCallback);
|
||||
|
||||
|
||||
#if UNITY_ANDROID
|
||||
if (!string.IsNullOrEmpty(fbAppId)) config.setFbAppId(fbAppId); // 注入 MIR ID
|
||||
|
|
@ -79,7 +87,6 @@ namespace Guru
|
|||
config.setLogDelegate(log => LogI(LOG_TAG, log));
|
||||
config.setEventSuccessDelegate(OnEventSuccessCallback);
|
||||
config.setEventFailureDelegate(OnEventFailureCallback);
|
||||
|
||||
config.setSessionFailureDelegate(OnSessionFailureCallback);
|
||||
config.setAttributionChangedDelegate(OnAttributionChangedCallback);
|
||||
#endif
|
||||
|
|
@ -87,9 +94,6 @@ namespace Guru
|
|||
SetupInstance();
|
||||
Adjust.start(config);
|
||||
|
||||
// 缓存标准属性
|
||||
_adjustId = Adjust.getAdid(); // 获取AdjustID
|
||||
|
||||
// 异步加载AdId
|
||||
FetchGoogleAdId();
|
||||
|
||||
|
|
@ -160,6 +164,22 @@ namespace Guru
|
|||
#endregion
|
||||
|
||||
#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)
|
||||
{
|
||||
|
|
@ -278,14 +298,6 @@ namespace Guru
|
|||
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)
|
||||
{
|
||||
LogI(LOG_TAG,"Session tracking failed!");
|
||||
|
|
@ -358,24 +370,22 @@ namespace Guru
|
|||
/// <summary>
|
||||
/// 广告收入上报 (Adjust 特有的接口)
|
||||
/// </summary>
|
||||
/// <param name="adInfo"></param>
|
||||
public static void TrackADRevenue(MaxSdkBase.AdInfo adInfo)
|
||||
/// <param name="value"></param>
|
||||
/// <param name="currency"></param>
|
||||
/// <param name="adSource"></param>
|
||||
/// <param name="adUnitId"></param>
|
||||
/// <param name="adPlacement"></param>
|
||||
public static void TrackADRevenue(double value, string currency, string adSource, string adUnitId, string adPlacement)
|
||||
{
|
||||
if (adInfo == null)
|
||||
return;
|
||||
|
||||
var adRevenue = new AdjustAdRevenue(AdjustConfig.AdjustAdRevenueSourceAppLovinMAX);
|
||||
adRevenue.setRevenue(adInfo.Revenue, "USD");
|
||||
adRevenue.setAdRevenueNetwork(adInfo.NetworkName);
|
||||
adRevenue.setAdRevenueUnit(adInfo.AdUnitIdentifier);
|
||||
adRevenue.setAdRevenuePlacement(adInfo.Placement);
|
||||
if (string.IsNullOrEmpty(currency)) currency = "USD";
|
||||
adRevenue.setRevenue(value, currency);
|
||||
adRevenue.setAdRevenueNetwork(adSource);
|
||||
adRevenue.setAdRevenueUnit(adUnitId);
|
||||
adRevenue.setAdRevenuePlacement(adPlacement);
|
||||
Adjust.trackAdRevenue(adRevenue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region 关键属性上报
|
||||
|
|
|
|||
|
|
@ -14,37 +14,60 @@ namespace Guru
|
|||
public class GuruAnalytics
|
||||
{
|
||||
// Plugin Version
|
||||
public const string Version = "1.10.5";
|
||||
public const string Version = "1.11.1";
|
||||
|
||||
public static readonly string Tag = "[ANU]";
|
||||
private static readonly string ActionName = "logger_error";
|
||||
internal const int EventPriorityDefault = 10;
|
||||
private 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 static IAnalyticsAgent _agent;
|
||||
|
||||
public static IAnalyticsAgent Agent
|
||||
private IAnalyticsAgent _agent;
|
||||
private IAnalyticsAgent Agent
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_agent == null)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
_agent = new AnalyticsAgentStub();
|
||||
#elif UNITY_ANDROID
|
||||
#if UNITY_EDITOR
|
||||
_agent = new AnalyticsAgentMock();
|
||||
#elif UNITY_ANDROID
|
||||
_agent = new AnalyticsAgentAndroid();
|
||||
#elif UNITY_IOS
|
||||
#elif UNITY_IOS
|
||||
_agent = new AnalyticsAgentIOS();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_agent == null)
|
||||
{
|
||||
throw new NotImplementedException("You Should Implement IAnalyticsAgent on platform first.");
|
||||
}
|
||||
|
||||
return _agent;
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> _userProperties;
|
||||
private Dictionary<string, string> _userProperties;
|
||||
/// <summary>
|
||||
/// 用户属性缓存字典
|
||||
/// </summary>
|
||||
public static Dictionary<string, string> UserProperties
|
||||
private Dictionary<string, string> UserProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
@ -59,15 +82,13 @@ namespace Guru
|
|||
/// <summary>
|
||||
/// 错误 code 表
|
||||
/// </summary>
|
||||
public static List<int> ErrorCodeList = new List<int>();
|
||||
|
||||
private static bool _autoSyncProperties = false;
|
||||
private static bool _enableErrorLog = false;
|
||||
public List<int> ErrorCodeList = new List<int>();
|
||||
private bool _enableErrorLog = false;
|
||||
|
||||
/// <summary>
|
||||
/// 启动日志错误上报
|
||||
/// </summary>
|
||||
public static bool EnableErrorLog
|
||||
public bool EnableErrorLog
|
||||
{
|
||||
get => _enableErrorLog;
|
||||
set
|
||||
|
|
@ -83,37 +104,40 @@ namespace Guru
|
|||
/// <summary>
|
||||
/// 初始化接口
|
||||
/// </summary>
|
||||
public static void Init(string appId, string deviceInfo, bool isDebug = false,
|
||||
bool enableErrorLog = false, bool syncProperties = false)
|
||||
public static void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false,
|
||||
bool enableErrorLog = false)
|
||||
{
|
||||
Debug.Log($"{Tag} --- Guru Analytics [{Version}] initialing...");
|
||||
|
||||
_autoSyncProperties = syncProperties;
|
||||
_enableErrorLog = enableErrorLog;
|
||||
Agent?.Init(appId, deviceInfo, isDebug);
|
||||
if(_enableErrorLog) InitCallbacks(); // 激活错误日志回调
|
||||
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new GuruAnalytics();
|
||||
_instance.Agent.Init(appId, deviceInfo, onInitComplete, isDebug);
|
||||
_instance.EnableErrorLog = enableErrorLog;
|
||||
_instance._isReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置视图名称
|
||||
/// </summary>
|
||||
/// <param name="screenName"></param>
|
||||
public static void SetScreen(string screenName)
|
||||
public void SetScreen(string screenName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(screenName)) return;
|
||||
CacheUserProperty($"screen_name", screenName);
|
||||
Agent?.SetScreen(screenName);
|
||||
Agent.SetScreen(screenName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置广告ID
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
public static void SetAdId(string id)
|
||||
public void SetAdId(string id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id)) return;
|
||||
CacheUserProperty($"ad_id", id);
|
||||
Agent?.SetAdId(id);
|
||||
Agent.SetAdId(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -121,59 +145,59 @@ namespace Guru
|
|||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
public static void SetUserProperty(string key, string value)
|
||||
public void SetUserProperty(string key, string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value)) return;
|
||||
CacheUserProperty(key, value); // 添加用户属性
|
||||
Agent?.SetUserProperty(key, value);
|
||||
Agent.SetUserProperty(key, value);
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置Firebase ID
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
public static void SetFirebaseId(string id)
|
||||
public void SetFirebaseId(string id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id)) return;
|
||||
CacheUserProperty($"firebase_id", id);
|
||||
Agent?.SetFirebaseId(id);
|
||||
Agent.SetFirebaseId(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置Adjust ID
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
public static void SetAdjustId(string id)
|
||||
public void SetAdjustId(string id)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id)) return;
|
||||
CacheUserProperty($"adjust_id", id);
|
||||
Agent?.SetAdjustId(id);
|
||||
Agent.SetAdjustId(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置设备ID
|
||||
/// </summary>
|
||||
/// <param name="deviceId"></param>
|
||||
public static void SetDeviceId(string deviceId)
|
||||
public void SetDeviceId(string deviceId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(deviceId)) return;
|
||||
CacheUserProperty($"device_id", deviceId);
|
||||
Agent?.SetDeviceId(deviceId);
|
||||
Agent.SetDeviceId(deviceId);
|
||||
}
|
||||
|
||||
|
||||
public static void SetAndroidID(string androidId)
|
||||
public void SetAndroidID(string androidId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(androidId)) return;
|
||||
CacheUserProperty(Analytics.PropertyAndroidID, androidId);
|
||||
}
|
||||
|
||||
public static void SetIDFV(string idfv)
|
||||
public void SetIDFV(string idfv)
|
||||
{
|
||||
if (string.IsNullOrEmpty(idfv)) return;
|
||||
CacheUserProperty(Analytics.PropertyIDFV, idfv);
|
||||
}
|
||||
|
||||
public static void SetIDFA(string idfa)
|
||||
public void SetIDFA(string idfa)
|
||||
{
|
||||
if (string.IsNullOrEmpty(idfa)) return;
|
||||
CacheUserProperty(Analytics.PropertyIDFA, idfa);
|
||||
|
|
@ -184,17 +208,17 @@ namespace Guru
|
|||
/// 设置用户ID
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
public static void SetUid(string uid)
|
||||
public void SetUid(string uid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(uid)) return;
|
||||
CacheUserProperty($"uid", uid);
|
||||
Agent?.SetUid(uid);
|
||||
Agent.SetUid(uid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上报事件成功率
|
||||
/// </summary>
|
||||
public static void ReportEventSuccessRate() => Agent?.ReportEventSuccessRate();
|
||||
public void ReportEventSuccessRate() => Agent.ReportEventSuccessRate();
|
||||
|
||||
/// <summary>
|
||||
/// 上报打点事件
|
||||
|
|
@ -202,21 +226,19 @@ namespace Guru
|
|||
/// <param name="eventName">事件名称</param>
|
||||
/// <param name="data">INT类型的值</param>
|
||||
/// <param name="priority"></param>
|
||||
public static void LogEvent(string eventName, Dictionary<string, dynamic> data = null, int priority = -1)
|
||||
public void LogEvent(string eventName, Dictionary<string, dynamic> data = null, int priority = -1)
|
||||
{
|
||||
if(_autoSyncProperties)
|
||||
UpdateAllUserProperties(); // 每次打点更新用户属性
|
||||
|
||||
string raw = "";
|
||||
if (data != null && data.Count > 0)
|
||||
{
|
||||
raw = BuildParamsJson(data);
|
||||
}
|
||||
if (priority < 0) priority = EventPriorityDefault;
|
||||
Debug.Log($"{Tag} event:{eventName} | raw: {raw} | priority: {priority}");
|
||||
Agent?.LogEvent(eventName, raw, priority);
|
||||
Debug.Log($"{Tag} --- LogEvent GuruAnalytics:{eventName} | raw: {raw} | priority: {priority}");
|
||||
Agent.LogEvent(eventName, raw, priority);
|
||||
}
|
||||
|
||||
/*
|
||||
private static string BuildParamsString(Dictionary<string, dynamic> data)
|
||||
{
|
||||
string raw = "";
|
||||
|
|
@ -228,8 +250,9 @@ namespace Guru
|
|||
}
|
||||
return raw;
|
||||
}
|
||||
*/
|
||||
|
||||
private static string BuildParamsJson(Dictionary<string, dynamic> data)
|
||||
private string BuildParamsJson(Dictionary<string, dynamic> data)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -247,6 +270,7 @@ namespace Guru
|
|||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// 构建带有类型格式的Str值
|
||||
/// </summary>
|
||||
|
|
@ -267,15 +291,16 @@ namespace Guru
|
|||
|
||||
return $"{kvp.Key}:s{kvp.Value}";
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// 设置太极02值
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public static void SetTch02Value(double value)
|
||||
public void SetTch02Value(double value)
|
||||
{
|
||||
Debug.Log($"{Tag} set tch_02_value:{value}");
|
||||
Agent?.SetTch02Value(value);
|
||||
Agent.SetTch02Value(value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -296,37 +321,19 @@ namespace Guru
|
|||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
private static void CacheUserProperty(string key, string value)
|
||||
private 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;
|
||||
// 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
|
||||
|
||||
#region 日志回调
|
||||
|
||||
private static void InitCallbacks()
|
||||
private void InitCallbacks()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -346,8 +353,8 @@ namespace Guru
|
|||
/// <summary>
|
||||
/// 获取SDK回调
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
private static void OnSDKCallback(string raw)
|
||||
/// <param name="raw"></param>
|
||||
private void OnSDKCallback(string raw)
|
||||
{
|
||||
if (string.IsNullOrEmpty(raw)) return;
|
||||
if (!raw.Contains($"\"{ActionName}\"")) return; // 不对其他行为的日志进行过滤
|
||||
|
|
@ -359,7 +366,7 @@ namespace Guru
|
|||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="errorInfo"></param>
|
||||
private static void OnLoggerErrorEvent(int code, string errorInfo = "")
|
||||
private void OnLoggerErrorEvent(int code, string errorInfo = "")
|
||||
{
|
||||
// Debug.Log($"{Tag} --- OnLoggerErrorEvent: code:{code}\tinfo:{errorInfo}");
|
||||
|
||||
|
|
@ -388,17 +395,13 @@ namespace Guru
|
|||
parameters["err"] = errorInfo;
|
||||
|
||||
Debug.Log($"{Tag} ------ ErrorLogInfo:: code:{codeString}\tinfo:{errorInfo}");
|
||||
|
||||
#if !UNITY_EDITOR
|
||||
|
||||
// Only for firebase GA
|
||||
Analytics.LogEvent("dev_audit", parameters,
|
||||
new Analytics.EventSetting() { EnableFirebaseAnalytics = true });
|
||||
#endif
|
||||
|
||||
Analytics.TrackEvent("dev_audit", parameters, new Analytics.EventSetting() { EnableFirebaseAnalytics = true });
|
||||
}
|
||||
|
||||
|
||||
private static bool ParseWithJson(string json)
|
||||
private bool ParseWithJson(string json)
|
||||
{
|
||||
Debug.Log($"{Tag} ------ ParseWithJson: json:\n{json}");
|
||||
|
||||
|
|
@ -435,7 +438,7 @@ namespace Guru
|
|||
{
|
||||
string p = "\"msg\":\"";
|
||||
string m = json;
|
||||
if (json.Contains(p)) m = json.Substring(json.IndexOf(p) + p.Length);
|
||||
if (json.Contains(p)) m = json.Substring(json.IndexOf(p, StringComparison.Ordinal) + p.Length);
|
||||
info = $"JsonEX:{m}";
|
||||
// Debug.Log($"{Tag} --- {info}");
|
||||
Analytics.LogCrashlytics(json, false);
|
||||
|
|
@ -445,22 +448,17 @@ namespace Guru
|
|||
return false;
|
||||
}
|
||||
|
||||
private static void ParseWithRaw(string raw)
|
||||
/**
|
||||
private void ParseWithRaw(string raw)
|
||||
{
|
||||
int code = (int)AnalyticsCode.Unknown;
|
||||
string info = raw;
|
||||
var code = (int)AnalyticsCode.Unknown;
|
||||
string info;
|
||||
|
||||
//------- message send to unity ----------
|
||||
Debug.Log($"{Tag} get callback errorInfo:\n{raw}");
|
||||
|
||||
string patten = "";
|
||||
string patten2 = "";
|
||||
int idx = 0;
|
||||
int idx2 = 0;
|
||||
int len = 0;
|
||||
|
||||
|
||||
patten = "msg\":\"";
|
||||
var patten = "msg\":\"";
|
||||
if (raw.Contains(patten))
|
||||
{
|
||||
|
||||
|
|
@ -483,16 +481,16 @@ namespace Guru
|
|||
try
|
||||
{
|
||||
|
||||
idx = raw.IndexOf(patten, StringComparison.Ordinal) + patten.Length;
|
||||
var idx = raw.IndexOf(patten, StringComparison.Ordinal) + patten.Length;
|
||||
string act = raw.Substring(idx, ActionName.Length);
|
||||
if (act == ActionName)
|
||||
{
|
||||
patten = "code\":";
|
||||
patten2 = ",\"msg";
|
||||
idx = raw.IndexOf(patten);
|
||||
idx2 = raw.IndexOf(patten2);
|
||||
var patten2 = ",\"msg";
|
||||
idx = raw.IndexOf(patten, StringComparison.Ordinal);
|
||||
var idx2 = raw.IndexOf(patten2, StringComparison.Ordinal);
|
||||
|
||||
len = idx2 - (idx + patten.Length);
|
||||
var len = idx2 - (idx + patten.Length);
|
||||
if (len > 0)
|
||||
{
|
||||
string c = raw.Substring(idx + patten.Length, len);
|
||||
|
|
@ -531,12 +529,12 @@ namespace Guru
|
|||
{
|
||||
Analytics.LogCrashlytics(raw, false);
|
||||
Analytics.LogCrashlytics($"{Tag} --- format error:{raw}");
|
||||
OnLoggerErrorEvent(code, raw.Substring(raw.IndexOf("msg\":" ) + 5));
|
||||
OnLoggerErrorEvent(code, raw.Substring(raw.IndexOf("msg\":", StringComparison.Ordinal) + 5));
|
||||
}
|
||||
}
|
||||
**/
|
||||
|
||||
|
||||
private static void ReportCodeInfo(int code, string info)
|
||||
private void ReportCodeInfo(int code, string info)
|
||||
{
|
||||
var ac = (AnalyticsCode)code;
|
||||
Debug.Log($"{Tag} ------ Get Code And Info: code:{code}[{ac}] \tinfo:{info}");
|
||||
|
|
@ -592,7 +590,7 @@ namespace Guru
|
|||
|
||||
public static void TestOnCallback(string msg)
|
||||
{
|
||||
OnSDKCallback(msg);
|
||||
Instance.OnSDKCallback(msg);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
namespace Guru
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// 自打点代理接口
|
||||
/// </summary>
|
||||
public interface IAnalyticsAgent
|
||||
{
|
||||
void Init(string appId, string deviceInfo, bool isDebug = false);
|
||||
void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false);
|
||||
void SetScreen(string screenName);
|
||||
void SetAdId(string id);
|
||||
void SetUserProperty(string key, string value);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
|
||||
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Guru
|
||||
{
|
||||
using System;
|
||||
|
|
@ -76,12 +78,16 @@ namespace Guru
|
|||
|
||||
#region 接口实现
|
||||
|
||||
public void Init(string appId, string deviceInfo, bool isDebug = false)
|
||||
public async void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false)
|
||||
{
|
||||
_isDebug = isDebug;
|
||||
string bundleId = Application.identifier;
|
||||
// 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); // 调用接口
|
||||
|
||||
onInitComplete?.Invoke();
|
||||
}
|
||||
|
||||
public void SetScreen(string screenName)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Guru
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
public class AnalyticsAgentIOS: IAnalyticsAgent
|
||||
{
|
||||
|
||||
|
|
@ -55,13 +57,14 @@ namespace Guru
|
|||
}
|
||||
|
||||
|
||||
public void Init(string appId, string deviceInfo, bool isDebug = false)
|
||||
public void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false)
|
||||
{
|
||||
_isDebug = isDebug;
|
||||
#if UNITY_IOS
|
||||
unityInitAnalytics(appId, deviceInfo, isDebug);
|
||||
unityInitException(); // 初始化报错守护进程
|
||||
#endif
|
||||
onInitComplete?.Invoke();
|
||||
}
|
||||
|
||||
public void SetScreen(string screenName)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Guru
|
||||
{
|
||||
public class AnalyticsAgentStub: IAnalyticsAgent
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
|
||||
public class AnalyticsAgentMock: IAnalyticsAgent
|
||||
{
|
||||
|
||||
public static readonly string TAG = "[EDT]";
|
||||
|
|
@ -24,7 +27,7 @@ namespace Guru
|
|||
|
||||
}
|
||||
|
||||
public void Init(string appId, string deviceInfo, bool isDebug = false)
|
||||
public void Init(string appId, string deviceInfo, Action onInitComplete, bool isDebug = false)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
_isShowLog = true;
|
||||
|
|
@ -32,6 +35,8 @@ namespace Guru
|
|||
_isDebug = isDebug;
|
||||
if(_isShowLog)
|
||||
Debug.Log($"{TAG} init with Debug: <color=orange>{isDebug}</color> appId:{appId} deviceInfo:{deviceInfo}");
|
||||
|
||||
onInitComplete?.Invoke();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -127,7 +132,7 @@ namespace Guru
|
|||
}
|
||||
}
|
||||
|
||||
Debug.Log($"{TAG} LogEvent: event:<color=orange>{eventName} ({priority})</color> Properties:\n{sb.ToString()}");
|
||||
Debug.Log($"{TAG} LogEvent: GuruAnalytics:<color=orange>{eventName} ({priority})</color> Properties:\n{sb.ToString()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ using UnityEngine.UI;
|
|||
|
||||
namespace Guru
|
||||
{
|
||||
public class CuruAnalyticsDemo: MonoBehaviour
|
||||
public class GuruAnalyticsDemo: MonoBehaviour
|
||||
{
|
||||
[SerializeField] private bool _isDebug = true;
|
||||
[SerializeField] private Button _btnInitSDK;
|
||||
|
|
@ -54,17 +54,22 @@ namespace Guru
|
|||
private void OnClickInit()
|
||||
{
|
||||
Debug.Log($"---- [DEMO] Call Analytics init");
|
||||
GuruAnalytics.Init(AppID, DeviceInfo, _isDebug);
|
||||
GuruAnalytics.Init(AppID, DeviceInfo, OnGuruAnalyticsInitComplete, _isDebug);
|
||||
}
|
||||
|
||||
|
||||
private void OnGuruAnalyticsInitComplete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void OnClickStatus()
|
||||
{
|
||||
Debug.Log($"---- [DEMO] Report Stats IDs: UID:{UID} DeviceID:{DeviceID} FirebaseID:{FirebaseID} AdID:{AdID} AdjustID:{AdjustID}");
|
||||
GuruAnalytics.SetUid(UID);
|
||||
GuruAnalytics.SetDeviceId(DeviceID);
|
||||
GuruAnalytics.SetFirebaseId(FirebaseID);
|
||||
GuruAnalytics.SetAdId(AdID);
|
||||
GuruAnalytics.SetAdjustId(AdjustID);
|
||||
GuruAnalytics.Instance.SetUid(UID);
|
||||
GuruAnalytics.Instance.SetDeviceId(DeviceID);
|
||||
GuruAnalytics.Instance.SetFirebaseId(FirebaseID);
|
||||
GuruAnalytics.Instance.SetAdId(AdID);
|
||||
GuruAnalytics.Instance.SetAdjustId(AdjustID);
|
||||
}
|
||||
|
||||
private void OnClickUserProperties()
|
||||
|
|
@ -72,14 +77,14 @@ namespace Guru
|
|||
string item_category = "main";
|
||||
int level = 7;
|
||||
Debug.Log($"---- [DEMO] Call SetUserProperty: item_category:{item_category} level:{level}");
|
||||
GuruAnalytics.SetUserProperty("item_category", item_category);
|
||||
GuruAnalytics.SetUserProperty("level", level.ToString());
|
||||
GuruAnalytics.Instance.SetUserProperty("item_category", item_category);
|
||||
GuruAnalytics.Instance.SetUserProperty("level", level.ToString());
|
||||
}
|
||||
|
||||
private void OnClickEvents()
|
||||
{
|
||||
Debug.Log($"---- [DEMO] Report Screen: {ScreenName}");
|
||||
GuruAnalytics.SetScreen(ScreenName);
|
||||
GuruAnalytics.Instance.SetScreen(ScreenName);
|
||||
|
||||
string eventName = "user_get_coin";
|
||||
Dictionary<string, dynamic> data = new Dictionary<string, dynamic>()
|
||||
|
|
@ -99,19 +104,19 @@ namespace Guru
|
|||
Debug.Log(s);
|
||||
|
||||
Debug.Log($"---- [DEMO] Call LogEvent");
|
||||
GuruAnalytics.LogEvent(eventName, data);
|
||||
GuruAnalytics.Instance.LogEvent(eventName, data);
|
||||
}
|
||||
|
||||
private void OnClickEvents2()
|
||||
{
|
||||
string eventName = "user_data_loaded";
|
||||
GuruAnalytics.LogEvent(eventName);
|
||||
GuruAnalytics.Instance.LogEvent(eventName);
|
||||
}
|
||||
|
||||
|
||||
private void OnClickReport()
|
||||
{
|
||||
GuruAnalytics.ReportEventSuccessRate();
|
||||
GuruAnalytics.Instance.ReportEventSuccessRate();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ namespace Guru
|
|||
DmaResult = result;
|
||||
|
||||
//----------- Guru Analytics report ---------------
|
||||
Analytics.LogEvent("dma_gg", new Dictionary<string, dynamic>()
|
||||
Analytics.TrackEvent("dma_gg", new Dictionary<string, dynamic>()
|
||||
{
|
||||
{ "purpose", purposeStr },
|
||||
{ "result", result }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
|
||||
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Guru
|
||||
{
|
||||
using UnityEngine;
|
||||
|
|
@ -30,6 +32,21 @@ namespace Guru
|
|||
Debug.Log($"{Tag} Consent Request -> deviceid: {deviceId} debugGeography: {debugGeography}");
|
||||
|
||||
#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);
|
||||
var go = GameObject.Find(_objName);
|
||||
if (go != null)
|
||||
|
|
@ -40,9 +57,10 @@ namespace Guru
|
|||
{
|
||||
Debug.LogError($"{Tag} Can't find callback object");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取 DMA 字段
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Guru
|
||||
|
|
@ -115,7 +116,7 @@ namespace Guru
|
|||
|
||||
private void OnLoadMaxBanner()
|
||||
{
|
||||
_badsloadStartTime = Time.realtimeSinceStartup;
|
||||
_badsloadStartTime = DateTime.UtcNow;
|
||||
_chanelMax.LoadBannerAD();
|
||||
OnBannerStartLoad?.Invoke(_chanelMax.MaxBADSSlotID);
|
||||
}
|
||||
|
|
@ -147,7 +148,7 @@ namespace Guru
|
|||
}
|
||||
|
||||
private void OnLoadMaxIV() {
|
||||
_iadsLoadStartTime = Time.realtimeSinceStartup; // 更新计时器
|
||||
_iadsLoadStartTime = DateTime.UtcNow; // 更新计时器
|
||||
_chanelMax.LoadInterstitialAD();
|
||||
OnInterstitialStartLoad?.Invoke(_chanelMax.MaxIADSSlotID);
|
||||
}
|
||||
|
|
@ -180,7 +181,7 @@ namespace Guru
|
|||
|
||||
private void OnLoadMaxRV()
|
||||
{
|
||||
_radsLoadStartTime = Time.realtimeSinceStartup; // 更新计时器
|
||||
_radsLoadStartTime = DateTime.UtcNow; // 更新计时器
|
||||
_chanelMax.LoadRewardAD();
|
||||
OnRewardedStartLoad?.Invoke(_chanelMax.MaxRADSSlotID);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
using System.Linq;
|
||||
|
||||
namespace Guru
|
||||
{
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using Guru.Ads;
|
||||
|
||||
public abstract class ADServiceBase<T> : IADService where T : new()
|
||||
{
|
||||
|
|
@ -18,7 +21,7 @@ namespace Guru
|
|||
}
|
||||
}
|
||||
|
||||
protected static readonly string Tag = "[Ads]";
|
||||
protected static readonly string Tag = "[SDK][ADS]";
|
||||
public bool IsInitialized => MaxSdk.IsInitialized() || _isServiceStarted;
|
||||
protected bool IsNetworkEnabled => Application.internetReachability != NetworkReachability.NotReachable;
|
||||
|
||||
|
|
@ -40,10 +43,15 @@ namespace Guru
|
|||
public static Action OnRewardLoaded;
|
||||
public static Action OnRewardFailed;
|
||||
public static Action OnRewardClosed;
|
||||
|
||||
|
||||
private Dictionary<string, string> _reviewCreativeIds = new Dictionary<string, string>(10); // Creative ID 缓存: Cid : RCid
|
||||
private Dictionary<string, List<AdImpressionData>> _impressionCache = new Dictionary<string, List<AdImpressionData>>(10);
|
||||
|
||||
protected AdsModel _model;
|
||||
protected AdsInitSpec _initSpec = null;
|
||||
|
||||
private AdImpressionDriver _impressionDriver;
|
||||
|
||||
public AdsModel Model
|
||||
{
|
||||
get
|
||||
|
|
@ -74,6 +82,9 @@ namespace Guru
|
|||
if(_model == null) _model = AdsModel.Create();
|
||||
this.Log("AD SDK Start Init");
|
||||
|
||||
_impressionDriver = new AdImpressionDriver();
|
||||
_impressionDriver.Init(ReportAdsRevenue); // 初始化 Impression 驱动器
|
||||
|
||||
InitMaxCallbacks(); // 初始化 MAX 广告
|
||||
InitService(); // 内部继承接口
|
||||
}
|
||||
|
|
@ -85,14 +96,16 @@ namespace Guru
|
|||
{
|
||||
//-------------- 初始化回调 ------------------
|
||||
MaxSdkCallbacks.OnSdkInitializedEvent += OnMaxSdkInitializedCallBack;
|
||||
MaxSdkCallbacks.Interstitial.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
|
||||
MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
|
||||
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent += OnBannerRevenuePaidEvent;
|
||||
MaxSdkCallbacks.MRec.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
|
||||
|
||||
//--------------- MRec 回调 -----------------
|
||||
// MaxSdkCallbacks.MRec.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
|
||||
|
||||
//--------------- Banner 回调 -----------------
|
||||
MaxSdkCallbacks.Banner.OnAdLoadedEvent += OnBannerLoadedEvent;
|
||||
MaxSdkCallbacks.Banner.OnAdLoadFailedEvent += OnBannerFailedEvent;
|
||||
MaxSdkCallbacks.Banner.OnAdClickedEvent += OnBannerClickedEvent;
|
||||
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent += OnBannerRevenuePaidEvent;
|
||||
MaxSdkCallbacks.Banner.OnAdReviewCreativeIdGeneratedEvent += OnAdReviewCreativeIdGeneratedEvent;
|
||||
//--------------- IV 回调 -----------------
|
||||
MaxSdkCallbacks.Interstitial.OnAdLoadedEvent += OnInterstitialLoadedEvent;
|
||||
MaxSdkCallbacks.Interstitial.OnAdLoadFailedEvent += OnInterstitialFailedEvent;
|
||||
|
|
@ -100,6 +113,8 @@ namespace Guru
|
|||
MaxSdkCallbacks.Interstitial.OnAdClickedEvent += OnInterstitialClickEvent;
|
||||
MaxSdkCallbacks.Interstitial.OnAdDisplayedEvent += OnInterstitialDisplayEvent;
|
||||
MaxSdkCallbacks.Interstitial.OnAdHiddenEvent += OnInterstitialDismissedEvent;
|
||||
MaxSdkCallbacks.Interstitial.OnAdRevenuePaidEvent += OnInterstitialPaidEvent;
|
||||
MaxSdkCallbacks.Interstitial.OnAdReviewCreativeIdGeneratedEvent += OnAdReviewCreativeIdGeneratedEvent;
|
||||
//--------------- RV 回调 -----------------
|
||||
MaxSdkCallbacks.Rewarded.OnAdLoadedEvent += OnRewardedAdLoadedEvent;
|
||||
MaxSdkCallbacks.Rewarded.OnAdLoadFailedEvent += OnRewardedAdFailedEvent;
|
||||
|
|
@ -108,11 +123,19 @@ namespace Guru
|
|||
MaxSdkCallbacks.Rewarded.OnAdClickedEvent += OnRewardedAdClickedEvent;
|
||||
MaxSdkCallbacks.Rewarded.OnAdHiddenEvent += OnRewardedAdDismissedEvent;
|
||||
MaxSdkCallbacks.Rewarded.OnAdReceivedRewardEvent += OnRewardedAdReceivedRewardEvent;
|
||||
|
||||
MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent += OnRewardedAdPaidEvent;
|
||||
MaxSdkCallbacks.Rewarded.OnAdReviewCreativeIdGeneratedEvent += OnAdReviewCreativeIdGeneratedEvent;
|
||||
|
||||
//--------------- Creative 回调 -----------------
|
||||
|
||||
|
||||
|
||||
//-------------- SDK 初始化 -------------------
|
||||
MaxSdk.SetExtraParameter("enable_black_screen_fixes", "true"); // 修复黑屏
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected virtual void InitService()
|
||||
{
|
||||
}
|
||||
|
|
@ -174,7 +197,7 @@ namespace Guru
|
|||
|
||||
#endregion
|
||||
|
||||
#region ILRD
|
||||
#region 收益打点
|
||||
|
||||
private double TchAD001RevValue
|
||||
{
|
||||
|
|
@ -188,49 +211,34 @@ namespace Guru
|
|||
set => _model.TchAD02RevValue = value;
|
||||
}
|
||||
|
||||
public void OnAdRevenuePaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||
{
|
||||
if (adInfo == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
Log.I( $"[ADRevenue] - adUnitId:{adUnitId}, Revenue:{adInfo?.Revenue : 0}");
|
||||
|
||||
// #1 ad_impression
|
||||
OnAdImpression(adInfo);
|
||||
|
||||
// #2 tch_001
|
||||
double revenue = adInfo.Revenue;
|
||||
CalcTaichi001Value(revenue);
|
||||
CalcTaichi02Value(revenue);
|
||||
|
||||
// #3 adjust_ad_revenue
|
||||
AdjustService.TrackADRevenue(adInfo);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Analytics.LogCrashlytics(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 广告ARO收益打点
|
||||
/// 上报广告收益
|
||||
/// </summary>
|
||||
/// <param name="adInfo"></param>
|
||||
/// <param name="platform"></param>
|
||||
private void OnAdImpression(MaxSdkBase.AdInfo adInfo, string platform = "")
|
||||
/// <param name="reviewedCreativeId"></param>
|
||||
private void ReportAdsRevenue(AdImpressionData data)
|
||||
{
|
||||
Analytics.ADImpression(adInfo, platform);
|
||||
// #1 ad_impression
|
||||
Analytics.ADImpression(data);
|
||||
|
||||
// #2 tch_001 和 tch_02
|
||||
double revenue = data.value;
|
||||
CalcTch001Value(revenue);
|
||||
CalcTch02Value(revenue);
|
||||
|
||||
// #3 adjust_ad_revenue
|
||||
AdjustService.TrackADRevenue(data.value, data.currency, data.ad_source, data.ad_unit_name, data.ad_placement);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 计算太极001收益
|
||||
/// </summary>
|
||||
/// <param name="revenue"></param>
|
||||
private void CalcTaichi001Value(double revenue)
|
||||
private void CalcTch001Value(double revenue)
|
||||
{
|
||||
TchAD001RevValue += revenue;
|
||||
double revenueValue = TchAD001RevValue;
|
||||
|
|
@ -247,7 +255,7 @@ namespace Guru
|
|||
/// 计算太极02收益
|
||||
/// </summary>
|
||||
/// <param name="revenue"></param>
|
||||
private void CalcTaichi02Value(double revenue)
|
||||
private void CalcTch02Value(double revenue)
|
||||
{
|
||||
if (!Analytics.EnableTch02Event) return;
|
||||
|
||||
|
|
@ -269,21 +277,24 @@ namespace Guru
|
|||
private string _backColorStr = "#50A436";
|
||||
private Color _backColor = new Color(0, 0, 0, 0);
|
||||
private string _badsCategory;
|
||||
protected float _badsloadStartTime = 0;
|
||||
protected DateTime _badsloadStartTime;
|
||||
private bool _bannerVisible = false;
|
||||
public bool IsBannerVisible => _bannerVisible;
|
||||
private int _badsloadedNum = 0;
|
||||
private int _badsLoadFailNum = 0;
|
||||
|
||||
|
||||
|
||||
private int GetAdsLoadDuration(ref float startTime)
|
||||
/// <summary>
|
||||
/// 获取动作间隔之间的毫秒数
|
||||
/// </summary>
|
||||
/// <param name="startTime"></param>
|
||||
/// <returns></returns>
|
||||
private int GetActionDuration(DateTime startTime)
|
||||
{
|
||||
int duration = (int)((Time.realtimeSinceStartup - startTime) * 1000);
|
||||
startTime = Time.realtimeSinceStartup;
|
||||
return duration;
|
||||
var sp = DateTime.UtcNow.Subtract(startTime.ToUniversalTime()).Duration();
|
||||
return (int) sp.TotalMilliseconds;
|
||||
}
|
||||
|
||||
|
||||
public virtual void RequestBannerAD()
|
||||
{
|
||||
_backColor = Color.clear;
|
||||
|
|
@ -314,12 +325,12 @@ namespace Guru
|
|||
|
||||
public void OnLoadBads()
|
||||
{
|
||||
_badsloadStartTime = Time.realtimeSinceStartup;
|
||||
_badsloadStartTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
protected virtual void OnBadsLoaded()
|
||||
{
|
||||
_badsloadStartTime = Time.realtimeSinceStartup;
|
||||
_badsloadStartTime = DateTime.UtcNow;
|
||||
OnBannerLoaded?.Invoke();
|
||||
}
|
||||
|
||||
|
|
@ -386,6 +397,7 @@ namespace Guru
|
|||
// --- fixed by Yufei 2024-5-29 为 don't report bads_loaded any more. ---
|
||||
// Analytics.ADBadsLoaded(AdParams.Build(adUnitId, adInfo,
|
||||
// duration: GetAdsLoadDuration(ref _badsloadStartTime), category: _badsCategory));
|
||||
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
|
||||
OnBadsLoaded();
|
||||
}
|
||||
|
||||
|
|
@ -394,7 +406,7 @@ namespace Guru
|
|||
_badsLoadFailNum ++;
|
||||
// Analytics.ADBadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _badsloadStartTime), _badsCategory);
|
||||
Analytics.ADBadsFailed(AdParams.Build(adUnitId,
|
||||
duration: GetAdsLoadDuration(ref _badsloadStartTime), category: _badsCategory,
|
||||
duration: GetActionDuration(_badsloadStartTime), category: _badsCategory,
|
||||
errorCode: (int)errorInfo.Code,
|
||||
waterfallName: errorInfo?.WaterfallInfo?.Name ?? ""));
|
||||
}
|
||||
|
|
@ -426,7 +438,8 @@ namespace Guru
|
|||
{
|
||||
if (_bannerVisible)
|
||||
{
|
||||
OnAdRevenuePaidEvent(adUnitId, adInfo); // Banner 只有显示时才上报收益值
|
||||
// Banner 只有显示时才上报收益值
|
||||
AppendImpressionData(adInfo, eventName:Analytics.EventBadsPaid, itemCategory:_badsCategory);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -436,9 +449,12 @@ namespace Guru
|
|||
|
||||
private string _iadsCategory = "main";
|
||||
private int _interstitialRetryAttempt;
|
||||
protected float _iadsLoadStartTime;
|
||||
private Action _interCloseAction;
|
||||
protected bool _isIadsLoading = false;
|
||||
protected DateTime _iadsLoadStartTime;
|
||||
private DateTime _iadsDisplayStartTime;
|
||||
|
||||
|
||||
public bool IsIadsLoading => _isIadsLoading;
|
||||
|
||||
public virtual void RequestInterstitialAD()
|
||||
|
|
@ -462,7 +478,7 @@ namespace Guru
|
|||
|
||||
public void OnLoadIads()
|
||||
{
|
||||
_iadsLoadStartTime = Time.realtimeSinceStartup;
|
||||
_iadsLoadStartTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -496,6 +512,7 @@ namespace Guru
|
|||
_interCloseAction = dismissAction;
|
||||
MaxSdk.ShowInterstitial(GetInterstitialID());
|
||||
|
||||
_iadsDisplayStartTime = DateTime.UtcNow;
|
||||
// RequestInterstitialAD(); // 直接加载下一个广告
|
||||
}
|
||||
|
||||
|
|
@ -506,9 +523,11 @@ namespace Guru
|
|||
// Reset retry attempt
|
||||
// Analytics.ADIadsLoaded(adUnitId, GetAdsLoadDuration(ref _iadsLoadStartTime), _iadsCategory);
|
||||
Analytics.ADIadsLoaded(AdParams.Build(adUnitId,
|
||||
duration: GetAdsLoadDuration(ref _iadsLoadStartTime), category: _iadsCategory));
|
||||
duration: GetActionDuration(_iadsLoadStartTime), category: _iadsCategory));
|
||||
_interstitialRetryAttempt = 0;
|
||||
|
||||
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
|
||||
|
||||
OnInterstitialLoaded?.Invoke();
|
||||
}
|
||||
|
||||
|
|
@ -523,8 +542,9 @@ namespace Guru
|
|||
float retryDelay = GetRetryDelaySeconds(_interstitialRetryAttempt);
|
||||
DelayCall(retryDelay, RequestInterstitialAD);
|
||||
// Analytics.ADIadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _iadsLoadStartTime), _iadsCategory);
|
||||
if(string.IsNullOrEmpty(_iadsCategory)) _iadsCategory = "not_set";
|
||||
Analytics.ADIadsFailed(AdParams.Build(adUnitId,
|
||||
duration: GetAdsLoadDuration(ref _iadsLoadStartTime), category: _iadsCategory,
|
||||
duration: GetActionDuration(_iadsLoadStartTime), category: _iadsCategory,
|
||||
errorCode: (int)errorInfo.Code,
|
||||
waterfallName: errorInfo?.WaterfallInfo?.Name ?? ""));
|
||||
|
||||
|
|
@ -539,42 +559,61 @@ namespace Guru
|
|||
$"InterstitialFailedToDisplayEvent AdLoadFailureInfo:{errorInfo.AdLoadFailureInfo}, Message: {errorInfo.Message}");
|
||||
// Analytics.ADIadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _iadsLoadStartTime), _iadsCategory);
|
||||
Analytics.ADIadsFailed(AdParams.Build(adUnitId,
|
||||
duration: GetAdsLoadDuration(ref _iadsLoadStartTime), category: _iadsCategory,
|
||||
duration: GetActionDuration(_iadsDisplayStartTime), category: _iadsCategory,
|
||||
errorCode: (int)errorInfo.Code,
|
||||
waterfallName: errorInfo?.WaterfallInfo?.Name ?? ""));
|
||||
waterfallName: errorInfo.WaterfallInfo?.Name ?? ""));
|
||||
DelayCall(2.0f, RequestInterstitialAD);
|
||||
}
|
||||
|
||||
|
||||
// iads_imp
|
||||
protected virtual void OnInterstitialDisplayEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||
{
|
||||
// Analytics.ADIadsImp(adUnitId, _iadsCategory);
|
||||
Analytics.ADIadsImp(AdParams.Build(adUnitId, category: _iadsCategory));
|
||||
AppendImpressionData(adInfo, eventName:Analytics.EventIadsImp, itemCategory:_iadsCategory);
|
||||
}
|
||||
|
||||
protected virtual void OnInterstitialClickEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||
{
|
||||
// Analytics.ADIadsClick(adUnitId, _iadsCategory);
|
||||
Analytics.ADIadsClick(AdParams.Build(adUnitId, category: _iadsCategory));
|
||||
if(string.IsNullOrEmpty(_iadsCategory)) _iadsCategory = "not_set";
|
||||
AppendImpressionData(adInfo,
|
||||
eventName:Analytics.EventIadsClick,
|
||||
itemCategory:_iadsCategory);
|
||||
}
|
||||
|
||||
|
||||
// Close
|
||||
protected virtual void OnInterstitialDismissedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||
{
|
||||
// Interstitial ad is hidden. Pre-load the next ad
|
||||
_interCloseAction?.Invoke();
|
||||
OnInterstitialClosed?.Invoke();
|
||||
// Analytics.ADIadsClose(adUnitId, _iadsCategory);
|
||||
Analytics.ADIadsClose(AdParams.Build(adUnitId, category: _iadsCategory));
|
||||
Analytics.ADIadsClose(new Dictionary<string, object>()
|
||||
{
|
||||
[Analytics.ParameterItemCategory] = _iadsCategory,
|
||||
[Analytics.ParameterDuration] = GetActionDuration(_iadsDisplayStartTime),
|
||||
});
|
||||
|
||||
_impressionDriver.CleanCreativeId(adInfo.CreativeIdentifier);
|
||||
|
||||
//延时加载下一个广告
|
||||
DelayCall(2.0f, RequestInterstitialAD);
|
||||
}
|
||||
|
||||
private void OnInterstitialPaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||
{
|
||||
AppendImpressionData(adInfo, eventName:Analytics.EventIadsPaid, itemCategory: _iadsCategory);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Rewarded Ads
|
||||
|
||||
private string _rewardCategory = "main";
|
||||
private int _rewardRetryAttempt;
|
||||
protected float _radsLoadStartTime;
|
||||
protected DateTime _radsLoadStartTime;
|
||||
protected DateTime _radsShowStartTime;
|
||||
private Action _rvRewardAction;
|
||||
private Action<string> _rvFailAction;
|
||||
private Action _rvDismissAction;
|
||||
|
|
@ -607,7 +646,7 @@ namespace Guru
|
|||
|
||||
public void OnLoadRads()
|
||||
{
|
||||
_radsLoadStartTime = Time.realtimeSinceStartup;
|
||||
_radsLoadStartTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -646,6 +685,8 @@ namespace Guru
|
|||
_rvDismissAction = dismissAction;
|
||||
MaxSdk.ShowRewardedAd(GetRewardedID());
|
||||
|
||||
_radsShowStartTime = DateTime.UtcNow;
|
||||
|
||||
// RequestRewardedAD();
|
||||
}
|
||||
|
||||
|
|
@ -658,8 +699,10 @@ namespace Guru
|
|||
// this.Log("OnRewardedAdLoadedEvent");
|
||||
// Analytics.ADRadsLoaded(adUnitId, GetAdsLoadDuration(ref _radsLoadStartTime), _rewardCategory);
|
||||
Analytics.ADRadsLoaded(AdParams.Build(adUnitId,
|
||||
duration: GetAdsLoadDuration(ref _radsLoadStartTime), category: _iadsCategory));
|
||||
duration: GetActionDuration(_radsLoadStartTime), category: _iadsCategory));
|
||||
_rewardRetryAttempt = 0;
|
||||
|
||||
Debug.Log( $"[SDK][Ads][Loaded] --- adUnitId:{adUnitId} Revenue:{adInfo.Revenue} Type:{adInfo.AdFormat} CreativeId:{adInfo.CreativeIdentifier}");
|
||||
|
||||
OnRewardLoaded?.Invoke();
|
||||
}
|
||||
|
|
@ -674,7 +717,7 @@ namespace Guru
|
|||
$"OnRewardedAdFailedEvent AdLoadFailureInfo:{errorInfo.AdLoadFailureInfo}, Message: {errorInfo.Message}");
|
||||
// Analytics.ADRadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _radsLoadStartTime), _rewardCategory);
|
||||
Analytics.ADRadsFailed(AdParams.Build(adUnitId,
|
||||
duration: GetAdsLoadDuration(ref _radsLoadStartTime), category: _rewardCategory,
|
||||
duration: GetActionDuration(_radsLoadStartTime), category: _rewardCategory,
|
||||
errorCode: (int)errorInfo.Code,
|
||||
waterfallName: errorInfo?.WaterfallInfo?.Name ?? ""));
|
||||
_rewardRetryAttempt++;
|
||||
|
|
@ -692,7 +735,7 @@ namespace Guru
|
|||
$"OnRewardedAdFailedToDisplayEvent AdLoadFailureInfo:{errorInfo.AdLoadFailureInfo}, Message: {errorInfo.Message}");
|
||||
// Analytics.ADRadsFailed(adUnitId, (int)errorInfo.Code, GetAdsLoadDuration(ref _radsLoadStartTime), _rewardCategory);
|
||||
Analytics.ADRadsFailed(AdParams.Build(adUnitId,
|
||||
duration: GetAdsLoadDuration(ref _radsLoadStartTime), category: _rewardCategory,
|
||||
duration: GetActionDuration(_radsShowStartTime), category: _rewardCategory,
|
||||
errorCode: (int)errorInfo.Code,
|
||||
waterfallName: errorInfo?.WaterfallInfo?.Name ?? ""));
|
||||
_rvFailAction?.Invoke("OnRewardedAdFailedToDisplayEvent");
|
||||
|
|
@ -705,16 +748,17 @@ namespace Guru
|
|||
{
|
||||
this.Log("OnRewardedAdDisplayedEvent");
|
||||
// Analytics.ADRadsImp(adUnitId, _rewardCategory);
|
||||
Analytics.ADRadsImp(AdParams.Build(adUnitId, category: _rewardCategory));
|
||||
AppendImpressionData(adInfo, eventName:Analytics.EventRadsImp, itemCategory: _rewardCategory);
|
||||
}
|
||||
|
||||
protected virtual void OnRewardedAdClickedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||
{
|
||||
this.Log("OnRewardedAdClickedEvent");
|
||||
// Analytics.ADRadsClick(adUnitId, _rewardCategory);
|
||||
Analytics.ADRadsClick(AdParams.Build(adUnitId, category: _rewardCategory));
|
||||
AppendImpressionData(adInfo, eventName:Analytics.EventRadsClick, itemCategory: _rewardCategory);
|
||||
}
|
||||
|
||||
|
||||
// rads_close
|
||||
protected virtual void OnRewardedAdDismissedEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||
{
|
||||
this.Log("OnRewardedAdDismissedEvent");
|
||||
|
|
@ -723,24 +767,36 @@ namespace Guru
|
|||
OnRewardClosed?.Invoke();
|
||||
|
||||
// Analytics.ADRadsClose(adUnitId, _rewardCategory);
|
||||
Analytics.ADRadsClose(AdParams.Build(adUnitId, category: _rewardCategory));
|
||||
Analytics.ADRadsClose(new Dictionary<string, object>()
|
||||
{
|
||||
[Analytics.ParameterItemCategory] = _rewardCategory,
|
||||
[Analytics.ParameterDuration] = GetActionDuration(_radsShowStartTime),
|
||||
});
|
||||
|
||||
_impressionDriver.CleanCreativeId(adInfo.CreativeIdentifier);
|
||||
|
||||
//延时加载下一个广告
|
||||
DelayCall(2.0f, RequestRewardedAD);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// rads_rewarded
|
||||
protected virtual void OnRewardedAdReceivedRewardEvent(string adUnitId, MaxSdk.Reward reward,
|
||||
MaxSdkBase.AdInfo arg3)
|
||||
MaxSdkBase.AdInfo adInfo)
|
||||
{
|
||||
this.Log("OnRewardedAdReceivedRewardEvent");
|
||||
// Analytics.ADRadsRewarded(adUnitId, _rewardCategory);
|
||||
Analytics.ADRadsRewarded(AdParams.Build(adUnitId, category: _rewardCategory));
|
||||
// Rewarded ad was displayed and user should receive the reward
|
||||
AppendImpressionData(adInfo, eventName:Analytics.EventRadsRewarded, itemCategory: _rewardCategory);
|
||||
_rvRewardAction?.Invoke();
|
||||
}
|
||||
|
||||
// rads_paid
|
||||
private void OnRewardedAdPaidEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
|
||||
{
|
||||
this.Log("OnRewardedAdReceivedRewardEvent");
|
||||
AppendImpressionData(adInfo, eventName:Analytics.EventRadsPaid, itemCategory: _rewardCategory);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Ad Settings
|
||||
|
|
@ -782,5 +838,87 @@ namespace Guru
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ImpressionData
|
||||
|
||||
const int MAX_BADS_CID_NUMBER = 6;
|
||||
private List<string> _badsCreativeIds = new List<string>(MAX_BADS_CID_NUMBER);
|
||||
|
||||
/// <summary>
|
||||
/// 构建 Impression 数据
|
||||
/// </summary>
|
||||
/// <param name="adInfo"></param>
|
||||
/// <param name="reviewCreativeId"></param>
|
||||
/// <param name="platform"></param>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="itemCategory"></param>
|
||||
/// <param name="duration"></param>
|
||||
/// <returns></returns>
|
||||
private AdImpressionData CreateImpressionData(MaxSdkBase.AdInfo adInfo,
|
||||
string reviewCreativeId = "", string platform = "",
|
||||
string eventName = "", string itemCategory = "", int duration = 0)
|
||||
{
|
||||
var impression = AdImpressionDriver.Build(adInfo.Revenue, Analytics.USD, platform,
|
||||
adInfo.NetworkName,
|
||||
adInfo.AdFormat,
|
||||
adInfo.AdUnitIdentifier,
|
||||
adInfo.NetworkPlacement,
|
||||
adInfo.CreativeIdentifier, reviewCreativeId,
|
||||
eventName, itemCategory, duration);
|
||||
|
||||
return impression;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加一条ImpressionData 数据
|
||||
/// </summary>
|
||||
/// <param name="adInfo"></param>
|
||||
/// <param name="reviewCreativeId"></param>
|
||||
/// <param name="platform"></param>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="itemCategory"></param>
|
||||
/// <param name="duration"></param>
|
||||
/// <returns></returns>
|
||||
private void AppendImpressionData(MaxSdkBase.AdInfo adInfo, string reviewCreativeId = "", string platform = "", string eventName = "", string itemCategory = "", int duration = 0)
|
||||
{
|
||||
var data = CreateImpressionData(adInfo, reviewCreativeId, platform, eventName, itemCategory, duration);
|
||||
_impressionDriver.Append(data);
|
||||
}
|
||||
|
||||
/// <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 (string.IsNullOrEmpty(adInfo.CreativeIdentifier))
|
||||
{
|
||||
Debug.LogError($"{Tag} --- Get ReviewCreativeId:{reviewCreativeId} but CreativeIdentifier is null");
|
||||
return;
|
||||
}
|
||||
|
||||
_impressionDriver.SetReviewCreativeId(adInfo.CreativeIdentifier, reviewCreativeId); // 缓存 ReviewCreateId
|
||||
|
||||
if (adUnitId == GetBannerID() || adInfo.AdFormat.ToUpper().Contains("BANNER"))
|
||||
{
|
||||
// 清理 BADS CID 缓存
|
||||
_badsCreativeIds.Add(adInfo.CreativeIdentifier);
|
||||
if (_badsCreativeIds.Count > MAX_BADS_CID_NUMBER)
|
||||
{
|
||||
var cid = _badsCreativeIds[0];
|
||||
_badsCreativeIds.Remove(cid);
|
||||
_impressionDriver.CleanCreativeId(cid);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1866d6a2a7d7447b867e491b9354a49b
|
||||
timeCreated: 1722313457
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
|
||||
|
||||
|
||||
namespace Guru.Ads
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// AdImpression 对象
|
||||
/// </summary>
|
||||
public class AdImpressionData
|
||||
{
|
||||
private const int MAX_VALUE_LENGTH = 96;
|
||||
|
||||
public double value;
|
||||
public string currency = "USD";
|
||||
public string ad_platform = "MAX";
|
||||
public string ad_source;
|
||||
public string ad_format;
|
||||
public string ad_unit_name;
|
||||
public string ad_placement;
|
||||
public string ad_creative_id;
|
||||
public string review_creative_id;
|
||||
public string event_name;
|
||||
public DateTime createTime;
|
||||
public string item_category;
|
||||
public int duration;
|
||||
|
||||
public AdImpressionData()
|
||||
{
|
||||
createTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"[AdImpressionData] ad_unit_name:{ad_unit_name} value:{value} currency:{currency} ad_platform:{ad_platform} ad_source:{ad_source} ad_format:{ad_format} ad_placement:{ad_placement} ad_creative_id:{ad_creative_id} review_creative_id:{review_creative_id} event_name:{event_name} duration:{duration} item_category:{item_category}";
|
||||
}
|
||||
|
||||
|
||||
public bool EqualsCreativeId(string cid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(cid)) return false;
|
||||
return ad_creative_id.Equals(cid);
|
||||
}
|
||||
|
||||
public bool EqualsReviewCreativeId(string rcid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(rcid)) return false;
|
||||
return review_creative_id.Equals(rcid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置 CreativeId
|
||||
/// </summary>
|
||||
/// <param name="creativeId"></param>
|
||||
public void SetCreativeId(string creativeId)
|
||||
{
|
||||
ad_creative_id = FixStringLength(creativeId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置 ReviewCreativeId
|
||||
/// </summary>
|
||||
/// <param name="reviewCreativeId"></param>
|
||||
public void SetReviewCreativeId(string reviewCreativeId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(reviewCreativeId)) return;
|
||||
review_creative_id = FixStringLength(reviewCreativeId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 限制字符串长度为 96
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
private string FixStringLength(string source)
|
||||
{
|
||||
return source.Length <= MAX_VALUE_LENGTH ? source : source.Substring(0, MAX_VALUE_LENGTH);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取自创建开始经过的秒数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public double GetPassedSecond()
|
||||
{
|
||||
return (DateTime.UtcNow - createTime).TotalSeconds;
|
||||
}
|
||||
|
||||
|
||||
public Dictionary<string, object> BuildEventData()
|
||||
{
|
||||
var data = new Dictionary<string, object>()
|
||||
{
|
||||
{ "value", value },
|
||||
{ "currency", currency },
|
||||
{ "ad_platform", ad_platform },
|
||||
{ "ad_format", ad_format },
|
||||
{ "ad_source", ad_source },
|
||||
{ "ad_unit_name", ad_unit_name },
|
||||
{ "ad_placement", ad_placement },
|
||||
{ "ad_creative_id", ad_creative_id },
|
||||
{ "review_creative_id", review_creative_id },
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public Dictionary<string, object> BuildEventAdImpData()
|
||||
{
|
||||
var data = new Dictionary<string, object>()
|
||||
{
|
||||
{ "ad_platform", ad_platform },
|
||||
{ "ad_source", ad_source },
|
||||
{ "ad_unit_name", ad_unit_name },
|
||||
{ "ad_placement", ad_placement },
|
||||
{ "ad_creative_id", ad_creative_id },
|
||||
{ "review_creative_id", review_creative_id },
|
||||
{ "item_category", item_category}
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> BuildEventAdClickData()
|
||||
{
|
||||
var data = new Dictionary<string, object>()
|
||||
{
|
||||
{ "value", value },
|
||||
{ "currency", currency },
|
||||
{ "ad_platform", ad_platform },
|
||||
{ "ad_source", ad_source },
|
||||
{ "ad_unit_name", ad_unit_name },
|
||||
{ "ad_placement", ad_placement },
|
||||
{ "ad_creative_id", ad_creative_id },
|
||||
{ "review_creative_id", review_creative_id },
|
||||
{ "item_category", item_category}
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> BuildEventAdPaidData()
|
||||
{
|
||||
var data = new Dictionary<string, object>()
|
||||
{
|
||||
{ "value", value },
|
||||
{ "currency", currency },
|
||||
{ "ad_platform", ad_platform },
|
||||
{ "ad_source", ad_source },
|
||||
{ "ad_unit_name", ad_unit_name },
|
||||
{ "ad_placement", ad_placement },
|
||||
{ "ad_creative_id", ad_creative_id },
|
||||
{ "review_creative_id", review_creative_id },
|
||||
{ "item_category", item_category}
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> BuildEventAdRewardedData()
|
||||
{
|
||||
var data = new Dictionary<string, object>()
|
||||
{
|
||||
{ "value", value },
|
||||
{ "currency", currency },
|
||||
{ "ad_platform", ad_platform },
|
||||
{ "ad_source", ad_source },
|
||||
{ "ad_unit_name", ad_unit_name },
|
||||
{ "ad_placement", ad_placement },
|
||||
{ "ad_creative_id", ad_creative_id },
|
||||
{ "review_creative_id", review_creative_id },
|
||||
{ "item_category", item_category}
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1aca2a4507b94dfe9f88040125708edb
|
||||
timeCreated: 1721883318
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
|
||||
|
||||
namespace Guru.Ads
|
||||
{
|
||||
// using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
public class AdImpressionDriver
|
||||
{
|
||||
private const string Tag = "[SDK][ADS]";
|
||||
private const double NEED_FLUSH_TIME = 40.0; // 单条 Impression data 存在的最大间隔时间(秒)
|
||||
private List<AdImpressionData> _impressionData; // 所有缓存待上报的 impression data
|
||||
private Dictionary<string, string> _savedReviewCreativeIds;
|
||||
|
||||
private Action<AdImpressionData> _onReportAdsRevenue;
|
||||
|
||||
|
||||
public static AdImpressionData Build(double value, string currency,
|
||||
string adPlatform, string adSource, string adFormat,
|
||||
string adUnitName, string adPlacement, string adCreativeID, string reviewCreativeID,
|
||||
string eventName = "", string itemCategory = "", int duration = 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(adPlatform)) adPlatform = Analytics.AdMAX;
|
||||
if (string.IsNullOrEmpty(itemCategory)) itemCategory = "not_set";
|
||||
if (string.IsNullOrEmpty(eventName)) eventName = Analytics.EventAdImpression;
|
||||
|
||||
var data = new AdImpressionData()
|
||||
{
|
||||
value = value,
|
||||
currency = currency,
|
||||
ad_platform = adPlatform,
|
||||
ad_source = adSource,
|
||||
ad_format = adFormat,
|
||||
ad_unit_name = adUnitName,
|
||||
ad_placement = adPlacement,
|
||||
ad_creative_id = adCreativeID,
|
||||
event_name = eventName,
|
||||
item_category = itemCategory,
|
||||
duration = duration,
|
||||
};
|
||||
|
||||
data.SetCreativeId(adCreativeID);
|
||||
data.SetReviewCreativeId(reviewCreativeID);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
public void Init(Action<AdImpressionData> onReportRevenue)
|
||||
{
|
||||
_impressionData = new List<AdImpressionData>(20);
|
||||
_savedReviewCreativeIds = new Dictionary<string, string>(100);
|
||||
|
||||
_onReportAdsRevenue = onReportRevenue;
|
||||
}
|
||||
|
||||
|
||||
public bool IsCreativeIdExists(string creativeId) => _savedReviewCreativeIds.ContainsKey(creativeId);
|
||||
|
||||
public void SetReviewCreativeId(string creativeId, string reviewCreativeId)
|
||||
{
|
||||
bool isCidExists = IsCreativeIdExists(creativeId);
|
||||
_savedReviewCreativeIds[creativeId] = reviewCreativeId;
|
||||
|
||||
if (isCidExists && !string.IsNullOrEmpty(reviewCreativeId))
|
||||
{
|
||||
FlushAllImpressionData(creativeId, reviewCreativeId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 强制发送相关的数据
|
||||
/// </summary>
|
||||
/// <param name="creativeId"></param>
|
||||
public void CleanCreativeId(string creativeId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(creativeId)) return;
|
||||
|
||||
if (IsCreativeIdExists(creativeId))
|
||||
{
|
||||
FlushAllImpressionData(creativeId, "", true);
|
||||
}
|
||||
RemoveCreativeId(creativeId); //清理对应的 createId
|
||||
}
|
||||
|
||||
|
||||
private string GetReviewCreativeId(string creativeId)
|
||||
{
|
||||
if(string.IsNullOrEmpty(creativeId)) return "";
|
||||
return _savedReviewCreativeIds.GetValueOrDefault(creativeId, "");
|
||||
}
|
||||
|
||||
|
||||
public void RemoveCreativeId(string creativeId)
|
||||
{
|
||||
if (IsCreativeIdExists(creativeId))
|
||||
{
|
||||
_savedReviewCreativeIds.Remove(creativeId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加一条Impression数据
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
public void Append(AdImpressionData data)
|
||||
{
|
||||
if (CanFlushData(data))
|
||||
{
|
||||
// 立即触发数据
|
||||
FlushImpressionData(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IsCreativeIdExists(data.ad_creative_id))
|
||||
{
|
||||
SetReviewCreativeId(data.ad_creative_id, "");
|
||||
}
|
||||
|
||||
// 缓存数据
|
||||
PushImpressionData(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void PushImpressionData(AdImpressionData data)
|
||||
{
|
||||
_impressionData.Add(data);
|
||||
}
|
||||
|
||||
|
||||
private bool CanFlushData(AdImpressionData data)
|
||||
{
|
||||
// #1 如果超时, 强制上报
|
||||
if (data.GetPassedSecond() > NEED_FLUSH_TIME) return true;
|
||||
// #2 如果 cid 和 rcid 都赋值了 则上报
|
||||
if (!string.IsNullOrEmpty(data.review_creative_id)) return true;
|
||||
// #3 如果 rcid 为空, 但是可以找到,也上报
|
||||
var rcid = GetReviewCreativeId(data.ad_creative_id);
|
||||
if (!string.IsNullOrEmpty(rcid))
|
||||
{
|
||||
data.SetReviewCreativeId(rcid);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 触发所有相关的 cid 和 reviewCreateId
|
||||
/// </summary>
|
||||
/// <param name="creativeId"></param>
|
||||
/// <param name="reviewCreativeId"></param>
|
||||
/// <param name="force">强制触发</param>
|
||||
private void FlushAllImpressionData(string creativeId, string reviewCreativeId = "", bool force = false)
|
||||
{
|
||||
List<AdImpressionData> tmp = new List<AdImpressionData>(_impressionData.Count);
|
||||
|
||||
if(string.IsNullOrEmpty(reviewCreativeId)) reviewCreativeId = GetReviewCreativeId(creativeId); //获取 reviewCreativeId
|
||||
|
||||
foreach(var data in _impressionData)
|
||||
{
|
||||
if (data.EqualsCreativeId(creativeId))
|
||||
{
|
||||
data.SetReviewCreativeId(reviewCreativeId);
|
||||
if (CanFlushData(data) || force)
|
||||
{
|
||||
FlushImpressionData(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp.Add(data);
|
||||
}
|
||||
}
|
||||
else if (CanFlushData(data))
|
||||
{
|
||||
FlushImpressionData(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
_impressionData = tmp;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 输出一个 Impression 事件
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
private void FlushImpressionData(AdImpressionData data)
|
||||
{
|
||||
Debug.Log($"{Tag} --- FlushImpressionData: {data}");
|
||||
switch (data.event_name)
|
||||
{
|
||||
case Analytics.EventBadsPaid:
|
||||
// BADS 收入事件
|
||||
// BADS 尚未统计 bads_paid 打点
|
||||
_onReportAdsRevenue?.Invoke(data);
|
||||
break;
|
||||
|
||||
case Analytics.EventIadsImp:
|
||||
Analytics.ADIadsImp(data.BuildEventAdImpData());
|
||||
break;
|
||||
|
||||
case Analytics.EventIadsClick:
|
||||
Analytics.ADIadsClick(data.BuildEventAdClickData());
|
||||
break;
|
||||
|
||||
case Analytics.EventIadsPaid:
|
||||
// IADS 收入事件
|
||||
Analytics.ADIadsPaid(data.BuildEventAdPaidData());
|
||||
_onReportAdsRevenue?.Invoke(data);
|
||||
break;
|
||||
|
||||
case Analytics.EventRadsImp:
|
||||
Analytics.ADRadsImp(data.BuildEventAdImpData());
|
||||
break;
|
||||
|
||||
case Analytics.EventRadsClick:
|
||||
Analytics.ADRadsClick(data.BuildEventAdClickData());
|
||||
break;
|
||||
|
||||
case Analytics.EventRadsRewarded:
|
||||
Analytics.ADRadsRewarded(data.BuildEventAdRewardedData());
|
||||
break;
|
||||
|
||||
case Analytics.EventRadsPaid:
|
||||
// RADS 收入事件
|
||||
Analytics.ADRadsPaid(data.BuildEventAdPaidData());
|
||||
_onReportAdsRevenue?.Invoke(data);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7194cdd8ed1447508011264371e2c23d
|
||||
timeCreated: 1722313472
|
||||
|
|
@ -22,7 +22,7 @@ namespace Guru
|
|||
}
|
||||
}
|
||||
|
||||
private static AdjustEvent CreateAdjustEvent(string eventName)
|
||||
internal static AdjustEvent CreateAdjustEvent(string eventName)
|
||||
{
|
||||
string tokenID = GetAdjustEventToken(eventName);
|
||||
if (string.IsNullOrEmpty(tokenID))
|
||||
|
|
|
|||
|
|
@ -36,15 +36,37 @@ namespace Guru
|
|||
|
||||
if (adParams.duration > 0)
|
||||
data[ParameterDuration] = adParams.duration;
|
||||
|
||||
if (adParams.errorCode != 0)
|
||||
data[ParameterErrorCode] = adParams.errorCode;
|
||||
|
||||
if (!string.IsNullOrEmpty(adParams.networkName))
|
||||
data[ParameterNetworkName] = adParams.networkName;
|
||||
if (!string.IsNullOrEmpty(adParams.networkPlacement))
|
||||
|
||||
if (!string.IsNullOrEmpty(adParams.networkPlacement))
|
||||
{
|
||||
data[ParameterNetworkPlacement] = adParams.networkPlacement;
|
||||
data[ParameterAdPlacement] = adParams.networkPlacement;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(adParams.waterfallName))
|
||||
data[ParameterWaterfall] = adParams.waterfallName;
|
||||
|
||||
if (!string.IsNullOrEmpty(adParams.creativeId))
|
||||
data[ParameterAdCreativeId] = adParams.creativeId;
|
||||
|
||||
if (!string.IsNullOrEmpty(adParams.reviewCreativeId))
|
||||
data[ParameterReviewCreativeId] = adParams.reviewCreativeId;
|
||||
|
||||
if (!string.IsNullOrEmpty(adParams.adPlatform))
|
||||
data[ParameterAdPlatform] = adParams.adPlatform;
|
||||
|
||||
if (!string.IsNullOrEmpty(adParams.adSource))
|
||||
data[ParameterAdSource] = adParams.adSource;
|
||||
|
||||
if (!string.IsNullOrEmpty(adParams.adFormat))
|
||||
data[ParameterAdFormat] = adParams.adFormat;
|
||||
|
||||
if (extra != null && extra.Count > 0)
|
||||
{
|
||||
foreach (var k in extra.Keys)
|
||||
|
|
@ -59,26 +81,26 @@ namespace Guru
|
|||
//---------------------- BANNER -------------------------
|
||||
public static void ADBadsLoad(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventBadsLoad, BuildAdEventData(adParams));
|
||||
TrackEvent(EventBadsLoad, BuildAdEventData(adParams));
|
||||
}
|
||||
public static void ADBadsLoaded(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventBadsLoaded, BuildAdEventData(adParams));
|
||||
TrackEvent(EventBadsLoaded, BuildAdEventData(adParams));
|
||||
}
|
||||
public static void ADBadsFailed(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventBadsFailed, BuildAdEventData(adParams));
|
||||
TrackEvent(EventBadsFailed, BuildAdEventData(adParams));
|
||||
}
|
||||
/// <summary>
|
||||
/// 广告点击
|
||||
/// </summary>
|
||||
public static void ADBadsClick(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventBadsClick, BuildAdEventData(adParams));
|
||||
TrackEvent(EventBadsClick, BuildAdEventData(adParams));
|
||||
}
|
||||
public static void ADBadsImp(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventBadsImp, BuildAdEventData(adParams));
|
||||
TrackEvent(EventBadsImp, BuildAdEventData(adParams));
|
||||
}
|
||||
|
||||
public static void ADBadsHide( int loadedTimes, int failTimes)
|
||||
|
|
@ -88,7 +110,7 @@ namespace Guru
|
|||
["loaded_times"] = loadedTimes,
|
||||
["fail_times"] = failTimes
|
||||
};
|
||||
LogEvent(EventBadsHide, dict);
|
||||
TrackEvent(EventBadsHide, dict);
|
||||
}
|
||||
//---------------------- INTERSTITIAL -------------------------
|
||||
/// <summary>
|
||||
|
|
@ -96,7 +118,7 @@ namespace Guru
|
|||
/// </summary>
|
||||
public static void ADIadsLoad(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventIadsLoad, BuildAdEventData(adParams));
|
||||
TrackEvent(EventIadsLoad, BuildAdEventData(adParams));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -104,7 +126,7 @@ namespace Guru
|
|||
/// </summary>
|
||||
public static void ADIadsLoaded(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventIadsLoaded, BuildAdEventData(adParams));
|
||||
TrackEvent(EventIadsLoaded, BuildAdEventData(adParams));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -112,7 +134,7 @@ namespace Guru
|
|||
/// </summary>
|
||||
public static void ADIadsFailed(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventIadsFailed, BuildAdEventData(adParams));
|
||||
TrackEvent(EventIadsFailed, BuildAdEventData(adParams));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -120,7 +142,12 @@ namespace Guru
|
|||
/// </summary>
|
||||
public static void ADIadsImp(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventIadsImp, BuildAdEventData(adParams));
|
||||
ADIadsImp(BuildAdEventData(adParams));
|
||||
}
|
||||
|
||||
public static void ADIadsImp(Dictionary<string, dynamic> data)
|
||||
{
|
||||
TrackEvent(EventIadsImp, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -128,7 +155,12 @@ namespace Guru
|
|||
/// </summary>
|
||||
public static void ADIadsClick(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventIadsClick, BuildAdEventData(adParams));
|
||||
ADIadsClick(BuildAdEventData(adParams));
|
||||
}
|
||||
|
||||
public static void ADIadsClick(Dictionary<string, object> data)
|
||||
{
|
||||
TrackEvent(EventIadsClick, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -136,7 +168,21 @@ namespace Guru
|
|||
/// </summary>
|
||||
public static void ADIadsClose(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventIadsClose, BuildAdEventData(adParams));
|
||||
ADIadsClose(BuildAdEventData(adParams));
|
||||
}
|
||||
|
||||
public static void ADIadsClose(Dictionary<string, object> data)
|
||||
{
|
||||
TrackEvent(EventIadsClose, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 插屏广告收到奖励
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
public static void ADIadsPaid(Dictionary<string, object> data)
|
||||
{
|
||||
TrackEvent(EventIadsPaid, data);
|
||||
}
|
||||
|
||||
//---------------------- REWARDS -------------------------
|
||||
|
|
@ -145,36 +191,48 @@ namespace Guru
|
|||
/// </summary>
|
||||
public static void ADRadsLoad(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventRadsLoad, BuildAdEventData(adParams));
|
||||
TrackEvent(EventRadsLoad, BuildAdEventData(adParams));
|
||||
}
|
||||
/// <summary>
|
||||
/// 广告拉取成功
|
||||
/// </summary>
|
||||
public static void ADRadsLoaded(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventRadsLoaded, BuildAdEventData(adParams));
|
||||
TrackEvent(EventRadsLoaded, BuildAdEventData(adParams));
|
||||
}
|
||||
/// <summary>
|
||||
/// 广告拉取失败
|
||||
/// </summary>
|
||||
public static void ADRadsFailed(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventRadsFailed, BuildAdEventData(adParams));
|
||||
TrackEvent(EventRadsFailed, BuildAdEventData(adParams));
|
||||
}
|
||||
/// <summary>
|
||||
/// 广告展示
|
||||
/// </summary>
|
||||
public static void ADRadsImp(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventRadsImp, BuildAdEventData(adParams));
|
||||
ADRadsImp(BuildAdEventData(adParams));
|
||||
}
|
||||
|
||||
public static void ADRadsImp(Dictionary<string, dynamic> data)
|
||||
{
|
||||
TrackEvent(EventRadsImp, data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 广告完成观看发奖励
|
||||
/// </summary>
|
||||
public static void ADRadsRewarded(AdParams adParams)
|
||||
{
|
||||
var data = BuildAdEventData(adParams);
|
||||
LogEvent(EventRadsRewarded, data);
|
||||
ADRadsRewarded(BuildAdEventData(adParams));
|
||||
}
|
||||
|
||||
public static void ADRadsRewarded(Dictionary<string, object> data)
|
||||
{
|
||||
TrackEvent(EventRadsRewarded, data);
|
||||
|
||||
if (RadsRewardCount == 0)
|
||||
{
|
||||
|
|
@ -183,6 +241,15 @@ namespace Guru
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 插屏广告收到奖励
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
public static void ADRadsPaid(Dictionary<string, object> data)
|
||||
{
|
||||
TrackEvent(EventRadsPaid, data);
|
||||
}
|
||||
|
||||
|
||||
private static int RadsRewardCount
|
||||
{
|
||||
|
|
@ -195,7 +262,7 @@ namespace Guru
|
|||
/// </summary>
|
||||
public static void ADRadsFirstRewarded(Dictionary<string, object> data)
|
||||
{
|
||||
LogEvent(EventFirstRadsRewarded, data);
|
||||
TrackEvent(EventFirstRadsRewarded, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -203,7 +270,12 @@ namespace Guru
|
|||
/// </summary>
|
||||
public static void ADRadsClick(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventRadsClick, BuildAdEventData(adParams));
|
||||
ADRadsClick(BuildAdEventData(adParams));
|
||||
}
|
||||
|
||||
public static void ADRadsClick(Dictionary<string, object> data)
|
||||
{
|
||||
TrackEvent(EventRadsClick, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -211,7 +283,12 @@ namespace Guru
|
|||
/// </summary>
|
||||
public static void ADRadsClose(AdParams adParams)
|
||||
{
|
||||
LogEvent(EventRadsClose, BuildAdEventData(adParams));
|
||||
ADRadsClose( BuildAdEventData(adParams));
|
||||
}
|
||||
|
||||
public static void ADRadsClose(Dictionary<string, dynamic> data)
|
||||
{
|
||||
TrackEvent(EventRadsClose, data);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
|
@ -235,7 +312,6 @@ namespace Guru
|
|||
{ "type", type }
|
||||
};
|
||||
if(!string.IsNullOrEmpty(scene)) dict[ParameterItemName] = scene;
|
||||
LogEvent(EventATTResult, dict);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -261,10 +337,15 @@ namespace Guru
|
|||
public string category;
|
||||
public string networkName;
|
||||
public string networkPlacement;
|
||||
public string adPlatform;
|
||||
public string adSource;
|
||||
public string adFormat;
|
||||
public string waterfallName;
|
||||
public string adUnitId;
|
||||
public int errorCode = 0;
|
||||
public int duration = 0;
|
||||
public string creativeId;
|
||||
public string reviewCreativeId;
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -276,31 +357,47 @@ namespace Guru
|
|||
/// <param name="duration"></param>
|
||||
/// <param name="errorCode"></param>
|
||||
/// <param name="waterfallName"></param>
|
||||
/// <param name="reviewCreativeId"></param>
|
||||
/// <param name="adPlatform"></param>
|
||||
/// <returns></returns>
|
||||
public static AdParams Build(string adUnitId, MaxSdkBase.AdInfo adInfo = null, string category = "",
|
||||
int duration = 0, int errorCode = 0, string waterfallName = "")
|
||||
int duration = 0, int errorCode = 0, string waterfallName = "", string reviewCreativeId = "", string adPlatform = "")
|
||||
{
|
||||
if (string.IsNullOrEmpty(adUnitId) && adInfo != null) adUnitId = adInfo.AdUnitIdentifier;
|
||||
var networkName = "";
|
||||
var networkPlacement = "";
|
||||
var creativeId = "";
|
||||
var adSource = "";
|
||||
var adFormart = "";
|
||||
|
||||
if (string.IsNullOrEmpty(adPlatform)) adPlatform = Analytics.AdMAX;
|
||||
if (adInfo != null)
|
||||
{
|
||||
networkName = adInfo.NetworkName;
|
||||
networkPlacement = adInfo.NetworkPlacement;
|
||||
creativeId = adInfo.CreativeIdentifier;
|
||||
adSource = adInfo.NetworkName;
|
||||
adFormart = adInfo.AdFormat;
|
||||
|
||||
if (string.IsNullOrEmpty(waterfallName))
|
||||
waterfallName = adInfo.WaterfallInfo?.Name ?? "";
|
||||
|
||||
}
|
||||
|
||||
var p = new AdParams()
|
||||
{
|
||||
adUnitId = adUnitId,
|
||||
adPlatform = adPlatform,
|
||||
adSource = adSource,
|
||||
adFormat = adFormart,
|
||||
duration = duration,
|
||||
networkName = networkName,
|
||||
networkPlacement = networkPlacement,
|
||||
waterfallName = waterfallName,
|
||||
category = category,
|
||||
errorCode = errorCode,
|
||||
creativeId = creativeId,
|
||||
reviewCreativeId = reviewCreativeId,
|
||||
};
|
||||
return p;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,112 +11,119 @@ namespace Guru
|
|||
//打点常量定义
|
||||
public static partial class Analytics
|
||||
{
|
||||
public static readonly string TAG = "Analytics";
|
||||
public const string TAG = "Analytics";
|
||||
// 美元符号
|
||||
public static readonly string USD = "USD";
|
||||
public const string USD = "USD";
|
||||
// 广告平台
|
||||
public static readonly string AdMAX = "MAX";
|
||||
public const string AdMAX = "MAX";
|
||||
public const string AdIronSource = "IronSource";
|
||||
|
||||
//IAP打点事件
|
||||
public static readonly string EventIAPFirst = "first_iap";
|
||||
public static readonly string EventIAPImp = "iap_imp";
|
||||
public static readonly string EventIAPClose = "iap_close";
|
||||
public static readonly string EventIAPClick = "iap_clk";
|
||||
public static readonly string EventIAPReturnTrue = "iap_ret_true";
|
||||
public static readonly string EventIAPReturnFalse = "iap_ret_false";
|
||||
public const string EventIAPFirst = "first_iap";
|
||||
public const string EventIAPImp = "iap_imp";
|
||||
public const string EventIAPClose = "iap_close";
|
||||
public const string EventIAPClick = "iap_clk";
|
||||
public const string EventIAPReturnTrue = "iap_ret_true";
|
||||
public const string EventIAPReturnFalse = "iap_ret_false";
|
||||
|
||||
// 关卡打点
|
||||
public static readonly string EventLevelFirstEnd = "level_first_end";
|
||||
public const string EventLevelFirstEnd = "level_first_end";
|
||||
|
||||
//横幅广告打点事件
|
||||
public static readonly string EventBadsLoad = "bads_load";
|
||||
public static readonly string EventBadsLoaded = "bads_loaded";
|
||||
public static readonly string EventBadsFailed = "bads_failed";
|
||||
public static readonly string EventBadsClick = "bads_clk";
|
||||
public static readonly string EventBadsImp = "bads_imp";
|
||||
public static readonly string EventBadsHide = "bads_hide";
|
||||
public const string EventBadsLoad = "bads_load";
|
||||
public const string EventBadsLoaded = "bads_loaded";
|
||||
public const string EventBadsFailed = "bads_failed";
|
||||
public const string EventBadsClick = "bads_clk";
|
||||
public const string EventBadsImp = "bads_imp";
|
||||
public const string EventBadsHide = "bads_hide";
|
||||
public const string EventBadsPaid = "bads_paid";
|
||||
|
||||
//插屏广告打点事件
|
||||
public static readonly string EventIadsLoad = "iads_load";
|
||||
public static readonly string EventIadsLoaded = "iads_loaded";
|
||||
public static readonly string EventIadsFailed = "iads_failed";
|
||||
public static readonly string EventIadsImp = "iads_imp";
|
||||
public static readonly string EventIadsClick = "iads_clk";
|
||||
public static readonly string EventIadsClose = "iads_close";
|
||||
public const string EventIadsLoad = "iads_load";
|
||||
public const string EventIadsLoaded = "iads_loaded";
|
||||
public const string EventIadsFailed = "iads_failed";
|
||||
public const string EventIadsImp = "iads_imp";
|
||||
public const string EventIadsClick = "iads_clk";
|
||||
public const string EventIadsClose = "iads_close";
|
||||
public const string EventIadsPaid = "iads_paid";
|
||||
|
||||
//激励视频广告打点事件
|
||||
public static readonly string EventRadsLoad = "rads_load";
|
||||
public static readonly string EventRadsLoaded = "rads_loaded";
|
||||
public static readonly string EventRadsFailed = "rads_failed";
|
||||
public static readonly string EventRadsImp = "rads_imp";
|
||||
public static readonly string EventRadsRewarded = "rads_rewarded";
|
||||
public static readonly string EventRadsClick = "rads_clk";
|
||||
public static readonly string EventRadsClose = "rads_close";
|
||||
public static readonly string EventFirstRadsRewarded = "first_rads_rewarded";
|
||||
public const string EventRadsLoad = "rads_load";
|
||||
public const string EventRadsLoaded = "rads_loaded";
|
||||
public const string EventRadsFailed = "rads_failed";
|
||||
public const string EventRadsImp = "rads_imp";
|
||||
public const string EventRadsRewarded = "rads_rewarded";
|
||||
public const string EventRadsClick = "rads_clk";
|
||||
public const string EventRadsClose = "rads_close";
|
||||
public const string EventRadsPaid = "rads_paid";
|
||||
public const string EventFirstRadsRewarded = "first_rads_rewarded";
|
||||
|
||||
//广告收益打点事件
|
||||
public static readonly string EventTchAdRev001Impression = "tch_ad_rev_roas_001";
|
||||
public static readonly string EventTchAdRev02Impression = "tch_ad_rev_roas_02";
|
||||
public static readonly string EventTchAdRevAbnormal = "tch_ad_rev_value_abnormal";
|
||||
public const string EventTchAdRev001Impression = "tch_ad_rev_roas_001";
|
||||
public const string EventTchAdRev02Impression = "tch_ad_rev_roas_02";
|
||||
public const string EventTchAdRevAbnormal = "tch_ad_rev_value_abnormal";
|
||||
|
||||
|
||||
//内购成功事件上报
|
||||
public static readonly string EventIAPPurchase = "iap_purchase";
|
||||
public static readonly string EventSubPurchase = "sub_purchase";
|
||||
public static readonly string IAPStoreCategory = "Store";
|
||||
public static readonly string IAPTypeProduct = "product";
|
||||
public static readonly string IAPTypeSubscription = "subscription";
|
||||
public const string EventIAPPurchase = "iap_purchase";
|
||||
public const string EventSubPurchase = "sub_purchase";
|
||||
public const string IAPStoreCategory = "Store";
|
||||
public const string IAPTypeProduct = "product";
|
||||
public const string IAPTypeSubscription = "subscription";
|
||||
|
||||
//打点参数名
|
||||
public static readonly string ParameterResult = "result";
|
||||
public static readonly string ParameterStep = "step";
|
||||
public static readonly string ParameterDuration = "duration";
|
||||
public static readonly string ParameterErrorCode = "error_code";
|
||||
public static readonly string ParameterProductId = "product_id";
|
||||
public static readonly string ParameterPlatform = "platform";
|
||||
public static readonly string ParameterStartType = "start_type"; // 游戏启动类型
|
||||
public static readonly string ParameterReplay = "replay"; // 游戏重玩
|
||||
public static readonly string ParameterContinue = "continue"; // 游戏继续
|
||||
public static readonly string ParameterAdUnitName = "ad_unit_name";
|
||||
public static readonly string ParameterAdCreativeId = "ad_creative_id";
|
||||
public const string ParameterResult = "result";
|
||||
public const string ParameterStep = "step";
|
||||
public const string ParameterDuration = "duration";
|
||||
public const string ParameterErrorCode = "error_code";
|
||||
public const string ParameterProductId = "product_id";
|
||||
public const string ParameterPlatform = "platform";
|
||||
public const string ParameterStartType = "start_type"; // 游戏启动类型
|
||||
public const string ParameterReplay = "replay"; // 游戏重玩
|
||||
public const string ParameterContinue = "continue"; // 游戏继续
|
||||
public const string ParameterAdUnitName = "ad_unit_name";
|
||||
public const string ParameterAdPlacement = "ad_placement";
|
||||
public const string ParameterAdCreativeId = "ad_creative_id";
|
||||
public const string ParameterReviewCreativeId = "review_creative_id";
|
||||
|
||||
|
||||
// 评价参数
|
||||
public static readonly string EventRateImp = "rate_imp"; // 评价弹窗展示
|
||||
public static readonly string EventRateNow = "rate_now"; // 点击评分引导弹窗中的评分
|
||||
public const string EventRateImp = "rate_imp"; // 评价弹窗展示
|
||||
public const string EventRateNow = "rate_now"; // 点击评分引导弹窗中的评分
|
||||
|
||||
//打点内部执行错误
|
||||
public static string ParameterEventError => "event_error";
|
||||
|
||||
//ios ATT打点
|
||||
public static readonly string ATTGuideShow = "att_guide_show";
|
||||
public static readonly string ATTGuideOK = "att_guide_ok";
|
||||
public static readonly string ATTWindowShow = "att_window_show";
|
||||
public static readonly string ATTOptIn = "att_opt_in";
|
||||
public static readonly string ATTOpOut = "att_opt_out";
|
||||
public static readonly string ParameterATTStatus = "att_status";
|
||||
public static readonly string EventATTResult = "att_result";
|
||||
public const string ATTGuideShow = "att_guide_show";
|
||||
public const string ATTGuideOK = "att_guide_ok";
|
||||
public const string ATTWindowShow = "att_window_show";
|
||||
public const string ATTOptIn = "att_opt_in";
|
||||
public const string ATTOpOut = "att_opt_out";
|
||||
public const string ParameterATTStatus = "att_status";
|
||||
public const string EventATTResult = "att_result";
|
||||
|
||||
// 用户属性
|
||||
public static readonly string PropertyFirstOpenTime = "first_open_time"; //用户第一次first_open的时间
|
||||
public static readonly string PropertyDeviceID = "device_id"; //用户的设备ID
|
||||
public static readonly string PropertyUserID = "user_id";
|
||||
public static readonly string PropertyLevel = "b_level"; //"每次完成通关上升一次,显示用户完成的最大关卡数。只针对主关卡和主玩法的局数做累加,初始值为0。"
|
||||
public static readonly string PropertyPlay = "b_play"; //每完成一局或者游戏触发,
|
||||
public static readonly string PropertyLastPlayedLevel = "last_played_level";
|
||||
public static readonly string PropertyGrade = "grade"; //当游戏玩家角色升级时触发
|
||||
public static readonly string PropertyIsIAPUser = "is_iap_user"; //付费成功后设置属性参数为true,如果没有发生付费可以不用设置该属性
|
||||
public static readonly string PropertyIAPCoin = "iap_coin"; //付费所得的总金币数(iap获取累计值)\
|
||||
public static readonly string PropertyNonIAPCoin = "noniap_coin"; //非付费iap获取累计值
|
||||
public static readonly string PropertyCoin = "coin"; //当前金币数
|
||||
public static readonly string PropertyExp = "exp"; // 经验值
|
||||
public static readonly string PropertyHp = "hp"; // 生命值/体力
|
||||
public static readonly string PropertyAndroidID = "android_id"; // Android 平台 AndroidID
|
||||
public static readonly string PropertyIDFV = "idfv"; // iOS 平台 IDFV
|
||||
public static readonly string PropertyIDFA = "idfa"; // iOS 平台 IDFA
|
||||
public static readonly string PropertyPicture = "picture"; // 玩家在主线的mapid
|
||||
public static readonly string PropertyNoAds = "no_ads"; // 玩家是否去广告
|
||||
public static readonly string PropertyATTStatus = "att_status"; // ATT 状态
|
||||
public static readonly string PropertyGDPR = "gdpr"; // GDPR状态
|
||||
public const string PropertyFirstOpenTime = "first_open_time"; //用户第一次first_open的时间
|
||||
public const string PropertyDeviceID = "device_id"; //用户的设备ID
|
||||
public const string PropertyUserID = "user_id";
|
||||
public const string PropertyLevel = "b_level"; //"每次完成通关上升一次,显示用户完成的最大关卡数。只针对主关卡和主玩法的局数做累加,初始值为0。"
|
||||
public const string PropertyPlay = "b_play"; //每完成一局或者游戏触发,
|
||||
public const string PropertyLastPlayedLevel = "last_played_level";
|
||||
public const string PropertyGrade = "grade"; //当游戏玩家角色升级时触发
|
||||
public const string PropertyIsIAPUser = "is_iap_user"; //付费成功后设置属性参数为true,如果没有发生付费可以不用设置该属性
|
||||
public const string PropertyIAPCoin = "iap_coin"; //付费所得的总金币数(iap获取累计值)\
|
||||
public const string PropertyNonIAPCoin = "noniap_coin"; //非付费iap获取累计值
|
||||
public const string PropertyCoin = "coin"; //当前金币数
|
||||
public const string PropertyExp = "exp"; // 经验值
|
||||
public const string PropertyHp = "hp"; // 生命值/体力
|
||||
public const string PropertyAndroidID = "android_id"; // Android 平台 AndroidID
|
||||
public const string PropertyIDFV = "idfv"; // iOS 平台 IDFV
|
||||
public const string PropertyIDFA = "idfa"; // iOS 平台 IDFA
|
||||
public const string PropertyPicture = "picture"; // 玩家在主线的mapid
|
||||
public const string PropertyNoAds = "no_ads"; // 玩家是否去广告
|
||||
public const string PropertyATTStatus = "att_status"; // ATT 状态
|
||||
public const string PropertyGDPR = "gdpr"; // GDPR状态
|
||||
|
||||
// 经济相关
|
||||
public const string ParameterBalance = "balance"; // 用于余额
|
||||
|
|
@ -124,6 +131,6 @@ namespace Guru
|
|||
public const string ParameterVirtualCurrencyName = "virtual_currency_name"; // 虚拟货币名称
|
||||
|
||||
// 中台
|
||||
public static readonly string EventDevAudit = "dev_audit"; // 中台事件异常
|
||||
public const string EventDevAudit = "dev_audit"; // 中台事件异常
|
||||
}
|
||||
}
|
||||
|
|
@ -26,9 +26,7 @@ namespace Guru
|
|||
|
||||
public static bool IsDebug { get; set; } = false;
|
||||
|
||||
private static bool _hasInited = false;
|
||||
|
||||
public static bool IsReady => _hasInited;
|
||||
private static bool _isGuruAnalyticInitOnce = false;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化Guru自打点系统 (请优先于 Firebase 初始化调用)
|
||||
|
|
@ -36,7 +34,7 @@ namespace Guru
|
|||
public static void InstallGuruAnalytics(bool isDebug = false, bool enableErrorLog = false)
|
||||
{
|
||||
|
||||
if (_hasInited) return;
|
||||
if (_isGuruAnalyticInitOnce) return;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -47,7 +45,7 @@ namespace Guru
|
|||
#endif
|
||||
string appId = IPMConfig.IPM_X_APP_ID;
|
||||
string deviceInfo = new DeviceInfoData().ToString();
|
||||
GuruAnalytics.Init(appId, deviceInfo, IsDebug, enableErrorLog); // 初始化(带Header)
|
||||
GuruAnalytics.Init(appId, deviceInfo, OnGuruAnalyticsInitComplete, IsDebug, enableErrorLog); // 初始化(带Header)
|
||||
|
||||
_hasGotFirebaseId = false;
|
||||
_hasGotAdId = false;
|
||||
|
|
@ -59,7 +57,7 @@ namespace Guru
|
|||
|
||||
UpdateAllValues();
|
||||
|
||||
_hasInited = true;
|
||||
_isGuruAnalyticInitOnce = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -79,7 +77,7 @@ namespace Guru
|
|||
if (!string.IsNullOrEmpty(IPMConfig.IPM_UID))
|
||||
{
|
||||
Debug.Log($"---[ANA] UID: {IPMConfig.IPM_UID}");
|
||||
GuruAnalytics.SetUid(IPMConfig.IPM_UID);
|
||||
GuruAnalytics.Instance.SetUid(IPMConfig.IPM_UID);
|
||||
FirebaseAnalytics.SetUserProperty(PropertyUserID, IPMConfig.IPM_UID);
|
||||
_hasGotUid = true;
|
||||
}
|
||||
|
|
@ -95,7 +93,7 @@ namespace Guru
|
|||
|
||||
if (!string.IsNullOrEmpty(IPMConfig.IPM_DEVICE_ID))
|
||||
{
|
||||
GuruAnalytics.SetDeviceId(IPMConfig.IPM_DEVICE_ID);
|
||||
GuruAnalytics.Instance.SetDeviceId(IPMConfig.IPM_DEVICE_ID);
|
||||
FirebaseAnalytics.SetUserProperty(PropertyDeviceID, IPMConfig.IPM_DEVICE_ID);
|
||||
_hasGotDeviceId = true;
|
||||
}
|
||||
|
|
@ -121,7 +119,7 @@ namespace Guru
|
|||
|
||||
if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ID))
|
||||
{
|
||||
GuruAnalytics.SetAdjustId(IPMConfig.ADJUST_ID);
|
||||
GuruAnalytics.Instance.SetAdjustId(IPMConfig.ADJUST_ID);
|
||||
_hasGotAdjustId = true;
|
||||
}
|
||||
else
|
||||
|
|
@ -152,7 +150,7 @@ namespace Guru
|
|||
|
||||
if (!string.IsNullOrEmpty(IPMConfig.ADJUST_ADID))
|
||||
{
|
||||
GuruAnalytics.SetAdId(IPMConfig.ADJUST_ADID);
|
||||
GuruAnalytics.Instance.SetAdId(IPMConfig.ADJUST_ADID);
|
||||
_hasGotAdId = true;
|
||||
}
|
||||
|
||||
|
|
@ -171,7 +169,7 @@ namespace Guru
|
|||
|
||||
if (!string.IsNullOrEmpty(IPMConfig.FIREBASE_ID))
|
||||
{
|
||||
GuruAnalytics.SetFirebaseId(IPMConfig.FIREBASE_ID);
|
||||
GuruAnalytics.Instance.SetFirebaseId(IPMConfig.FIREBASE_ID);
|
||||
_hasGotFirebaseId = true;
|
||||
}
|
||||
else
|
||||
|
|
@ -185,6 +183,8 @@ namespace Guru
|
|||
/// </summary>
|
||||
private static void FetchFirebaseId()
|
||||
{
|
||||
if (!IsFirebaseReady) return;
|
||||
|
||||
FirebaseAnalytics.GetAnalyticsInstanceIdAsync()
|
||||
.ContinueWithOnMainThread(task =>
|
||||
{
|
||||
|
|
@ -207,12 +207,12 @@ namespace Guru
|
|||
private static void SetATTStatus()
|
||||
{
|
||||
string status = ATTManager.GetStatus();
|
||||
GuruAnalytics.SetUserProperty(ParameterATTStatus, status);
|
||||
GuruAnalytics.Instance.SetUserProperty(ParameterATTStatus, status);
|
||||
}
|
||||
|
||||
private static void SetIDFV()
|
||||
{
|
||||
GuruAnalytics.SetIDFV(DeviceIDHelper.IDFV);
|
||||
GuruAnalytics.Instance.SetIDFV(DeviceIDHelper.IDFV);
|
||||
}
|
||||
|
||||
private static void SetIDFA()
|
||||
|
|
@ -228,7 +228,7 @@ namespace Guru
|
|||
|
||||
if (!string.IsNullOrEmpty(IPMConfig.ADJUST_IDFA))
|
||||
{
|
||||
GuruAnalytics.SetIDFA(IPMConfig.ADJUST_IDFA);
|
||||
GuruAnalytics.Instance.SetIDFA(IPMConfig.ADJUST_IDFA);
|
||||
_hasGotIDFA = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -241,7 +241,7 @@ namespace Guru
|
|||
/// </summary>
|
||||
private static void SetAndroidId()
|
||||
{
|
||||
GuruAnalytics.SetAndroidID(DeviceIDHelper.AndroidID);
|
||||
GuruAnalytics.Instance.SetAndroidID(DeviceIDHelper.AndroidID);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -276,7 +276,7 @@ namespace Guru
|
|||
var interval = (DateTime.Now - _lastReportRateDate).TotalSeconds;
|
||||
if (interval > _reportSuccessInterval)
|
||||
{
|
||||
GuruAnalytics.ReportEventSuccessRate();
|
||||
GuruAnalytics.Instance.ReportEventSuccessRate();
|
||||
_lastReportRateDate = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
|
@ -294,7 +294,7 @@ namespace Guru
|
|||
{
|
||||
try
|
||||
{
|
||||
GuruAnalytics.SetUserProperty(key, value);
|
||||
GuruAnalytics.Instance.SetUserProperty(key, value);
|
||||
UpdateAllValues(); // 同步所有的ID
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
@ -309,12 +309,12 @@ namespace Guru
|
|||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="data"></param>
|
||||
private static void CustomLogEvent(string key, Dictionary<string, dynamic> data = null, int priority = -1)
|
||||
private static void TrackEventGuru(string key, Dictionary<string, dynamic> data = null, int priority = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (data == null) data = new Dictionary<string, dynamic>();
|
||||
GuruAnalytics.LogEvent(key, data, priority);
|
||||
GuruAnalytics.Instance.LogEvent(key, data, priority);
|
||||
UpdateAllValues(); // 同步所有的ID
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
@ -337,7 +337,7 @@ namespace Guru
|
|||
if (Math.Abs(_tch02TargetValue - value) > 0.001d)
|
||||
{
|
||||
_tch02TargetValue = value;
|
||||
GuruAnalytics.SetTch02Value(value);
|
||||
GuruAnalytics.Instance.SetTch02Value(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ namespace Guru
|
|||
if(!string.IsNullOrEmpty(scene)) data[ParameterScene] = scene; // 获取的虚拟货币或者道具的场景
|
||||
if (extra != null) data.AddRange(extra, isOverride: true);
|
||||
|
||||
LogEvent(EventEarnVirtualCurrency, data, new EventSetting() { EnableFirebaseAnalytics = true });
|
||||
TrackEvent(EventEarnVirtualCurrency, data, new EventSetting() { EnableFirebaseAnalytics = true });
|
||||
|
||||
// FB 上报收入点
|
||||
FBService.LogEvent(EventEarnVirtualCurrency, value, data);
|
||||
|
|
@ -131,7 +131,7 @@ namespace Guru
|
|||
|
||||
if(!string.IsNullOrEmpty(scene)) data[ParameterScene] = scene; // 获取的虚拟货币或者道具的场景
|
||||
|
||||
LogEvent(EventSpendVirtualCurrency, data, new EventSetting() { EnableFirebaseAnalytics = true });
|
||||
TrackEvent(EventSpendVirtualCurrency, data, new EventSetting() { EnableFirebaseAnalytics = true });
|
||||
|
||||
// FB 上报消费点
|
||||
FBService.LogEvent(EventSpendVirtualCurrency, value, data);
|
||||
|
|
|
|||
|
|
@ -5,104 +5,104 @@ namespace Guru
|
|||
//Firebase内置定义事件名称和参数名称
|
||||
public static partial class Analytics
|
||||
{
|
||||
internal static readonly string EventAdImpression = "ad_impression";
|
||||
internal static readonly string EventAddPaymentInfo = "add_payment_info";
|
||||
internal static readonly string EventAddShippingInfo = "add_shipping_info";
|
||||
internal static readonly string EventAddToCart = "add_to_cart";
|
||||
internal static readonly string EventAddToWishlist = "add_to_wishlist";
|
||||
internal static readonly string EventAppOpen = "app_open";
|
||||
internal static readonly string EventBeginCheckout = "begin_checkout";
|
||||
internal static readonly string EventCampaignDetails = "campaign_details";
|
||||
internal static readonly string EventEarnVirtualCurrency = "earn_virtual_currency";
|
||||
internal static readonly string EventGenerateLead = "generate_lead";
|
||||
internal static readonly string EventJoinGroup = "join_group";
|
||||
internal static readonly string EventLevelEnd = "level_end";
|
||||
internal static readonly string EventLevelStart = "level_start";
|
||||
internal static readonly string EventLevelUp = "level_up";
|
||||
internal static readonly string EventLogin = "login";
|
||||
internal static readonly string EventPostScore = "post_score";
|
||||
internal static readonly string EventPurchase = "purchase";
|
||||
internal static readonly string EventRefund = "refund";
|
||||
internal static readonly string EventRemoveFromCart = "remove_from_cart";
|
||||
internal static readonly string EventScreenView = "screen_view";
|
||||
internal static readonly string EventSearch = "search";
|
||||
internal static readonly string EventSelectContent = "select_content";
|
||||
internal static readonly string EventSelectItem = "select_item";
|
||||
internal static readonly string EventSelectPromotion = "select_promotion";
|
||||
internal static readonly string EventShare = "share";
|
||||
internal static readonly string EventSignUp = "sign_up";
|
||||
internal static readonly string EventSpendVirtualCurrency = "spend_virtual_currency";
|
||||
internal static readonly string EventTutorialBegin = "tutorial_begin";
|
||||
internal static readonly string EventTutorialComplete = "tutorial_complete";
|
||||
internal static readonly string EventUnlockAchievement = "unlock_achievement";
|
||||
internal static readonly string EventViewCart = "view_cart";
|
||||
internal static readonly string EventViewItem = "view_item";
|
||||
internal static readonly string EventViewItemList = "view_item_list";
|
||||
internal static readonly string EventViewPromotion = "view_promotion";
|
||||
internal static readonly string EventViewSearchResults = "view_search_results";
|
||||
internal static readonly string ParameterAchievementId = "achievement_id";
|
||||
internal static readonly string ParameterAdFormat = "ad_format";
|
||||
internal static readonly string ParameterAdNetworkClickID = "aclid";
|
||||
internal static readonly string ParameterAdPlatform = "ad_platform";
|
||||
internal static readonly string ParameterAdSource = "ad_source";
|
||||
internal const string EventAdImpression = "ad_impression";
|
||||
internal const string EventAddPaymentInfo = "add_payment_info";
|
||||
internal const string EventAddShippingInfo = "add_shipping_info";
|
||||
internal const string EventAddToCart = "add_to_cart";
|
||||
internal const string EventAddToWishlist = "add_to_wishlist";
|
||||
internal const string EventAppOpen = "app_open";
|
||||
internal const string EventBeginCheckout = "begin_checkout";
|
||||
internal const string EventCampaignDetails = "campaign_details";
|
||||
internal const string EventEarnVirtualCurrency = "earn_virtual_currency";
|
||||
internal const string EventGenerateLead = "generate_lead";
|
||||
internal const string EventJoinGroup = "join_group";
|
||||
internal const string EventLevelEnd = "level_end";
|
||||
internal const string EventLevelStart = "level_start";
|
||||
internal const string EventLevelUp = "level_up";
|
||||
internal const string EventLogin = "login";
|
||||
internal const string EventPostScore = "post_score";
|
||||
internal const string EventPurchase = "purchase";
|
||||
internal const string EventRefund = "refund";
|
||||
internal const string EventRemoveFromCart = "remove_from_cart";
|
||||
internal const string EventScreenView = "screen_view";
|
||||
internal const string EventSearch = "search";
|
||||
internal const string EventSelectContent = "select_content";
|
||||
internal const string EventSelectItem = "select_item";
|
||||
internal const string EventSelectPromotion = "select_promotion";
|
||||
internal const string EventShare = "share";
|
||||
internal const string EventSignUp = "sign_up";
|
||||
internal const string EventSpendVirtualCurrency = "spend_virtual_currency";
|
||||
internal const string EventTutorialBegin = "tutorial_begin";
|
||||
internal const string EventTutorialComplete = "tutorial_complete";
|
||||
internal const string EventUnlockAchievement = "unlock_achievement";
|
||||
internal const string EventViewCart = "view_cart";
|
||||
internal const string EventViewItem = "view_item";
|
||||
internal const string EventViewItemList = "view_item_list";
|
||||
internal const string EventViewPromotion = "view_promotion";
|
||||
internal const string EventViewSearchResults = "view_search_results";
|
||||
internal const string ParameterAchievementId = "achievement_id";
|
||||
internal const string ParameterAdFormat = "ad_format";
|
||||
internal const string ParameterAdNetworkClickID = "aclid";
|
||||
internal const string ParameterAdPlatform = "ad_platform";
|
||||
internal const string ParameterAdSource = "ad_source";
|
||||
|
||||
internal static readonly string ParameterAffiliation = "affiliation";
|
||||
internal static readonly string ParameterCP1 = "cp1";
|
||||
internal static readonly string ParameterCampaign = "campaign";
|
||||
internal static readonly string ParameterCharacter = "character";
|
||||
internal static readonly string ParameterContent = "content";
|
||||
internal static readonly string ParameterContentType = "content_type";
|
||||
internal static readonly string ParameterCoupon = "coupon";
|
||||
internal static readonly string ParameterCreativeName = "creative_name";
|
||||
internal static readonly string ParameterCreativeSlot = "creative_slot";
|
||||
internal static readonly string ParameterCurrency = "currency";
|
||||
internal static readonly string ParameterDestination = "destination";
|
||||
internal static readonly string ParameterDiscount = "discount";
|
||||
internal static readonly string ParameterEndDate = "end_date";
|
||||
internal static readonly string ParameterExtendSession = "extend_session";
|
||||
internal static readonly string ParameterFlightNumber = "flight_number";
|
||||
internal static readonly string ParameterGroupId = "group_id";
|
||||
internal static readonly string ParameterIndex = "index";
|
||||
internal static readonly string ParameterItemBrand = "item_brand";
|
||||
internal static readonly string ParameterItemCategory = "item_category";
|
||||
internal static readonly string ParameterItemCategory2 = "item_category2";
|
||||
internal static readonly string ParameterItemCategory3 = "item_category3";
|
||||
internal static readonly string ParameterItemCategory4 = "item_category4";
|
||||
internal static readonly string ParameterItemCategory5 = "item_category5";
|
||||
internal static readonly string ParameterItemId = "item_id";
|
||||
internal static readonly string ParameterItemList = "item_list";
|
||||
internal static readonly string ParameterItemListID = "item_list_id";
|
||||
internal static readonly string ParameterItemListName = "item_list_name";
|
||||
internal static readonly string ParameterItemName = "item_name";
|
||||
internal static readonly string ParameterLevel = "level";
|
||||
internal static readonly string ParameterLevelName = "level_name";
|
||||
internal static readonly string ParameterLocation = "location";
|
||||
internal static readonly string ParameterLocationID = "location_id";
|
||||
internal static readonly string ParameterMedium = "medium";
|
||||
internal static readonly string ParameterMethod = "method";
|
||||
internal static readonly string ParameterNumberOfNights = "number_of_nights";
|
||||
internal static readonly string ParameterNumberOfPassengers = "number_of_passengers";
|
||||
internal static readonly string ParameterNumberOfRooms = "number_of_rooms";
|
||||
internal static readonly string ParameterOrigin = "origin";
|
||||
internal static readonly string ParameterPaymentType = "payment_type";
|
||||
internal static readonly string ParameterPrice = "price";
|
||||
internal static readonly string ParameterPromotionID = "promotion_id";
|
||||
internal static readonly string ParameterPromotionName = "promotion_name";
|
||||
internal static readonly string ParameterQuantity = "quantity";
|
||||
internal static readonly string ParameterScore = "score";
|
||||
internal static readonly string ParameterScreenClass = "screen_class";
|
||||
internal static readonly string ParameterScreenName = "screen_name";
|
||||
internal static readonly string ParameterSearchTerm = "search_term";
|
||||
internal static readonly string ParameterShipping = "shipping";
|
||||
internal static readonly string ParameterShippingTier = "shipping_tier";
|
||||
internal static readonly string ParameterSignUpMethod = "sign_up_method";
|
||||
internal static readonly string ParameterSource = "source";
|
||||
internal static readonly string ParameterStartDate = "start_date";
|
||||
internal static readonly string ParameterSuccess = "success";
|
||||
internal static readonly string ParameterTax = "tax";
|
||||
internal static readonly string ParameterTerm = "term";
|
||||
internal static readonly string ParameterTransactionId = "transaction_id";
|
||||
internal static readonly string ParameterTravelClass = "travel_class";
|
||||
internal static readonly string ParameterValue = "value";
|
||||
internal const string ParameterAffiliation = "affiliation";
|
||||
internal const string ParameterCP1 = "cp1";
|
||||
internal const string ParameterCampaign = "campaign";
|
||||
internal const string ParameterCharacter = "character";
|
||||
internal const string ParameterContent = "content";
|
||||
internal const string ParameterContentType = "content_type";
|
||||
internal const string ParameterCoupon = "coupon";
|
||||
internal const string ParameterCreativeName = "creative_name";
|
||||
internal const string ParameterCreativeSlot = "creative_slot";
|
||||
internal const string ParameterCurrency = "currency";
|
||||
internal const string ParameterDestination = "destination";
|
||||
internal const string ParameterDiscount = "discount";
|
||||
internal const string ParameterEndDate = "end_date";
|
||||
internal const string ParameterExtendSession = "extend_session";
|
||||
internal const string ParameterFlightNumber = "flight_number";
|
||||
internal const string ParameterGroupId = "group_id";
|
||||
internal const string ParameterIndex = "index";
|
||||
internal const string ParameterItemBrand = "item_brand";
|
||||
internal const string ParameterItemCategory = "item_category";
|
||||
internal const string ParameterItemCategory2 = "item_category2";
|
||||
internal const string ParameterItemCategory3 = "item_category3";
|
||||
internal const string ParameterItemCategory4 = "item_category4";
|
||||
internal const string ParameterItemCategory5 = "item_category5";
|
||||
internal const string ParameterItemId = "item_id";
|
||||
internal const string ParameterItemList = "item_list";
|
||||
internal const string ParameterItemListID = "item_list_id";
|
||||
internal const string ParameterItemListName = "item_list_name";
|
||||
internal const string ParameterItemName = "item_name";
|
||||
internal const string ParameterLevel = "level";
|
||||
internal const string ParameterLevelName = "level_name";
|
||||
internal const string ParameterLocation = "location";
|
||||
internal const string ParameterLocationID = "location_id";
|
||||
internal const string ParameterMedium = "medium";
|
||||
internal const string ParameterMethod = "method";
|
||||
internal const string ParameterNumberOfNights = "number_of_nights";
|
||||
internal const string ParameterNumberOfPassengers = "number_of_passengers";
|
||||
internal const string ParameterNumberOfRooms = "number_of_rooms";
|
||||
internal const string ParameterOrigin = "origin";
|
||||
internal const string ParameterPaymentType = "payment_type";
|
||||
internal const string ParameterPrice = "price";
|
||||
internal const string ParameterPromotionID = "promotion_id";
|
||||
internal const string ParameterPromotionName = "promotion_name";
|
||||
internal const string ParameterQuantity = "quantity";
|
||||
internal const string ParameterScore = "score";
|
||||
internal const string ParameterScreenClass = "screen_class";
|
||||
internal const string ParameterScreenName = "screen_name";
|
||||
internal const string ParameterSearchTerm = "search_term";
|
||||
internal const string ParameterShipping = "shipping";
|
||||
internal const string ParameterShippingTier = "shipping_tier";
|
||||
internal const string ParameterSignUpMethod = "sign_up_method";
|
||||
internal const string ParameterSource = "source";
|
||||
internal const string ParameterStartDate = "start_date";
|
||||
internal const string ParameterSuccess = "success";
|
||||
internal const string ParameterTax = "tax";
|
||||
internal const string ParameterTerm = "term";
|
||||
internal const string ParameterTransactionId = "transaction_id";
|
||||
internal const string ParameterTravelClass = "travel_class";
|
||||
internal const string ParameterValue = "value";
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ namespace Guru
|
|||
using System.Collections.Generic;
|
||||
using Facebook.Unity;
|
||||
using UnityEngine;
|
||||
using Guru.Ads;
|
||||
|
||||
//游戏通用模版打点定义
|
||||
public static partial class Analytics
|
||||
|
|
@ -27,7 +28,7 @@ namespace Guru
|
|||
};
|
||||
if (extra != null) dict.AddRange(extra, isOverride:true);
|
||||
|
||||
LogEvent(EventLevelUp, dict);
|
||||
TrackEvent(EventLevelUp, dict);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -42,7 +43,7 @@ namespace Guru
|
|||
};
|
||||
if (extra != null) dict.AddRange(extra, isOverride:true);
|
||||
|
||||
LogEvent(EventUnlockAchievement, dict);
|
||||
TrackEvent(EventUnlockAchievement, dict);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -53,7 +54,7 @@ namespace Guru
|
|||
[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>()
|
||||
TrackEvent(EventLevelStart, new Dictionary<string, object>()
|
||||
{
|
||||
{ ParameterLevel, level },
|
||||
{ ParameterItemCategory, "main" },
|
||||
|
|
@ -91,7 +92,7 @@ namespace Guru
|
|||
dict.AddRange(extra, isOverride:true);
|
||||
}
|
||||
|
||||
LogEvent(EventLevelStart, dict);
|
||||
TrackEvent(EventLevelStart, dict);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -131,7 +132,7 @@ namespace Guru
|
|||
|
||||
if(extra != null) dict.AddRange(extra, isOverride:true);
|
||||
|
||||
LogEvent(EventLevelEnd, dict);
|
||||
TrackEvent(EventLevelEnd, dict);
|
||||
|
||||
// if (isSuccess)
|
||||
// {
|
||||
|
|
@ -160,7 +161,7 @@ namespace Guru
|
|||
["level"] = level,
|
||||
};
|
||||
}
|
||||
LogEvent(eventName, extra, new EventSetting()
|
||||
TrackEvent(eventName, extra, new EventSetting()
|
||||
{
|
||||
EnableFirebaseAnalytics = true,
|
||||
EnableFacebookAnalytics = true,
|
||||
|
|
@ -188,7 +189,7 @@ namespace Guru
|
|||
if (extra != null)
|
||||
dict.AddRange(extra, isOverride: true);
|
||||
|
||||
LogEvent(EventLevelFirstEnd, dict);
|
||||
TrackEvent(EventLevelFirstEnd, dict);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -215,7 +216,7 @@ namespace Guru
|
|||
};
|
||||
if(extra != null) dict.AddRange(extra, isOverride: true);
|
||||
|
||||
LogEvent(EventEarnVirtualCurrency, dict);
|
||||
TrackEvent(EventEarnVirtualCurrency, dict);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -237,7 +238,7 @@ namespace Guru
|
|||
};
|
||||
if(extra != null) dict.AddRange(extra, isOverride: true);
|
||||
|
||||
LogEvent(EventSpendVirtualCurrency, dict);
|
||||
TrackEvent(EventSpendVirtualCurrency, dict);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
|
@ -260,7 +261,7 @@ namespace Guru
|
|||
};
|
||||
if(extra != null) dict.AddRange(extra, isOverride: true);
|
||||
|
||||
LogEvent("hit_points", dict);
|
||||
TrackEvent("hit_points", dict);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
|
@ -387,7 +388,7 @@ namespace Guru
|
|||
|
||||
//--------- Extra data for IAP receipt ---------------
|
||||
|
||||
LogEvent(evtName, data);
|
||||
TrackEvent(evtName, data);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -416,7 +417,6 @@ namespace Guru
|
|||
/// 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 eg:0.002
|
||||
|
|
@ -427,25 +427,25 @@ namespace Guru
|
|||
/// ad_unit_name string 广告位名称
|
||||
/// ad_creative_id string 广告素材id
|
||||
/// </li>
|
||||
public static void ADImpression(MaxSdkBase.AdInfo impressionData, string platform = "")
|
||||
public static void ADImpression(AdImpressionData impressionData)
|
||||
{
|
||||
if (string.IsNullOrEmpty(platform)) platform = AdMAX;
|
||||
double revenue = impressionData.Revenue;
|
||||
LogEvent(EventAdImpression, new Dictionary<string, dynamic>()
|
||||
TrackEvent(EventAdImpression, new Dictionary<string, dynamic>()
|
||||
{
|
||||
[ParameterValue] = revenue,
|
||||
[ParameterCurrency] = USD,
|
||||
[ParameterAdPlatform] = platform,
|
||||
[ParameterAdSource] = impressionData.NetworkName,
|
||||
[ParameterAdFormat] = impressionData.AdFormat,
|
||||
[ParameterAdUnitName] = impressionData.AdUnitIdentifier,
|
||||
[ParameterAdCreativeId] = impressionData.CreativeIdentifier,
|
||||
[ParameterValue] = impressionData.value,
|
||||
[ParameterCurrency] = impressionData.currency,
|
||||
[ParameterAdPlatform] = impressionData.ad_platform,
|
||||
[ParameterAdSource] = impressionData.ad_source,
|
||||
[ParameterAdFormat] = impressionData.ad_format,
|
||||
[ParameterAdUnitName] = impressionData.ad_unit_name,
|
||||
[ParameterAdPlacement] = impressionData.ad_placement,
|
||||
[ParameterAdCreativeId] = impressionData.ad_creative_id,
|
||||
[ParameterReviewCreativeId] = impressionData.review_creative_id,
|
||||
});
|
||||
}
|
||||
|
||||
public static void TchAdAbnormalEvent(double value)
|
||||
{
|
||||
LogEvent(EventTchAdRevAbnormal, new Dictionary<string, dynamic>()
|
||||
TrackEvent(EventTchAdRevAbnormal, new Dictionary<string, dynamic>()
|
||||
{
|
||||
{ ParameterAdPlatform, AdMAX },
|
||||
{ ParameterCurrency, USD },
|
||||
|
|
@ -470,7 +470,7 @@ namespace Guru
|
|||
};
|
||||
if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra);
|
||||
|
||||
LogEvent(EventIAPImp, dict);
|
||||
TrackEvent(EventIAPImp, dict);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -486,7 +486,7 @@ namespace Guru
|
|||
};
|
||||
if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra);
|
||||
|
||||
LogEvent(EventIAPClose, dict);
|
||||
TrackEvent(EventIAPClose, dict);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -512,7 +512,7 @@ namespace Guru
|
|||
};
|
||||
if(extra != null) dict = GuruSDKUtils.MergeDictionary(dict, extra);
|
||||
|
||||
LogEvent(EventIAPClick, dict);
|
||||
TrackEvent(EventIAPClick, dict);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -543,7 +543,7 @@ namespace Guru
|
|||
if(!string.IsNullOrEmpty(offerId))
|
||||
dict["basePlan"] = offerId;
|
||||
|
||||
LogEvent(EventIAPReturnTrue, dict, new EventSetting()
|
||||
TrackEvent(EventIAPReturnTrue, dict, new EventSetting()
|
||||
{
|
||||
EnableFirebaseAnalytics = true,
|
||||
EnableAdjustAnalytics = true,
|
||||
|
|
@ -559,7 +559,7 @@ namespace Guru
|
|||
/// <param name="failReason"></param>
|
||||
internal static void IAPRetFalse(string itemCategory, string productId, string failReason)
|
||||
{
|
||||
LogEvent(EventIAPReturnFalse, new Dictionary<string, object>()
|
||||
TrackEvent(EventIAPReturnFalse, new Dictionary<string, object>()
|
||||
{
|
||||
{ ParameterItemCategory, itemCategory },
|
||||
{ ParameterItemName, productId },
|
||||
|
|
@ -576,7 +576,7 @@ namespace Guru
|
|||
/// <param name="currency">币种</param>
|
||||
public static void FirstIAP(string itemName, double value, string currency)
|
||||
{
|
||||
LogEvent(EventIAPFirst, new Dictionary<string, object>()
|
||||
TrackEvent(EventIAPFirst, new Dictionary<string, object>()
|
||||
{
|
||||
{ ParameterItemName, itemName },
|
||||
{ ParameterValue, value },
|
||||
|
|
@ -597,7 +597,7 @@ namespace Guru
|
|||
if (productName.Contains(".")) productName = productName.Replace(".", "_");
|
||||
|
||||
string eventName = $"iap_{productName}";
|
||||
LogEvent(eventName, new Dictionary<string, object>()
|
||||
TrackEvent(eventName, new Dictionary<string, object>()
|
||||
{
|
||||
{ ParameterItemName, itemName },
|
||||
{ ParameterValue, value },
|
||||
|
|
@ -724,10 +724,8 @@ namespace Guru
|
|||
["sandbox"] = isSandbox? "true": "false"
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 上报Firebase + 自打点
|
||||
LogEvent(eventName, dict, new EventSetting() { EnableFirebaseAnalytics = true });
|
||||
TrackEvent(eventName, dict, new EventSetting() { EnableFirebaseAnalytics = true });
|
||||
|
||||
// 上报 Adjust 支付事件
|
||||
LogAdjustRevenueEvent(eventName, value, productId, orderId, purchaseToken, receipt, dict);
|
||||
|
|
@ -746,7 +744,7 @@ namespace Guru
|
|||
if (data == null) return;
|
||||
data["country"] = IPMConfig.IPM_COUNTRY_CODE;
|
||||
data["network"] = Application.internetReachability.ToString();
|
||||
LogEvent(EventDevAudit, data, new EventSetting() { EnableFirebaseAnalytics = true });
|
||||
TrackEvent(EventDevAudit, data, new EventSetting() { EnableFirebaseAnalytics = true });
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
|
||||
|
||||
using System.Threading;
|
||||
|
||||
namespace Guru
|
||||
{
|
||||
using System;
|
||||
|
|
@ -16,82 +18,111 @@ namespace Guru
|
|||
{
|
||||
public class EventSetting
|
||||
{
|
||||
public bool EnableFirebaseAnalytics = false;
|
||||
public bool EnableAdjustAnalytics = false;
|
||||
public bool EnableFacebookAnalytics = false;
|
||||
public bool EnableFirebaseAnalytics;
|
||||
public bool EnableAdjustAnalytics;
|
||||
public bool EnableFacebookAnalytics;
|
||||
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;
|
||||
|
||||
private static bool _isInited; //Analytics是否初始化完成
|
||||
private static EventSetting DefaultEventSetting => EventSetting.GetDefaultSetting();
|
||||
|
||||
private static bool _isInitOnce; //Analytics是否初始化完成
|
||||
public static bool EnableDebugAnalytics; //允许Debug包上报打点
|
||||
|
||||
public static bool IsDebugMode => PlatformUtil.IsDebug();
|
||||
private static bool IsFirebaseReady => FirebaseUtil.IsFirebaseInitialized;
|
||||
|
||||
private static bool IsEnable
|
||||
private static bool IsReady
|
||||
{
|
||||
get
|
||||
{
|
||||
//Firebase服务没有初始化完成不上报打点
|
||||
if (!FirebaseUtil.IsFirebaseInitialized)
|
||||
return false;
|
||||
|
||||
//Analytics没有初始化不上报打点
|
||||
if (!_isInited)
|
||||
return false;
|
||||
|
||||
if (!_isInitOnce) return false;
|
||||
|
||||
//Firebase服务没有初始化完成不上报打点
|
||||
if (!IsFirebaseReady) return false;
|
||||
|
||||
#if !UNITY_EDITOR
|
||||
//开发环境打点不上报
|
||||
if (IsDebugMode && !EnableDebugAnalytics)
|
||||
return false;
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static AdjustEventDriver _adjustEventDriver;
|
||||
private static FBEventDriver _fbEventDriver;
|
||||
private static FirebaseEventDriver _firebaseEventDriver;
|
||||
private static GuruEventDriver _guruEventDriver;
|
||||
|
||||
|
||||
#region 初始化
|
||||
|
||||
public static void InitAnalytics()
|
||||
{
|
||||
if (_isInited) return;
|
||||
_isInited = true;
|
||||
if (_isInitOnce) return;
|
||||
_isInitOnce = true;
|
||||
|
||||
// -------- 初始化 Exception ----------
|
||||
CrashlyticsAgent.Install();
|
||||
_adjustEventDriver = new AdjustEventDriver();
|
||||
_fbEventDriver = new FBEventDriver();
|
||||
_firebaseEventDriver = new FirebaseEventDriver();
|
||||
_guruEventDriver = new GuruEventDriver();
|
||||
|
||||
// ------- 初始化自打点 ----------
|
||||
InstallGuruAnalytics(IsDebug);
|
||||
|
||||
if (_defaultEventSetting == null)
|
||||
{
|
||||
var analyticsSetting = GuruSettings.Instance.AnalyticsSetting;
|
||||
_defaultEventSetting = new EventSetting
|
||||
{
|
||||
EnableFirebaseAnalytics = analyticsSetting.EnalbeFirebaseAnalytics,
|
||||
EnableFacebookAnalytics = analyticsSetting.EnalbeFacebookAnalytics,
|
||||
EnableAdjustAnalytics = analyticsSetting.EnalbeAdjustAnalytics
|
||||
};
|
||||
}
|
||||
|
||||
FirebaseUtil.onInitComplete += OnFirebaseCompleted;
|
||||
}
|
||||
|
||||
private static void OnFirebaseCompleted(bool success)
|
||||
|
||||
|
||||
public static void OnFirebaseInitCompleted()
|
||||
{
|
||||
FirebaseUtil.onInitComplete -= OnFirebaseCompleted;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
Debug.Log($"[SDK] --- Analytics Init After FirebaseReady:{IsFirebaseReady}");
|
||||
|
||||
// -------- 初始化 Crashlytics ----------
|
||||
CrashlyticsAgent.Init();
|
||||
FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
|
||||
FirebaseAnalytics.SetSessionTimeoutDuration(new TimeSpan(0, 30, 0));
|
||||
SetUserProperty(FirebaseAnalytics.UserPropertySignUpMethod, "Google");
|
||||
SetUserProperty(PropertyDeviceID, IPMConfig.IPM_DEVICE_ID);
|
||||
// SetUserProperty(PropertyFirstOpenTime, FirstOpenTime);
|
||||
|
||||
_firebaseEventDriver.TriggerFlush();
|
||||
}
|
||||
|
||||
|
||||
public static void OnFBInitComplete()
|
||||
{
|
||||
_fbEventDriver.TriggerFlush();
|
||||
}
|
||||
|
||||
public static void OnAdjustInitComplete()
|
||||
{
|
||||
_adjustEventDriver.TriggerFlush();
|
||||
}
|
||||
|
||||
private static void OnGuruAnalyticsInitComplete()
|
||||
{
|
||||
_guruEventDriver.TriggerFlush();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
@ -99,14 +130,19 @@ namespace Guru
|
|||
|
||||
public static void SetCurrentScreen(string screenName, string className)
|
||||
{
|
||||
if (!_isInitOnce)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Log.I(TAG,$"SetCurrentScreen -> screenName:{screenName}, className:{className}");
|
||||
GuruAnalytics.SetScreen(screenName);
|
||||
|
||||
if (!IsEnable) return;
|
||||
FirebaseAnalytics.LogEvent(FirebaseAnalytics.EventScreenView,
|
||||
new Parameter(FirebaseAnalytics.ParameterScreenClass, className),
|
||||
new Parameter(FirebaseAnalytics.ParameterScreenName, screenName)
|
||||
);
|
||||
GuruAnalytics.Instance.SetScreen(screenName);
|
||||
|
||||
TrackEvent(EventScreenView, new Dictionary<string, dynamic>()
|
||||
{
|
||||
[ParameterScreenName] = screenName,
|
||||
[ParameterScreenClass] = className,
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -120,7 +156,7 @@ namespace Guru
|
|||
public static void SetUserIDProperty(string userID)
|
||||
{
|
||||
Log.I(TAG,$"SetUserIDProperty -> userID:{userID}");
|
||||
if (!IsEnable) return;
|
||||
if (!IsReady) return;
|
||||
|
||||
FirebaseAnalytics.SetUserId(userID);
|
||||
}
|
||||
|
|
@ -128,126 +164,107 @@ namespace Guru
|
|||
/// <summary>
|
||||
/// Firebase上报用户属性
|
||||
/// </summary>
|
||||
public static void SetUserProperty(string propertyName, string propertyValue)
|
||||
public static void SetUserProperty(string key, string value)
|
||||
{
|
||||
Log.I(TAG,$"SetUserProperty -> propertyName:{propertyName}, propertyValue:{propertyValue}");
|
||||
|
||||
if (!IsEnable)
|
||||
return;
|
||||
if (!_isInitOnce)
|
||||
{
|
||||
throw new Exception($"[{TAG}][SDK] Analytics did not initialized, Call <Analytics.{nameof(InitAnalytics)}()> first!");
|
||||
}
|
||||
|
||||
if (IsDebug && !EnableDebugAnalytics)
|
||||
{
|
||||
Debug.LogWarning($"[{TAG}][SDK] --- SetProperty {key}:{value} can not send int Debug mode. Set <InitConfig.EnableDebugAnalytics> with `true`");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 填充相关的追踪事件
|
||||
_guruEventDriver.AddProperty(key, value);
|
||||
_firebaseEventDriver.AddProperty(key, value);
|
||||
Debug.Log($"{TAG} --- SetUserProperty -> propertyName:{key}, propertyValue:{value}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (FirebaseUtil.IsReady)
|
||||
{
|
||||
Crashlytics.LogException(ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"Catch Error: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
FirebaseAnalytics.SetUserProperty(propertyName, propertyValue);
|
||||
CustomSetUserProperty(propertyName, propertyValue);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#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>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="extras"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="eventSetting"></param>
|
||||
/// <param name="priority"></param>
|
||||
internal static void LogEvent(string eventName, Dictionary<string, dynamic> extras, EventSetting eventSetting = null, int priority = -1)
|
||||
internal static void TrackEvent(string eventName, Dictionary<string, dynamic> data,
|
||||
EventSetting eventSetting = null, int priority = -1)
|
||||
{
|
||||
CustomLogEvent(eventName, extras, priority); // 自定义打点上报
|
||||
CheckLogCache(eventName, extras, eventSetting); // log缓存和消费
|
||||
|
||||
if (!IsEnable) return;
|
||||
|
||||
if (extras == null)
|
||||
if (!_isInitOnce)
|
||||
{
|
||||
LogEvent(eventName, eventSetting, priority); // 防空判定
|
||||
throw new Exception($"[{TAG}][SDK] Analytics did not initialized, Call <Analytics.{nameof(InitAnalytics)}()> first!");
|
||||
}
|
||||
|
||||
if (IsDebug && !EnableDebugAnalytics)
|
||||
{
|
||||
Debug.LogWarning($"[{TAG}][SDK] --- LogEvent [{eventName}] can not send int Debug mode. Set <InitConfig.EnableDebugAnalytics> with `true`");
|
||||
return;
|
||||
}
|
||||
|
||||
string paramStr = string.Join(",", extras);
|
||||
Log.I(TAG, $"eventName:{eventName}, params:{paramStr}");
|
||||
if (eventSetting == null) eventSetting = DefaultEventSetting;
|
||||
|
||||
if (eventSetting == null) eventSetting = _defaultEventSetting;
|
||||
if (eventSetting.EnableFirebaseAnalytics)
|
||||
{
|
||||
List<Parameter> parameters = new List<Parameter>();
|
||||
foreach (var kv in extras)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
GuruSDKUtils.MergeDictionary(dict, extras);
|
||||
var dataStr = "";
|
||||
if (data != null) dataStr = JsonParser.ToJson(data);
|
||||
Debug.Log($"[{TAG}] --- [SDK] TrackEvent: {eventName} | priority: {priority} | data:{dataStr} | eventSetting: {eventSetting}");
|
||||
|
||||
if (eventSetting.EnableAdjustAnalytics)
|
||||
try
|
||||
{
|
||||
AdjustEvent adjustEvent = Analytics.CreateAdjustEvent(eventName);
|
||||
if (adjustEvent != null)
|
||||
// 填充相关的追踪事件
|
||||
if (eventSetting.EnableGuruAnalytics)
|
||||
{
|
||||
if (dict.Count > 0)
|
||||
{
|
||||
foreach (var kv in dict)
|
||||
{
|
||||
adjustEvent.AddEventParameter(kv.Key, kv.Value.ToString());
|
||||
}
|
||||
}
|
||||
Adjust.trackEvent(adjustEvent);
|
||||
_guruEventDriver.AddEvent(eventName, data, eventSetting, priority);
|
||||
}
|
||||
if (eventSetting.EnableFirebaseAnalytics)
|
||||
{
|
||||
_firebaseEventDriver.AddEvent(eventName, data, eventSetting, priority);
|
||||
}
|
||||
if (eventSetting.EnableAdjustAnalytics)
|
||||
{
|
||||
_adjustEventDriver.AddEvent(eventName, data, eventSetting, priority);
|
||||
}
|
||||
if (eventSetting.EnableFacebookAnalytics)
|
||||
{
|
||||
_fbEventDriver.AddEvent(eventName, data, eventSetting, priority);
|
||||
}
|
||||
}
|
||||
|
||||
if (eventSetting.EnableFacebookAnalytics)
|
||||
catch (Exception ex)
|
||||
{
|
||||
FBService.LogEvent(eventName, null, dict);
|
||||
if (FirebaseUtil.IsReady)
|
||||
{
|
||||
Crashlytics.LogException(ex);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"Catch Error: {ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 上报 Adjust 事件
|
||||
|
|
@ -300,14 +317,7 @@ namespace Guru
|
|||
/// <param name="priority"></param>
|
||||
public static void Track(string key, Dictionary<string, dynamic> data = null, EventSetting setting = null, int priority = -1)
|
||||
{
|
||||
if (null != data)
|
||||
{
|
||||
LogEvent(key, data, setting, priority);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogEvent(key, setting, priority);
|
||||
}
|
||||
TrackEvent(key, data, setting, priority);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -318,7 +328,7 @@ namespace Guru
|
|||
/// <param name="isException"></param>
|
||||
public static void LogCrashlytics(string msg, bool isException = true)
|
||||
{
|
||||
if (!_isInited) return;
|
||||
if (!_isInitOnce) return;
|
||||
if (isException)
|
||||
{
|
||||
LogCrashlytics(new Exception(msg));
|
||||
|
|
@ -332,84 +342,15 @@ namespace Guru
|
|||
|
||||
public static void LogCrashlytics(Exception exp)
|
||||
{
|
||||
if (!_isInited) return;
|
||||
if (!_isInitOnce) return;
|
||||
CrashlyticsAgent.LogException(exp);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 打点缓存
|
||||
|
||||
private static Queue<SavedLog> _savedLogs;
|
||||
|
||||
internal static Queue<SavedLog> SavedLogs
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_savedLogs == null) _savedLogs = new Queue<SavedLog>(20);
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
internal class SavedLog
|
||||
{
|
||||
public string key;
|
||||
public int priority;
|
||||
public Dictionary<string, dynamic> data;
|
||||
public Analytics.EventSetting setting;
|
||||
|
||||
public SavedLog()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存打点信息
|
||||
/// </summary>
|
||||
/// <param name="_key"></param>
|
||||
/// <param name="_data"></param>
|
||||
/// <param name="_setting"></param>
|
||||
/// <param name="_priority"></param>
|
||||
public SavedLog(string _key, Dictionary<string, dynamic> _data = null, Analytics.EventSetting _setting = null, int _priority = -1)
|
||||
{
|
||||
key = _key;
|
||||
data = _data;
|
||||
setting = _setting;
|
||||
priority = _priority;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d13f245a2ea24c8ebdb957ad4ba79ca4
|
||||
timeCreated: 1721908201
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Guru
|
||||
{
|
||||
|
||||
public interface IEventDriver
|
||||
{
|
||||
void TriggerFlush();
|
||||
void AddEvent(TrackingEvent trackingEvent);
|
||||
}
|
||||
|
||||
public interface IPropertyCollecter
|
||||
{
|
||||
void AddProperty(string key, string value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public abstract class AbstractEventDriver: IEventDriver, IPropertyCollecter
|
||||
{
|
||||
private GuruEventBuffer<TrackingEvent> _eventBuffer = new GuruEventBuffer<TrackingEvent>();
|
||||
private GuruEventBuffer<TrackingProperty> _propertyBuffer = new GuruEventBuffer<TrackingProperty>();
|
||||
|
||||
// Firebase 是否可用
|
||||
private bool _isDriverReady = false;
|
||||
|
||||
public void TriggerFlush()
|
||||
{
|
||||
_isDriverReady = true;
|
||||
FlushAll();
|
||||
}
|
||||
|
||||
|
||||
public void AddEvent(string eventName, Dictionary<string, dynamic> data = null,
|
||||
Analytics.EventSetting setting = null, int priority = -1)
|
||||
{
|
||||
var trackingEvent= new TrackingEvent(eventName, data, setting, priority);
|
||||
AddEvent(trackingEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加事件
|
||||
/// </summary>
|
||||
/// <param name="trackingEvent"></param>
|
||||
public void AddEvent(TrackingEvent trackingEvent)
|
||||
{
|
||||
if (_isDriverReady)
|
||||
{
|
||||
FlushTrackingEvent(trackingEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
_eventBuffer.Push(trackingEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加属性
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="value"></param>
|
||||
public void AddProperty(string key, string value)
|
||||
{
|
||||
var property = new TrackingProperty(key, value);
|
||||
if (_isDriverReady)
|
||||
{
|
||||
FlushProperty(property);
|
||||
}
|
||||
else
|
||||
{
|
||||
_propertyBuffer.Push(property);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入所有
|
||||
/// </summary>
|
||||
private void FlushAll()
|
||||
{
|
||||
while(_eventBuffer.Pop(out var trackingEvent))
|
||||
{
|
||||
FlushTrackingEvent(trackingEvent);
|
||||
}
|
||||
|
||||
while (_propertyBuffer.Pop(out var property))
|
||||
{
|
||||
FlushProperty(property);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 发送事件
|
||||
/// </summary>
|
||||
/// <param name="trackEvent"></param>
|
||||
protected abstract void FlushTrackingEvent(TrackingEvent trackEvent);
|
||||
|
||||
|
||||
protected abstract void FlushProperty(TrackingProperty property);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: fe02e66845f64aafa94654814822930a
|
||||
timeCreated: 1721916181
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void FlushProperty(TrackingProperty property)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f064544085c8401d988b9eae91bd79b1
|
||||
timeCreated: 1721910840
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
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);
|
||||
}
|
||||
|
||||
protected override void FlushProperty(TrackingProperty property)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 305a62f1c0fe4a16b7c9101264be523b
|
||||
timeCreated: 1721910530
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输出属性
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
protected override void FlushProperty(TrackingProperty property)
|
||||
{
|
||||
FirebaseAnalytics.SetUserProperty(property.key, property.value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7a4c2262ab86431ba6d5961e7453d60f
|
||||
timeCreated: 1721905429
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
namespace Guru
|
||||
{
|
||||
using System.Collections.Concurrent;
|
||||
public class GuruEventBuffer<T>
|
||||
{
|
||||
private ConcurrentQueue<T> _buffer;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public GuruEventBuffer()
|
||||
{
|
||||
_buffer = new ConcurrentQueue<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 入栈
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
public void Push(T item)
|
||||
{
|
||||
_buffer.Enqueue(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 出栈
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public bool Pop(out T item)
|
||||
{
|
||||
return _buffer.TryDequeue(out item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f6dd65ae849944c59be2182eb64db34a
|
||||
timeCreated: 1721899117
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
namespace Guru
|
||||
{
|
||||
public class GuruEventDriver: AbstractEventDriver
|
||||
{
|
||||
protected override void FlushTrackingEvent(TrackingEvent trackingEvent)
|
||||
{
|
||||
GuruAnalytics.Instance.LogEvent(trackingEvent.eventName, trackingEvent.data, trackingEvent.priority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输出属性
|
||||
/// </summary>
|
||||
/// <param name="property"></param>
|
||||
protected override void FlushProperty(TrackingProperty property)
|
||||
{
|
||||
GuruAnalytics.Instance.SetUserProperty(property.key, property.value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d3fee5c262ca43c387ce76d52fb149c8
|
||||
timeCreated: 1721908696
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
namespace Guru
|
||||
{
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
public class GuruPropertyBuffer
|
||||
{
|
||||
private ConcurrentQueue<TrackingEvent> _propertyQueue;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 38faf6b8af864e829144d9de91c4b0a5
|
||||
timeCreated: 1721983424
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
|
||||
namespace Guru
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// 追踪事件
|
||||
/// </summary>
|
||||
public class TrackingEvent
|
||||
{
|
||||
public string eventName;
|
||||
public int priority;
|
||||
public Dictionary<string, dynamic> data;
|
||||
public Analytics.EventSetting setting;
|
||||
|
||||
public TrackingEvent()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存打点信息
|
||||
/// </summary>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="_data"></param>
|
||||
/// <param name="_setting"></param>
|
||||
/// <param name="_priority"></param>
|
||||
public TrackingEvent(string eventName, Dictionary<string, dynamic> data = null, Analytics.EventSetting setting = null, int priority = -1)
|
||||
{
|
||||
this.eventName = eventName;
|
||||
this.data = data;
|
||||
this.setting = setting;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"eventName: {eventName}, data: {data}, setting: {setting}, priority: {priority}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 追踪用户属性
|
||||
/// </summary>
|
||||
public class TrackingProperty
|
||||
{
|
||||
public string key;
|
||||
public string value;
|
||||
|
||||
public TrackingProperty(string key, string value)
|
||||
{
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"property: {key}:{value}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6b9532ec20444115a888ffc89276172a
|
||||
timeCreated: 1721983520
|
||||
|
|
@ -58,7 +58,7 @@ namespace Guru
|
|||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
PlayerPrefs.SetString(nameof(FirebaseId), value);
|
||||
GuruAnalytics.SetFirebaseId(value);
|
||||
GuruAnalytics.Instance.SetFirebaseId(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ namespace Guru
|
|||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
PlayerPrefs.SetString(nameof(AdjustId), value);
|
||||
GuruAnalytics.SetAdjustId(value);
|
||||
GuruAnalytics.Instance.SetAdjustId(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ namespace Guru
|
|||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
PlayerPrefs.SetString(nameof(GoogleAdId), value);
|
||||
GuruAnalytics.SetAdId(value);
|
||||
GuruAnalytics.Instance.SetAdId(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,44 +1,38 @@
|
|||
using System.Collections.Generic;
|
||||
using Facebook.Unity;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Guru
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Facebook.Unity;
|
||||
using UnityEngine;
|
||||
|
||||
[MonoSingleton(EMonoSingletonType.CreateOnNewGameObject, false)]
|
||||
public class FBService : MonoSingleton<FBService>
|
||||
{
|
||||
public static readonly string LOG_TAG = "FB";
|
||||
private const string Tag = "[FB]";
|
||||
private bool _isInitOnce;
|
||||
private Action _onInitComplete;
|
||||
|
||||
public void StartService()
|
||||
public void StartService(Action onInitComplete = null)
|
||||
{
|
||||
if (!FB.IsInitialized)
|
||||
{
|
||||
// Initialize the Facebook SDK
|
||||
FB.Init(InitCallback, OnHideUnity);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Already initialized, signal an app activation App Event
|
||||
FB.ActivateApp();
|
||||
}
|
||||
if(_isInitOnce) return;
|
||||
_isInitOnce = true;
|
||||
|
||||
_onInitComplete = onInitComplete;
|
||||
// Initialize the Facebook SDK
|
||||
FB.Init(InitCallback, OnHideUnity);
|
||||
}
|
||||
|
||||
private void InitCallback()
|
||||
{
|
||||
if (FB.IsInitialized)
|
||||
{
|
||||
// Signal an app activation App Event
|
||||
FB.ActivateApp();
|
||||
FB.Mobile.SetAdvertiserIDCollectionEnabled(true);
|
||||
FB.Mobile.SetAutoLogAppEventsEnabled(false); // 关闭自动打点上报
|
||||
|
||||
// Signal an app activation App Event
|
||||
FB.ActivateApp();
|
||||
FB.Mobile.SetAdvertiserIDCollectionEnabled(true);
|
||||
FB.Mobile.SetAutoLogAppEventsEnabled(false); // 关闭自动打点上报
|
||||
#if UNITY_IOS
|
||||
FB.Mobile.SetAdvertiserTrackingEnabled(true);
|
||||
FB.Mobile.SetAdvertiserTrackingEnabled(true);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.E(LOG_TAG, "Failed to Initialize the Facebook SDK");
|
||||
}
|
||||
_onInitComplete?.Invoke();
|
||||
}
|
||||
|
||||
private void OnHideUnity(bool isGameShown)
|
||||
|
|
@ -81,13 +75,13 @@ namespace Guru
|
|||
}
|
||||
|
||||
|
||||
private static bool IsAvailable
|
||||
public static bool IsAvailable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!FB.IsInitialized)
|
||||
{
|
||||
Debug.LogError("[FB] FB is not initialized, please call <FBService.StartService> first.");
|
||||
Debug.LogError($"{Tag} FB is not initialized, please call <FBService.StartService> first.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -8,14 +8,31 @@ namespace Guru
|
|||
public static partial class FirebaseUtil
|
||||
{
|
||||
private static int _messageRetry = 5;
|
||||
public static bool? IsInitMessage;
|
||||
|
||||
// public static bool? IsInitMessage;
|
||||
private static bool _isAutoFetchFcmToken = true;
|
||||
private static bool _isFetchOnce = false;
|
||||
|
||||
public static void SetAutoFetchFcmToken(bool value)
|
||||
{
|
||||
_isAutoFetchFcmToken = value;
|
||||
}
|
||||
|
||||
public static void InitializeMessage()
|
||||
{
|
||||
if (_isAutoFetchFcmToken)
|
||||
{
|
||||
StartFetchFcmToken();
|
||||
}
|
||||
}
|
||||
|
||||
public static void StartFetchFcmToken()
|
||||
{
|
||||
if (_isFetchOnce) return;
|
||||
_isFetchOnce = true;
|
||||
|
||||
FirebaseMessaging.TokenReceived += OnTokenReceived;
|
||||
FirebaseMessaging.MessageReceived += OnMessageReceived;
|
||||
GetFCMToken();
|
||||
IsInitMessage = true;
|
||||
}
|
||||
|
||||
private static void GetFCMToken()
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ namespace Guru
|
|||
public static partial class FirebaseUtil
|
||||
{
|
||||
private static readonly string LOG_TAG = "Firebase";
|
||||
private static bool _isDebug = false;
|
||||
private static bool _isReady = false;
|
||||
public static bool IsReady => _isReady;
|
||||
|
||||
|
|
@ -19,14 +18,13 @@ namespace Guru
|
|||
|
||||
public static Action<bool> OnFirebaseAuthResult;
|
||||
public static Action<bool> OnUserAuthResult;
|
||||
public static Action<string> OnAdjustDeeplinkCallback = null;
|
||||
|
||||
|
||||
|
||||
public static void InitFirebase(Action callback, bool isDebug = false)
|
||||
public static void InitFirebase(Action callback)
|
||||
{
|
||||
_isReady = false;
|
||||
_isDebug = isDebug;
|
||||
Analytics.InitAnalytics(); // 打点提前初始化
|
||||
// Analytics.InitAnalytics(); // 打点提前初始化
|
||||
|
||||
// Loom.StartUp(); // 确保主线程开启
|
||||
|
||||
|
|
@ -103,6 +101,7 @@ namespace Guru
|
|||
FirebaseAnalytics.GetAnalyticsInstanceIdAsync()
|
||||
.ContinueWithOnMainThread(task =>
|
||||
{
|
||||
|
||||
if (task.IsCompleted && !string.IsNullOrEmpty(task.Result))
|
||||
{
|
||||
// 保存本地ID备份
|
||||
|
|
@ -119,27 +118,29 @@ namespace Guru
|
|||
string fbAppId = GuruSettings.Instance.IPMSetting.FacebookAppId;
|
||||
|
||||
if (!string.IsNullOrEmpty(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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@ namespace Guru
|
|||
public static class CrashlyticsAgent
|
||||
{
|
||||
private static bool _initOnce;
|
||||
private static bool _isReady;
|
||||
private static bool IsFirebaseReady => FirebaseUtil.IsFirebaseInitialized;
|
||||
|
||||
private static Queue<Exception> _expCache;
|
||||
private static bool _hasSetUser = false;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -32,45 +31,18 @@ namespace Guru
|
|||
LogType.Assert,
|
||||
};
|
||||
|
||||
public static void Install()
|
||||
public static void Init()
|
||||
{
|
||||
if (_initOnce) return;
|
||||
_initOnce = true;
|
||||
_expCache = new Queue<Exception>(20);
|
||||
|
||||
Application.logMessageReceived -= OnReceivedMessage;
|
||||
Application.logMessageReceived += OnReceivedMessage;
|
||||
|
||||
// Application.logMessageReceivedThreaded -= OnReceivedMessage;
|
||||
// Application.logMessageReceivedThreaded += OnReceivedMessage;
|
||||
|
||||
if (FirebaseUtil.IsReady)
|
||||
{
|
||||
OnFirebaseComplete(true);
|
||||
return;
|
||||
}
|
||||
|
||||
FirebaseUtil.onInitComplete -= OnFirebaseComplete;
|
||||
FirebaseUtil.onInitComplete += OnFirebaseComplete;
|
||||
Crashlytics.IsCrashlyticsCollectionEnabled = true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -101,14 +73,8 @@ namespace Guru
|
|||
|
||||
public static void LogException(Exception ex)
|
||||
{
|
||||
if (!_isReady)
|
||||
{
|
||||
Install();
|
||||
_expCache.Enqueue(ex);
|
||||
return;
|
||||
}
|
||||
if (!IsFirebaseReady) return;
|
||||
Crashlytics.LogException(ex);
|
||||
// CheckSetUser();
|
||||
}
|
||||
|
||||
public static void LogException(string msg)
|
||||
|
|
@ -118,15 +84,14 @@ namespace Guru
|
|||
|
||||
public static void Log(string msg)
|
||||
{
|
||||
if (!_isReady) return;
|
||||
if (!IsFirebaseReady) return;
|
||||
Crashlytics.Log(msg);
|
||||
// CheckSetUser();
|
||||
}
|
||||
|
||||
|
||||
public static void SetCustomKey(string key, string value)
|
||||
{
|
||||
if (!_isReady) return;
|
||||
if (!IsFirebaseReady) return;
|
||||
Crashlytics.SetCustomKey(key, value);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,9 +140,13 @@ namespace Guru
|
|||
public class AnalyticsSetting
|
||||
{
|
||||
[SerializeField] private int levelEndSuccessNum = 50;
|
||||
[Obsolete("Will not use in next version", false)]
|
||||
[SerializeField] private bool enalbeFirebaseAnalytics = true;
|
||||
[Obsolete("Will not use in next version", false)]
|
||||
[SerializeField] private bool enalbeFacebookAnalytics = true;
|
||||
[Obsolete("Will not use in next version", false)]
|
||||
[SerializeField] private bool enalbeAdjustAnalytics = true;
|
||||
|
||||
[SerializeField] internal List<AdjustEvent> adjustEventList;
|
||||
|
||||
public int LevelEndSuccessNum => levelEndSuccessNum;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ namespace Guru
|
|||
|
||||
private void OnStatueChanged(AdStatusInfo info)
|
||||
{
|
||||
if (_model == null) return;
|
||||
_model.monitorInfo = CreateMonitorInfo();
|
||||
|
||||
if (info != null)
|
||||
|
|
@ -106,7 +107,7 @@ namespace Guru
|
|||
string msg = "";
|
||||
bool loaded = false;
|
||||
|
||||
if (!ADService.Instance.IsInitialized)
|
||||
if (ADService.Instance == null || !ADService.Instance.IsInitialized)
|
||||
{
|
||||
msg = ColoredText("AdService not initialized...", Consts.ColorRed);
|
||||
return msg;
|
||||
|
|
|
|||
|
|
@ -1132,7 +1132,7 @@ namespace Guru
|
|||
|
||||
private void ReportGoogleOrderLost(GoogleOrderData data)
|
||||
{
|
||||
Analytics.LogEvent("google_order_lost", new Dictionary<string, dynamic>()
|
||||
Analytics.TrackEvent("google_order_lost", new Dictionary<string, dynamic>()
|
||||
{
|
||||
["data"] = data.ToString(),
|
||||
}, new Analytics.EventSetting()
|
||||
|
|
@ -1144,7 +1144,7 @@ namespace Guru
|
|||
|
||||
private void ReportAppleOrderLost(AppleOrderData data)
|
||||
{
|
||||
Analytics.LogEvent("apple_order_lost", new Dictionary<string, dynamic>()
|
||||
Analytics.TrackEvent("apple_order_lost", new Dictionary<string, dynamic>()
|
||||
{
|
||||
["data"] = data.ToString(),
|
||||
}, new Analytics.EventSetting()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 10f8491dbf6264bc393cb7578397ec7f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bc0062a7d36f144beabfdea9e3a8e2c7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4725a71a48aec4a5083c37f5ff09a550
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
|
@ -0,0 +1,32 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 05a3c5d94488c454ea77722fc8f0a80c
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
-keep class com.facebook.unity.* { *; }
|
||||
-keepattributes Signature
|
||||
-keep class com.guru.unity.monitor.** { *; }
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d0ac28ef06c604f789bb32b31225c157
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e5d09fde296334b46844a972d0289dcc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 18c322abb3a1e4d9eaea5e395dab1377
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
Exclude iOS: 0
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: true
|
||||
CPU: AnyCPU
|
||||
CompileFlags:
|
||||
FrameworkDependencies:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ec7317011341a40a1a0ee7ae5f38f270
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a4ccb52ed7f6b4dff8731e9e93293ccb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,337 @@
|
|||
#if 0
|
||||
#elif defined(__arm64__) && __arm64__
|
||||
// Generated by Apple Swift version 5.9.2 effective-4.1.50 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
|
||||
#ifndef CONNECTIVITY_SWIFT_H
|
||||
#define CONNECTIVITY_SWIFT_H
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wgcc-compat"
|
||||
|
||||
#if !defined(__has_include)
|
||||
# define __has_include(x) 0
|
||||
#endif
|
||||
#if !defined(__has_attribute)
|
||||
# define __has_attribute(x) 0
|
||||
#endif
|
||||
#if !defined(__has_feature)
|
||||
# define __has_feature(x) 0
|
||||
#endif
|
||||
#if !defined(__has_warning)
|
||||
# define __has_warning(x) 0
|
||||
#endif
|
||||
|
||||
#if __has_include(<swift/objc-prologue.h>)
|
||||
# include <swift/objc-prologue.h>
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic ignored "-Wauto-import"
|
||||
#if defined(__OBJC__)
|
||||
#include <Foundation/Foundation.h>
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <cstdbool>
|
||||
#include <cstring>
|
||||
#include <stdlib.h>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
#if defined(__arm64e__) && __has_include(<ptrauth.h>)
|
||||
# include <ptrauth.h>
|
||||
#else
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wreserved-macro-identifier"
|
||||
# ifndef __ptrauth_swift_value_witness_function_pointer
|
||||
# define __ptrauth_swift_value_witness_function_pointer(x)
|
||||
# endif
|
||||
# ifndef __ptrauth_swift_class_method_pointer
|
||||
# define __ptrauth_swift_class_method_pointer(x)
|
||||
# endif
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(SWIFT_TYPEDEFS)
|
||||
# define SWIFT_TYPEDEFS 1
|
||||
# if __has_include(<uchar.h>)
|
||||
# include <uchar.h>
|
||||
# elif !defined(__cplusplus)
|
||||
typedef uint_least16_t char16_t;
|
||||
typedef uint_least32_t char32_t;
|
||||
# endif
|
||||
typedef float swift_float2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef float swift_float3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef float swift_float4 __attribute__((__ext_vector_type__(4)));
|
||||
typedef double swift_double2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef double swift_double3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef double swift_double4 __attribute__((__ext_vector_type__(4)));
|
||||
typedef int swift_int2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef int swift_int3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef int swift_int4 __attribute__((__ext_vector_type__(4)));
|
||||
typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
|
||||
#endif
|
||||
|
||||
#if !defined(SWIFT_PASTE)
|
||||
# define SWIFT_PASTE_HELPER(x, y) x##y
|
||||
# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
|
||||
#endif
|
||||
#if !defined(SWIFT_METATYPE)
|
||||
# define SWIFT_METATYPE(X) Class
|
||||
#endif
|
||||
#if !defined(SWIFT_CLASS_PROPERTY)
|
||||
# if __has_feature(objc_class_property)
|
||||
# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
|
||||
# else
|
||||
# define SWIFT_CLASS_PROPERTY(...)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_RUNTIME_NAME)
|
||||
# if __has_attribute(objc_runtime_name)
|
||||
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
|
||||
# else
|
||||
# define SWIFT_RUNTIME_NAME(X)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_COMPILE_NAME)
|
||||
# if __has_attribute(swift_name)
|
||||
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
|
||||
# else
|
||||
# define SWIFT_COMPILE_NAME(X)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_METHOD_FAMILY)
|
||||
# if __has_attribute(objc_method_family)
|
||||
# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
|
||||
# else
|
||||
# define SWIFT_METHOD_FAMILY(X)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_NOESCAPE)
|
||||
# if __has_attribute(noescape)
|
||||
# define SWIFT_NOESCAPE __attribute__((noescape))
|
||||
# else
|
||||
# define SWIFT_NOESCAPE
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_RELEASES_ARGUMENT)
|
||||
# if __has_attribute(ns_consumed)
|
||||
# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed))
|
||||
# else
|
||||
# define SWIFT_RELEASES_ARGUMENT
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_WARN_UNUSED_RESULT)
|
||||
# if __has_attribute(warn_unused_result)
|
||||
# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||
# else
|
||||
# define SWIFT_WARN_UNUSED_RESULT
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_NORETURN)
|
||||
# if __has_attribute(noreturn)
|
||||
# define SWIFT_NORETURN __attribute__((noreturn))
|
||||
# else
|
||||
# define SWIFT_NORETURN
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_CLASS_EXTRA)
|
||||
# define SWIFT_CLASS_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_PROTOCOL_EXTRA)
|
||||
# define SWIFT_PROTOCOL_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_ENUM_EXTRA)
|
||||
# define SWIFT_ENUM_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_CLASS)
|
||||
# if __has_attribute(objc_subclassing_restricted)
|
||||
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
|
||||
# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# else
|
||||
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_RESILIENT_CLASS)
|
||||
# if __has_attribute(objc_class_stub)
|
||||
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub))
|
||||
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME)
|
||||
# else
|
||||
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME)
|
||||
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_PROTOCOL)
|
||||
# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
|
||||
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
|
||||
#endif
|
||||
#if !defined(SWIFT_EXTENSION)
|
||||
# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
|
||||
#endif
|
||||
#if !defined(OBJC_DESIGNATED_INITIALIZER)
|
||||
# if __has_attribute(objc_designated_initializer)
|
||||
# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||
# else
|
||||
# define OBJC_DESIGNATED_INITIALIZER
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_ENUM_ATTR)
|
||||
# if __has_attribute(enum_extensibility)
|
||||
# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility)))
|
||||
# else
|
||||
# define SWIFT_ENUM_ATTR(_extensibility)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_ENUM)
|
||||
# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
|
||||
# if __has_feature(generalized_swift_name)
|
||||
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
|
||||
# else
|
||||
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_UNAVAILABLE)
|
||||
# define SWIFT_UNAVAILABLE __attribute__((unavailable))
|
||||
#endif
|
||||
#if !defined(SWIFT_UNAVAILABLE_MSG)
|
||||
# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
|
||||
#endif
|
||||
#if !defined(SWIFT_AVAILABILITY)
|
||||
# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
|
||||
#endif
|
||||
#if !defined(SWIFT_WEAK_IMPORT)
|
||||
# define SWIFT_WEAK_IMPORT __attribute__((weak_import))
|
||||
#endif
|
||||
#if !defined(SWIFT_DEPRECATED)
|
||||
# define SWIFT_DEPRECATED __attribute__((deprecated))
|
||||
#endif
|
||||
#if !defined(SWIFT_DEPRECATED_MSG)
|
||||
# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
|
||||
#endif
|
||||
#if !defined(SWIFT_DEPRECATED_OBJC)
|
||||
# if __has_feature(attribute_diagnose_if_objc)
|
||||
# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning")))
|
||||
# else
|
||||
# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg)
|
||||
# endif
|
||||
#endif
|
||||
#if defined(__OBJC__)
|
||||
#if !defined(IBSegueAction)
|
||||
# define IBSegueAction
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SWIFT_EXTERN)
|
||||
# if defined(__cplusplus)
|
||||
# define SWIFT_EXTERN extern "C"
|
||||
# else
|
||||
# define SWIFT_EXTERN extern
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(SWIFT_CALL)
|
||||
# define SWIFT_CALL __attribute__((swiftcall))
|
||||
#endif
|
||||
#if !defined(SWIFT_INDIRECT_RESULT)
|
||||
# define SWIFT_INDIRECT_RESULT __attribute__((swift_indirect_result))
|
||||
#endif
|
||||
#if !defined(SWIFT_CONTEXT)
|
||||
# define SWIFT_CONTEXT __attribute__((swift_context))
|
||||
#endif
|
||||
#if !defined(SWIFT_ERROR_RESULT)
|
||||
# define SWIFT_ERROR_RESULT __attribute__((swift_error_result))
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
# define SWIFT_NOEXCEPT noexcept
|
||||
#else
|
||||
# define SWIFT_NOEXCEPT
|
||||
#endif
|
||||
#if !defined(SWIFT_C_INLINE_THUNK)
|
||||
# if __has_attribute(always_inline)
|
||||
# if __has_attribute(nodebug)
|
||||
# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline)) __attribute__((nodebug))
|
||||
# else
|
||||
# define SWIFT_C_INLINE_THUNK inline __attribute__((always_inline))
|
||||
# endif
|
||||
# else
|
||||
# define SWIFT_C_INLINE_THUNK inline
|
||||
# endif
|
||||
#endif
|
||||
#if defined(_WIN32)
|
||||
#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL)
|
||||
# define SWIFT_IMPORT_STDLIB_SYMBOL __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#if !defined(SWIFT_IMPORT_STDLIB_SYMBOL)
|
||||
# define SWIFT_IMPORT_STDLIB_SYMBOL
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__OBJC__)
|
||||
#if __has_feature(objc_modules)
|
||||
#if __has_warning("-Watimport-in-framework-header")
|
||||
#pragma clang diagnostic ignored "-Watimport-in-framework-header"
|
||||
#endif
|
||||
@import Foundation;
|
||||
@import ObjectiveC;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
|
||||
#pragma clang diagnostic ignored "-Wduplicate-method-arg"
|
||||
#if __has_warning("-Wpragma-clang-attribute")
|
||||
# pragma clang diagnostic ignored "-Wpragma-clang-attribute"
|
||||
#endif
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma clang diagnostic ignored "-Wnullability"
|
||||
#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
|
||||
|
||||
#if __has_attribute(external_source_symbol)
|
||||
# pragma push_macro("any")
|
||||
# undef any
|
||||
# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="Connectivity",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol))
|
||||
# pragma pop_macro("any")
|
||||
#endif
|
||||
|
||||
#if defined(__OBJC__)
|
||||
@class NSString;
|
||||
|
||||
SWIFT_CLASS("_TtC12Connectivity12Connectivity")
|
||||
@interface Connectivity : NSObject
|
||||
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) Connectivity * _Nonnull shared;)
|
||||
+ (Connectivity * _Nonnull)shared SWIFT_WARN_UNUSED_RESULT;
|
||||
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, copy) NSString * _Nonnull CONNECTIVITY_NONE;)
|
||||
+ (NSString * _Nonnull)CONNECTIVITY_NONE SWIFT_WARN_UNUSED_RESULT;
|
||||
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, copy) NSString * _Nonnull CONNECTIVITY_WIFI;)
|
||||
+ (NSString * _Nonnull)CONNECTIVITY_WIFI SWIFT_WARN_UNUSED_RESULT;
|
||||
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, copy) NSString * _Nonnull CONNECTIVITY_MOBILE;)
|
||||
+ (NSString * _Nonnull)CONNECTIVITY_MOBILE SWIFT_WARN_UNUSED_RESULT;
|
||||
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, copy) NSString * _Nonnull CONNECTIVITY_ETHERNET;)
|
||||
+ (NSString * _Nonnull)CONNECTIVITY_ETHERNET SWIFT_WARN_UNUSED_RESULT;
|
||||
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, copy) NSString * _Nonnull CONNECTIVITY_VPN;)
|
||||
+ (NSString * _Nonnull)CONNECTIVITY_VPN SWIFT_WARN_UNUSED_RESULT;
|
||||
SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, copy) NSString * _Nonnull CONNECTIVITY_OTHER;)
|
||||
+ (NSString * _Nonnull)CONNECTIVITY_OTHER SWIFT_WARN_UNUSED_RESULT;
|
||||
- (nonnull instancetype)init SWIFT_UNAVAILABLE;
|
||||
+ (nonnull instancetype)new SWIFT_DEPRECATED_MSG("-init is unavailable");
|
||||
- (void)initializeWithCompletion:(void (^ _Nonnull)(BOOL))completion;
|
||||
- (NSArray<NSString *> * _Nonnull)checkConnectionType SWIFT_WARN_UNUSED_RESULT;
|
||||
@end
|
||||
|
||||
#endif
|
||||
#if __has_attribute(external_source_symbol)
|
||||
# pragma clang attribute pop
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
#endif
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error unsupported Swift architecture
|
||||
#endif
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c7072e499221b489e8a171a746c1d381
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b3be6515c98fc4516b74799d2232851a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 009197294dbfe4bd5b64f833fce7277e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: db929fad7809a40a6af254c5262adb3a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d014052e45f6948db82f9fbecdb02a96
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5a2b967c5b7f944adb348971a0e13c79
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ABIRoot": {
|
||||
"kind": "Root",
|
||||
"name": "TopLevel",
|
||||
"printedName": "TopLevel",
|
||||
"json_format_version": 8
|
||||
},
|
||||
"ConstValues": []
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b8637a4450c6b4ca895cd05427db6ffc
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2b7b377a06cfe4472ace76077b0d1e24
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: be5b523ba98e649d9938fc7df1e7b55a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
framework module Connectivity {
|
||||
header "Connectivity-Swift.h"
|
||||
requires objc
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 97a465fd6df3b4f72a477ef19bf727a9
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1a90376b0826241cf8ed25c4ba2b91fc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>files</key>
|
||||
<dict>
|
||||
<key>Headers/Connectivity-Swift.h</key>
|
||||
<data>
|
||||
2jZWRNZEB9lWoT02/WI0gpx8bUY=
|
||||
</data>
|
||||
<key>Info.plist</key>
|
||||
<data>
|
||||
lVs8E6FtUHvDAsoK7zwpgZ+1m84=
|
||||
</data>
|
||||
<key>Modules/Connectivity.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo</key>
|
||||
<data>
|
||||
3vRjRUNrw8fWaShfTaH+cBfxfLE=
|
||||
</data>
|
||||
<key>Modules/Connectivity.swiftmodule/arm64-apple-ios.abi.json</key>
|
||||
<data>
|
||||
FSPnLbho3G+LL9smI3XgVOqBIQ4=
|
||||
</data>
|
||||
<key>Modules/Connectivity.swiftmodule/arm64-apple-ios.swiftdoc</key>
|
||||
<data>
|
||||
HgPMAkcK2+NGvcVfwyFJ9u/nd0k=
|
||||
</data>
|
||||
<key>Modules/Connectivity.swiftmodule/arm64-apple-ios.swiftmodule</key>
|
||||
<data>
|
||||
nK9APrK3atZTGuid35+A6Dde02M=
|
||||
</data>
|
||||
<key>Modules/module.modulemap</key>
|
||||
<data>
|
||||
JQ0IhYrWi46ysbcXxnNfARgJPro=
|
||||
</data>
|
||||
</dict>
|
||||
<key>files2</key>
|
||||
<dict>
|
||||
<key>Headers/Connectivity-Swift.h</key>
|
||||
<dict>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
xwPPIVygOJDaH/CCrDO25Y2645Q/IQYSiJrV3eJJy+M=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Modules/Connectivity.swiftmodule/Project/arm64-apple-ios.swiftsourceinfo</key>
|
||||
<dict>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
Qgk/xiutw35xy8VeU5niELPbBEi5gVVuXYai3rhRrbI=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Modules/Connectivity.swiftmodule/arm64-apple-ios.abi.json</key>
|
||||
<dict>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
KnRdWE4y6t4QM5zi5JDptPdHFgJy1Tku+7GLkZS2aNM=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Modules/Connectivity.swiftmodule/arm64-apple-ios.swiftdoc</key>
|
||||
<dict>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
ZNpy4/pGL15IFXpHTav2UvUYM7kQPN/0eTjxtfLqYq8=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Modules/Connectivity.swiftmodule/arm64-apple-ios.swiftmodule</key>
|
||||
<dict>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
Et4EI2nA28WHGnFW0ki2IUjCTs703CjwdRvol0loQGo=
|
||||
</data>
|
||||
</dict>
|
||||
<key>Modules/module.modulemap</key>
|
||||
<dict>
|
||||
<key>hash2</key>
|
||||
<data>
|
||||
07XGBKw7w58ugYy09lbnsq9IhqStrsOHCKCfwm/MrpU=
|
||||
</data>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>rules</key>
|
||||
<dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^version.plist$</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>rules2</key>
|
||||
<dict>
|
||||
<key>.*\.dSYM($|/)</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>11</real>
|
||||
</dict>
|
||||
<key>^(.*/)?\.DS_Store$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>2000</real>
|
||||
</dict>
|
||||
<key>^.*</key>
|
||||
<true/>
|
||||
<key>^.*\.lproj/</key>
|
||||
<dict>
|
||||
<key>optional</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1000</real>
|
||||
</dict>
|
||||
<key>^.*\.lproj/locversion.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>1100</real>
|
||||
</dict>
|
||||
<key>^Base\.lproj/</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>1010</real>
|
||||
</dict>
|
||||
<key>^Info\.plist$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^PkgInfo$</key>
|
||||
<dict>
|
||||
<key>omit</key>
|
||||
<true/>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^embedded\.provisionprofile$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
<key>^version\.plist$</key>
|
||||
<dict>
|
||||
<key>weight</key>
|
||||
<real>20</real>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 158f1aee738db4ad8a07a36e89614060
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a0a25c648675a494eb50f2dd3159ff81
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d1121778023d64cafad6d7eb947140d0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
|
||||
namespace Guru.Network
|
||||
{
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class NetworkStatusMonitor
|
||||
{
|
||||
private const string Tag = "[NET]";
|
||||
private const string NETWORK_STATUS_NONE = "none";
|
||||
private const string NETWORK_STATUS_MOBILE = "mobile";
|
||||
private const string NETWORK_STATUS_WIFI = "wifi";
|
||||
private const string NETWORK_STATUS_ETHERNET = "ethernet";
|
||||
private const string NETWORK_STATUS_VPN = "vpn";
|
||||
private const string NETWORK_STATUS_TETHER = "tether";
|
||||
private const string NETWORK_STATUS_BLUETOOTH = "bluetooth";
|
||||
private const string NETWORK_STATUS_OTHER = "other";
|
||||
|
||||
private bool _isReady = false;
|
||||
|
||||
private INetworkStatusProxy _proxy;
|
||||
private INetworkStatusProxy Proxy
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_proxy == null)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
_proxy = new NetworkStatusEditor();
|
||||
#elif UNITY_ANDROID
|
||||
_proxy = new NetworkStatusAndroid();
|
||||
#elif UNITY_IOS
|
||||
_proxy = new NetworkStatusIOS();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_proxy == null)
|
||||
{
|
||||
// 如果未实现则报异常
|
||||
throw new NotImplementedException("Can't find NetworkStatusProxy instance!!");
|
||||
}
|
||||
|
||||
return _proxy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 网络状态列表
|
||||
/// </summary>
|
||||
private List<string> _statusNameList = new List<string>()
|
||||
{
|
||||
NETWORK_STATUS_VPN,
|
||||
NETWORK_STATUS_TETHER,
|
||||
NETWORK_STATUS_MOBILE,
|
||||
NETWORK_STATUS_WIFI,
|
||||
NETWORK_STATUS_ETHERNET,
|
||||
NETWORK_STATUS_BLUETOOTH,
|
||||
NETWORK_STATUS_OTHER,
|
||||
NETWORK_STATUS_NONE,
|
||||
};
|
||||
|
||||
public void Init(Action<bool> onInitComplete = null)
|
||||
{
|
||||
Proxy.Init(success =>
|
||||
{
|
||||
_isReady = success;
|
||||
onInitComplete?.Invoke(success);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络状态
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetNetworkStatus()
|
||||
{
|
||||
if (_isReady)
|
||||
{
|
||||
var status = Proxy.GetNetworkStatus();
|
||||
if (status != null && status.Length > 0)
|
||||
{
|
||||
string statusName = "";
|
||||
for (int i = 0; i < _statusNameList.Count; i++)
|
||||
{
|
||||
// 根据名称优先级, 先获取到的优先上报
|
||||
statusName = _statusNameList[i];
|
||||
if (status.Contains(statusName))
|
||||
{
|
||||
Debug.Log($"{Tag} --- GetNetworkStatus: [{string.Join(",", status)}]");
|
||||
return statusName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Debug.LogWarning($"{Tag} --- Network Monitor is not ready!");
|
||||
return NETWORK_STATUS_NONE;
|
||||
}
|
||||
|
||||
// private void OnProxyInitComplete(bool success)
|
||||
// {
|
||||
// if (success)
|
||||
// {
|
||||
// Debug.Log($"{Tag} --- NetworkStatusMonitor init success");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Debug.LogError($"{Tag} --- NetworkStatusMonitor init failed");
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 89389dfafc844651bb8f6a23865edca6
|
||||
timeCreated: 1721958852
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1981d1e0510af48ff81cbd4db201318f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
namespace Guru.Network
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// 网络状态代理
|
||||
/// </summary>
|
||||
public interface INetworkStatusProxy
|
||||
{
|
||||
void Init(Action<bool> onInitComplete);
|
||||
|
||||
string[] GetNetworkStatus();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: aeba66b9f9e4413a8475bf5cc363fae1
|
||||
timeCreated: 1721957685
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
|
||||
namespace Guru.Network
|
||||
{
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class NetworkStatusAndroid: INetworkStatusProxy
|
||||
{
|
||||
private const string Tag = "[NET][AND]";
|
||||
#if UNITY_ANDROID
|
||||
private const string CONNECTIVITY_ANDROID_CLASS_NAME = "com.guru.unity.monitor.Connectivity";
|
||||
private AndroidJavaObject _connectivity;
|
||||
private bool _isReady = false;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
/// <param name="onInitComplete"></param>
|
||||
public void Init(Action<bool> onInitComplete)
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
AndroidJavaObject currentActivity = new AndroidJavaObject("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
|
||||
_connectivity = new AndroidJavaObject(CONNECTIVITY_ANDROID_CLASS_NAME).CallStatic<AndroidJavaObject>("getInstance");
|
||||
_isReady = _connectivity.Call<bool>("initialize", currentActivity);
|
||||
// Debug.LogWarning($"{Tag} --- Network status init result:{_isReady}");
|
||||
// Debug.LogWarning($"{Tag} --- _connectivity:{_connectivity}");
|
||||
onInitComplete?.Invoke(_isReady); // 调用初始化回调
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取网络状态
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string[] GetNetworkStatus()
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
if (!_isReady)
|
||||
{
|
||||
Debug.LogError($"{Tag} --- GetNetworkStatus :: initialized failed.");
|
||||
}
|
||||
else if(_connectivity != null)
|
||||
{
|
||||
return _connectivity.Call<string[]>("checkConnectionType");
|
||||
}
|
||||
|
||||
#endif
|
||||
return new string[] {"none"};
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue