com.taptap.sdk.core 4.3.4 → 4.3.10-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Mobile/Editor/NativeDependencies.xml +2 -2
- package/Mobile/Runtime/IOSNativeWrapper.cs +3 -3
- package/Mobile/Runtime/TapCoreMobile.cs +5 -5
- package/Runtime/Internal/Init/IInitTask.cs +2 -2
- package/Runtime/Internal/Log/TapLog.cs +117 -0
- package/Runtime/Internal/Log/TapLog.cs.meta +11 -0
- package/Runtime/Internal/Log.meta +8 -0
- package/Runtime/Internal/Platform/ITapCorePlatform.cs +2 -2
- package/Runtime/Public/TapTapEvent.cs +1 -1
- package/Runtime/Public/TapTapSDK.cs +10 -7
- package/Runtime/Public/{TapTapSDKCoreOptions.cs → TapTapSdkOptions.cs} +2 -2
- package/Standalone/Runtime/Internal/EventSender.cs +1 -1
- package/Standalone/Runtime/Internal/Http/NetUtils.cs +2 -2
- package/Standalone/Runtime/Internal/Openlog/Bean/TapOpenlogLogGroup.cs +39 -0
- package/Standalone/Runtime/Internal/Openlog/Bean/TapOpenlogLogGroup.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Openlog/Bean/TapOpenlogStoreBean.cs +33 -0
- package/Standalone/Runtime/Internal/Openlog/Bean/TapOpenlogStoreBean.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Openlog/Bean.meta +8 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogHttpClient.cs +164 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogHttpClient.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogParamConstants.cs +104 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogParamConstants.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueBase.cs +198 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueBase.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueBusiness.cs +17 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueBusiness.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueTechnology.cs +15 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueTechnology.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogStandalone.cs +190 -0
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogStandalone.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Openlog.meta +8 -0
- package/Standalone/Runtime/Internal/Tracker.cs +2 -2
- package/Standalone/Runtime/Internal/Utils/TapProtoBufffer.cs +28 -0
- package/Standalone/Runtime/Internal/Utils/TapProtoBufffer.cs.meta +11 -0
- package/Standalone/Runtime/Internal/Utils.meta +8 -0
- package/Standalone/Runtime/Public/TapCoreStandalone.cs +6 -3
- package/package.json +1 -1
- /package/Runtime/Public/{TapTapSDKCoreOptions.cs.meta → TapTapSdkOptions.cs.meta} +0 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<repositories>
|
|
6
6
|
<repository>https://repo.maven.apache.org/maven2</repository>
|
|
7
7
|
</repositories>
|
|
8
|
-
<androidPackage spec="com.taptap.sdk:tap-core-unity:4.3.
|
|
8
|
+
<androidPackage spec="com.taptap.sdk:tap-core-unity:4.3.10"/>
|
|
9
9
|
</androidPackages>
|
|
10
10
|
|
|
11
11
|
<!-- iOS Cocoapod dependencies can be specified by each iosPod element. -->
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</sources>
|
|
16
16
|
|
|
17
17
|
<iosPod name="Protobuf" version="~> 3.0" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
18
|
-
<iosPod name="TapTapCoreSDK" version="~> 4.3.
|
|
18
|
+
<iosPod name="TapTapCoreSDK" version="~> 4.3.10" bitcodeEnabled="false" addToAllTargets="false"/>
|
|
19
19
|
|
|
20
20
|
</iosPods>
|
|
21
21
|
|
|
@@ -93,7 +93,7 @@ namespace TapSDK.Core.Mobile {
|
|
|
93
93
|
private static extern void _TapTapSDKCoreSwitchToRND();
|
|
94
94
|
|
|
95
95
|
// 提供给 Unity 调用的 C# 方法
|
|
96
|
-
public static void Init(
|
|
96
|
+
public static void Init(TapTapSdkOptions coreOption, TapTapSdkBaseOptions[] otherOptions)
|
|
97
97
|
{
|
|
98
98
|
// 将其他选项转换为JSON字符串
|
|
99
99
|
string otherOptionsJson = ConvertOtherOptionsToJson(otherOptions);
|
|
@@ -105,7 +105,7 @@ namespace TapSDK.Core.Mobile {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
// 提供给 Unity 调用的 C# 方法
|
|
108
|
-
public static void Init(
|
|
108
|
+
public static void Init(TapTapSdkOptions coreOption)
|
|
109
109
|
{
|
|
110
110
|
// 调用C方法
|
|
111
111
|
_TapTapSDKInit(
|
|
@@ -221,7 +221,7 @@ namespace TapSDK.Core.Mobile {
|
|
|
221
221
|
return null;
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
private static string ConvertOtherOptionsToJson(
|
|
224
|
+
private static string ConvertOtherOptionsToJson(TapTapSdkBaseOptions[] otherOptions)
|
|
225
225
|
{
|
|
226
226
|
if (otherOptions == null || otherOptions.Length == 0)
|
|
227
227
|
{
|
|
@@ -21,10 +21,10 @@ namespace TapSDK.Core.Mobile
|
|
|
21
21
|
EngineBridgeInitializer.Initialize();
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
public void Init(
|
|
24
|
+
public void Init(TapTapSdkOptions coreOption, TapTapSdkBaseOptions[] otherOptions)
|
|
25
25
|
{
|
|
26
26
|
Debug.Log("TapCoreMobile SDK inited");
|
|
27
|
-
SetPlatformAndVersion(TapTapSDK.SDKPlatform, TapTapSDK.
|
|
27
|
+
SetPlatformAndVersion(TapTapSDK.SDKPlatform, TapTapSDK.Version);
|
|
28
28
|
string coreOptionsJson = JsonUtility.ToJson(coreOption);
|
|
29
29
|
string[] otherOptionsJson = otherOptions.Select(option => JsonConvert.SerializeObject(option)).ToArray();
|
|
30
30
|
Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
|
|
@@ -40,7 +40,7 @@ namespace TapSDK.Core.Mobile
|
|
|
40
40
|
Bridge.CallHandler(EngineBridgeInitializer.GetBridgeServer()
|
|
41
41
|
.Method("setPlatformAndVersion")
|
|
42
42
|
.Args("platform", TapTapSDK.SDKPlatform)
|
|
43
|
-
.Args("version", TapTapSDK.
|
|
43
|
+
.Args("version", TapTapSDK.Version)
|
|
44
44
|
.CommandBuilder());
|
|
45
45
|
SetSDKArtifact("Unity");
|
|
46
46
|
}
|
|
@@ -54,9 +54,9 @@ namespace TapSDK.Core.Mobile
|
|
|
54
54
|
.CommandBuilder());
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
public void Init(
|
|
57
|
+
public void Init(TapTapSdkOptions coreOption)
|
|
58
58
|
{
|
|
59
|
-
Init(coreOption, new
|
|
59
|
+
Init(coreOption, new TapTapSdkBaseOptions[0]);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
public void UpdateLanguage(TapTapLanguageType language)
|
|
@@ -10,9 +10,9 @@ namespace TapSDK.Core.Internal.Init {
|
|
|
10
10
|
/// 初始化
|
|
11
11
|
/// </summary>
|
|
12
12
|
/// <param name="config"></param>
|
|
13
|
-
void Init(
|
|
13
|
+
void Init(TapTapSdkOptions coreOption, TapTapSdkBaseOptions[] otherOptions);
|
|
14
14
|
|
|
15
|
-
void Init(
|
|
15
|
+
void Init(TapTapSdkOptions coreOption);
|
|
16
16
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
using UnityEngine;
|
|
2
|
+
|
|
3
|
+
namespace TapSDK.Core.Internal.Log
|
|
4
|
+
{
|
|
5
|
+
public class TapLog
|
|
6
|
+
{
|
|
7
|
+
private const string TAG = "TapSDKUnity";
|
|
8
|
+
// 颜色常量
|
|
9
|
+
private const string InfoColor = "#FFFFFF"; // 白色
|
|
10
|
+
private const string WarningColor = "#FFFF00"; // 黄色
|
|
11
|
+
private const string ErrorColor = "#FF0000"; // 红色
|
|
12
|
+
private const string MainThreadColor = "#00FF00"; // 绿色
|
|
13
|
+
private const string IOThreadColor = "#FF00FF"; // 紫色
|
|
14
|
+
private const string TagColor = "#00FFFF"; // 青色
|
|
15
|
+
|
|
16
|
+
// 开关变量,控制是否启用日志输出
|
|
17
|
+
public static bool Enabled = false;
|
|
18
|
+
|
|
19
|
+
private string module;
|
|
20
|
+
private string tag;
|
|
21
|
+
|
|
22
|
+
public TapLog(string module, string tag = TAG)
|
|
23
|
+
{
|
|
24
|
+
this.tag = tag;
|
|
25
|
+
this.module = module;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public void Log(string message, string detail = null)
|
|
29
|
+
{
|
|
30
|
+
TapLog.Log(message, detail, tag, module);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 输出带有自定义颜色和标签的警告
|
|
34
|
+
public void Warning(string message, string detail = null)
|
|
35
|
+
{
|
|
36
|
+
TapLog.Warning(message, detail, tag, module);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 输出带有自定义颜色和标签的错误
|
|
40
|
+
public void Error(string message, string detail = null)
|
|
41
|
+
{
|
|
42
|
+
TapLog.Error(message, detail, tag, module);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 输出带有自定义颜色和标签的普通日志
|
|
46
|
+
public static void Log(string message, string detail = null, string tag = TAG, string module = null)
|
|
47
|
+
{
|
|
48
|
+
if (Enabled)
|
|
49
|
+
{
|
|
50
|
+
Debug.Log(GetFormattedMessage(message: message, detail: detail, colorHex: InfoColor, tag: tag, module: module));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 输出带有自定义颜色和标签的警告
|
|
55
|
+
public static void Warning(string message, string detail = null, string tag = TAG, string module = null)
|
|
56
|
+
{
|
|
57
|
+
if (Enabled)
|
|
58
|
+
{
|
|
59
|
+
Debug.LogWarning(GetFormattedMessage(message: message, detail: detail, colorHex: WarningColor, tag: tag, module: module));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 输出带有自定义颜色和标签的错误
|
|
64
|
+
public static void Error(string message, string detail = null, string tag = TAG, string module = null)
|
|
65
|
+
{
|
|
66
|
+
if (Enabled)
|
|
67
|
+
{
|
|
68
|
+
Debug.LogError(GetFormattedMessage(message: message, detail: detail, colorHex: ErrorColor, tag: tag, module: module));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 格式化带有颜色和标签的消息
|
|
73
|
+
private static string GetFormattedMessage(string message, string detail, string colorHex, string tag, string module)
|
|
74
|
+
{
|
|
75
|
+
string threadInfo = GetThreadInfo();
|
|
76
|
+
string tagColor = TagColor;
|
|
77
|
+
if (module != null && module != "")
|
|
78
|
+
{
|
|
79
|
+
tag = $"{tag}.{module}";
|
|
80
|
+
}
|
|
81
|
+
if (IsMobilePlatform())
|
|
82
|
+
{
|
|
83
|
+
return $"[{tag}] {threadInfo} {message}\n{detail}";
|
|
84
|
+
}
|
|
85
|
+
else
|
|
86
|
+
{
|
|
87
|
+
return $"<color={tagColor}>[{tag}]</color> {threadInfo} <color={colorHex}>{message}</color>\n{detail}\n";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 获取当前线程信息
|
|
93
|
+
private static string GetThreadInfo()
|
|
94
|
+
{
|
|
95
|
+
bool isMainThread = System.Threading.Thread.CurrentThread.IsAlive && System.Threading.Thread.CurrentThread.ManagedThreadId == 1;
|
|
96
|
+
string threadInfo = isMainThread ? "Main Thread" : $"IO Thread {System.Threading.Thread.CurrentThread.ManagedThreadId}";
|
|
97
|
+
|
|
98
|
+
if (IsMobilePlatform())
|
|
99
|
+
{
|
|
100
|
+
// 移动平台的线程信息不使用颜色
|
|
101
|
+
return $"({threadInfo})";
|
|
102
|
+
}
|
|
103
|
+
else
|
|
104
|
+
{
|
|
105
|
+
// 其他平台的线程信息使用颜色
|
|
106
|
+
string color = isMainThread ? MainThreadColor : IOThreadColor;
|
|
107
|
+
return $"<color={color}>({threadInfo})</color>";
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 检查是否是移动平台
|
|
112
|
+
private static bool IsMobilePlatform()
|
|
113
|
+
{
|
|
114
|
+
return Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -3,9 +3,9 @@ using System.Threading.Tasks;
|
|
|
3
3
|
|
|
4
4
|
namespace TapSDK.Core.Internal {
|
|
5
5
|
public interface ITapCorePlatform {
|
|
6
|
-
void Init(
|
|
6
|
+
void Init(TapTapSdkOptions config);
|
|
7
7
|
|
|
8
|
-
void Init(
|
|
8
|
+
void Init(TapTapSdkOptions coreOption, TapTapSdkBaseOptions[] otherOptions);
|
|
9
9
|
|
|
10
10
|
void UpdateLanguage(TapTapLanguageType language);
|
|
11
11
|
}
|
|
@@ -81,7 +81,7 @@ namespace TapSDK.Core {
|
|
|
81
81
|
public static void ClearAllCommonProperties(){
|
|
82
82
|
platformWrapper?.ClearAllCommonProperties();
|
|
83
83
|
}
|
|
84
|
-
public static void
|
|
84
|
+
public static void LogPurchasedEvent(string orderID, string productName, long amount, string currencyType, string paymentMethod, string properties){
|
|
85
85
|
platformWrapper?.LogChargeEvent(orderID, productName, amount, currencyType, paymentMethod, properties);
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -7,14 +7,15 @@ using System.Collections.Generic;
|
|
|
7
7
|
using UnityEngine;
|
|
8
8
|
using System.Reflection;
|
|
9
9
|
using TapSDK.Core.Internal.Init;
|
|
10
|
+
using TapSDK.Core.Internal.Log;
|
|
10
11
|
|
|
11
12
|
namespace TapSDK.Core {
|
|
12
13
|
public class TapTapSDK {
|
|
13
|
-
public static readonly string
|
|
14
|
-
|
|
14
|
+
public static readonly string Version = "4.3.10-alpha.4";
|
|
15
|
+
|
|
15
16
|
public static string SDKPlatform = "TapSDK-Unity";
|
|
16
17
|
|
|
17
|
-
public static
|
|
18
|
+
public static TapTapSdkOptions taptapSdkOptions;
|
|
18
19
|
private static ITapCorePlatform platformWrapper;
|
|
19
20
|
|
|
20
21
|
private static bool disableDurationStatistics;
|
|
@@ -31,12 +32,13 @@ namespace TapSDK.Core {
|
|
|
31
32
|
"TapSDK.Core") as ITapCorePlatform;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
public static void Init(
|
|
35
|
+
public static void Init(TapTapSdkOptions coreOption) {
|
|
35
36
|
if (coreOption == null)
|
|
36
37
|
throw new ArgumentException("[TapSDK] options is null!");
|
|
37
38
|
if (string.IsNullOrEmpty(coreOption.clientId))
|
|
38
39
|
throw new ArgumentException("[TapSDK] clientID is null or empty!");
|
|
39
|
-
TapTapSDK.
|
|
40
|
+
TapTapSDK.taptapSdkOptions = coreOption;
|
|
41
|
+
TapLog.Enabled = coreOption.enableLog;
|
|
40
42
|
platformWrapper?.Init(coreOption);
|
|
41
43
|
// 初始化各个模块
|
|
42
44
|
|
|
@@ -54,13 +56,14 @@ namespace TapSDK.Core {
|
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
public static void Init(
|
|
59
|
+
public static void Init(TapTapSdkOptions coreOption, TapTapSdkBaseOptions[] otherOptions){
|
|
58
60
|
if (coreOption == null)
|
|
59
61
|
throw new ArgumentException("[TapSDK] options is null!");
|
|
60
62
|
if (string.IsNullOrEmpty(coreOption.clientId))
|
|
61
63
|
throw new ArgumentException("[TapSDK] clientID is null or empty!");
|
|
62
64
|
|
|
63
|
-
TapTapSDK.
|
|
65
|
+
TapTapSDK.taptapSdkOptions = coreOption;
|
|
66
|
+
TapLog.Enabled = coreOption.enableLog;
|
|
64
67
|
platformWrapper?.Init(coreOption,otherOptions);
|
|
65
68
|
|
|
66
69
|
Type[] initTaskTypes = GetInitTypeList();
|
|
@@ -3,7 +3,7 @@ using Newtonsoft.Json;
|
|
|
3
3
|
|
|
4
4
|
namespace TapSDK.Core
|
|
5
5
|
{
|
|
6
|
-
public interface
|
|
6
|
+
public interface TapTapSdkBaseOptions
|
|
7
7
|
{
|
|
8
8
|
string moduleName { get; }
|
|
9
9
|
|
|
@@ -36,7 +36,7 @@ namespace TapSDK.Core
|
|
|
36
36
|
vi// 越南语
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
public class
|
|
39
|
+
public class TapTapSdkOptions : TapTapSdkBaseOptions
|
|
40
40
|
{
|
|
41
41
|
/// <summary>
|
|
42
42
|
/// 客户端 ID,开发者后台获取
|
|
@@ -35,7 +35,7 @@ namespace TapSDK.Core.Standalone.Internal {
|
|
|
35
35
|
// 初始化 HttpClient
|
|
36
36
|
var header = new Dictionary<string, string>
|
|
37
37
|
{
|
|
38
|
-
{ "User-Agent", $"{TapTapSDK.SDKPlatform}/{TapTapSDK.
|
|
38
|
+
{ "User-Agent", $"{TapTapSDK.SDKPlatform}/{TapTapSDK.Version}" }
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
var coreOptions = TapCoreStandalone.coreOptions;
|
|
@@ -25,7 +25,7 @@ namespace TapSDK.Core.Standalone.Internal
|
|
|
25
25
|
public static Dictionary<string, string> commonHeaders {
|
|
26
26
|
get {
|
|
27
27
|
var headers = new Dictionary<string, string> {
|
|
28
|
-
{ "User-Agent", $"{TapTapSDK.SDKPlatform}/{TapTapSDK.
|
|
28
|
+
{ "User-Agent", $"{TapTapSDK.SDKPlatform}/{TapTapSDK.Version}" },
|
|
29
29
|
{ "X-Tap-Ts", TimeUtil.GetCurrentTime().ToString() },
|
|
30
30
|
{ "X-Tap-Nonce", NetUtils.GenerateNonce() },
|
|
31
31
|
{ "X-Tap-PN", "TapSDK" },
|
|
@@ -33,7 +33,7 @@ namespace TapSDK.Core.Standalone.Internal
|
|
|
33
33
|
{ "X-Tap-Device-Id", Identity.DeviceId },
|
|
34
34
|
{ "X-Tap-Platform", "PC" },
|
|
35
35
|
{ "X-Tap-SDK-Module", "TapSDKCore" },
|
|
36
|
-
{ "X-Tap-SDK-Module-Version", TapTapSDK.
|
|
36
|
+
{ "X-Tap-SDK-Module-Version", TapTapSDK.Version },
|
|
37
37
|
{ "X-Tap-SDK-Artifact", "Unity" }
|
|
38
38
|
};
|
|
39
39
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN
|
|
2
|
+
using Newtonsoft.Json;
|
|
3
|
+
using ProtoBuf;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
|
|
6
|
+
namespace TapSDK.Core.Standalone.Internal
|
|
7
|
+
{
|
|
8
|
+
[ProtoContract]
|
|
9
|
+
public class LogContent
|
|
10
|
+
{
|
|
11
|
+
[JsonProperty("Key")]
|
|
12
|
+
[ProtoMember(1)]
|
|
13
|
+
public string Key { get; set; }
|
|
14
|
+
|
|
15
|
+
[JsonProperty("Value")]
|
|
16
|
+
[ProtoMember(2)]
|
|
17
|
+
public string Value { get; set; }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
[ProtoContract]
|
|
21
|
+
public class Log
|
|
22
|
+
{
|
|
23
|
+
[JsonProperty("Value")]
|
|
24
|
+
[ProtoMember(1)]
|
|
25
|
+
public uint Time { get; set; }
|
|
26
|
+
[JsonProperty("Contents")]
|
|
27
|
+
[ProtoMember(2)]
|
|
28
|
+
public List<LogContent> Contents { get; set; }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
[ProtoContract]
|
|
32
|
+
public class LogGroup
|
|
33
|
+
{
|
|
34
|
+
[JsonProperty("Logs")]
|
|
35
|
+
[ProtoMember(1)]
|
|
36
|
+
public List<Log> Logs { get; set; }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
#endif
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
using System.Collections.Generic;
|
|
2
|
+
using Newtonsoft.Json;
|
|
3
|
+
|
|
4
|
+
namespace TapSDK.Core.Standalone.Internal.Openlog
|
|
5
|
+
{
|
|
6
|
+
public class TapOpenlogStoreBean
|
|
7
|
+
{
|
|
8
|
+
[JsonProperty("action")]
|
|
9
|
+
public string action;
|
|
10
|
+
|
|
11
|
+
[JsonProperty("timestamp")]
|
|
12
|
+
public long timestamp;
|
|
13
|
+
|
|
14
|
+
[JsonProperty("t_log_id")]
|
|
15
|
+
public string tLogId;
|
|
16
|
+
|
|
17
|
+
[JsonProperty("props")]
|
|
18
|
+
public readonly Dictionary<string, string> props;
|
|
19
|
+
|
|
20
|
+
public TapOpenlogStoreBean(string action, long timestamp, string tLogId, Dictionary<string, string> props)
|
|
21
|
+
{
|
|
22
|
+
this.action = action;
|
|
23
|
+
this.timestamp = timestamp;
|
|
24
|
+
this.tLogId = tLogId;
|
|
25
|
+
this.props = props;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public override string ToString()
|
|
29
|
+
{
|
|
30
|
+
return $"TapOpenlogStoreBean(action: {action} , tLogId: {tLogId} , timestamp: {timestamp})";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN
|
|
2
|
+
using System;
|
|
3
|
+
using System.Threading.Tasks;
|
|
4
|
+
using System.Net;
|
|
5
|
+
using System.Net.Http;
|
|
6
|
+
using System.Net.Http.Headers;
|
|
7
|
+
using System.Linq;
|
|
8
|
+
using System.Security.Cryptography;
|
|
9
|
+
using System.Text;
|
|
10
|
+
using TapSDK.Core.Internal.Log;
|
|
11
|
+
using K4os.Compression.LZ4;
|
|
12
|
+
|
|
13
|
+
namespace TapSDK.Core.Standalone.Internal
|
|
14
|
+
{
|
|
15
|
+
public class TapOpenlogHttpClient
|
|
16
|
+
{
|
|
17
|
+
|
|
18
|
+
private const string HOST_CN = "openlog.xdrnd.cn";
|
|
19
|
+
private const string HOST_IO = "openlog.xdrnd.cn";
|
|
20
|
+
|
|
21
|
+
private string GetHost()
|
|
22
|
+
{
|
|
23
|
+
if (TapCoreStandalone.coreOptions.region == TapTapRegionType.CN)
|
|
24
|
+
{
|
|
25
|
+
return HOST_CN;
|
|
26
|
+
}
|
|
27
|
+
else if (TapCoreStandalone.coreOptions.region == TapTapRegionType.Overseas)
|
|
28
|
+
{
|
|
29
|
+
return HOST_IO;
|
|
30
|
+
}
|
|
31
|
+
else
|
|
32
|
+
{
|
|
33
|
+
return HOST_CN;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private static TapLog log = new TapLog(module: "Openlog.HttpClient");
|
|
38
|
+
|
|
39
|
+
private static System.Net.Http.HttpClient client;
|
|
40
|
+
|
|
41
|
+
public TapOpenlogHttpClient()
|
|
42
|
+
{
|
|
43
|
+
// var ip = "http://172.26.200.194:8888";
|
|
44
|
+
// ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) =>
|
|
45
|
+
// {
|
|
46
|
+
// return true;
|
|
47
|
+
// };
|
|
48
|
+
// HttpClientHandler clientHandler = new HttpClientHandler
|
|
49
|
+
// {
|
|
50
|
+
// Proxy = new WebProxy(ip)
|
|
51
|
+
// };
|
|
52
|
+
// client = new System.Net.Http.HttpClient(clientHandler);
|
|
53
|
+
client = new System.Net.Http.HttpClient();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public async Task<bool> Post(string path, byte[] content)
|
|
57
|
+
{
|
|
58
|
+
string url = BuildUrl(path);
|
|
59
|
+
var request = new HttpRequestMessage(HttpMethod.Post, url);
|
|
60
|
+
|
|
61
|
+
request.Headers.Add("User-Agent", "TapSDK-Unity/" + TapTapSDK.Version);
|
|
62
|
+
request.Headers.Add("Accept", "*/*");
|
|
63
|
+
request.Headers.Add("x-log-apiversion", "0.6.0");
|
|
64
|
+
request.Headers.Add("x-log-compresstype", "lz4");
|
|
65
|
+
request.Headers.Add("x-log-signaturemethod", "hmac-sha1");
|
|
66
|
+
request.Headers.Add("x-log-timestamp", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString());
|
|
67
|
+
request.Headers.Add("x-log-bodyrawsize", content.Length.ToString());
|
|
68
|
+
|
|
69
|
+
byte[] compressContent = LZ4Compress(content);
|
|
70
|
+
// byte[] compressContent = content;
|
|
71
|
+
|
|
72
|
+
var contentMD5 = EncryptString(compressContent);
|
|
73
|
+
request.Headers.Add("x-content-md5", contentMD5);
|
|
74
|
+
|
|
75
|
+
string methodPart = request.Method.Method;
|
|
76
|
+
string urlPath = request.RequestUri.LocalPath;
|
|
77
|
+
string headersPart = GetHeadersPart(request.Headers);
|
|
78
|
+
string signParts = methodPart + "\n" + contentMD5 + "\n" + "application/x-protobuf" + "\n" + headersPart + "\n" + urlPath;
|
|
79
|
+
string sign;
|
|
80
|
+
using (var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(TapCoreStandalone.coreOptions.clientToken)))
|
|
81
|
+
{
|
|
82
|
+
byte[] hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(signParts));
|
|
83
|
+
sign = Convert.ToBase64String(hash);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
request.Headers.Add("Authorization", "LOG " + TapCoreStandalone.coreOptions.clientId + ":" + sign);
|
|
87
|
+
|
|
88
|
+
ByteArrayContent requestContent = new ByteArrayContent(compressContent);
|
|
89
|
+
requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-protobuf");
|
|
90
|
+
request.Content = requestContent;
|
|
91
|
+
|
|
92
|
+
return await SendRequest(request);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private static string EncryptString(byte[] str)
|
|
96
|
+
{
|
|
97
|
+
var md5 = MD5.Create();
|
|
98
|
+
byte[] byteOld = str;
|
|
99
|
+
byte[] byteNew = md5.ComputeHash(byteOld);
|
|
100
|
+
var sb = new StringBuilder();
|
|
101
|
+
foreach (byte b in byteNew)
|
|
102
|
+
{
|
|
103
|
+
sb.Append(b.ToString("X2"));
|
|
104
|
+
}
|
|
105
|
+
return sb.ToString();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private static byte[] LZ4Compress(byte[] data)
|
|
109
|
+
{
|
|
110
|
+
int maxCompressedLength = LZ4Codec.MaximumOutputSize(data.Length);
|
|
111
|
+
byte[] compressedData = new byte[maxCompressedLength];
|
|
112
|
+
int compressedLength = LZ4Codec.Encode(data, 0, data.Length, compressedData, 0, compressedData.Length);
|
|
113
|
+
|
|
114
|
+
byte[] result = new byte[compressedLength];
|
|
115
|
+
Array.Copy(compressedData, result, compressedLength);
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private static string GetHeadersPart(HttpRequestHeaders headers)
|
|
120
|
+
{
|
|
121
|
+
var headerKeys = headers
|
|
122
|
+
.Where(h => h.Key.StartsWith("x-log-", StringComparison.OrdinalIgnoreCase))
|
|
123
|
+
.OrderBy(h => h.Key.ToLowerInvariant())
|
|
124
|
+
.Select(h => $"{h.Key.ToLowerInvariant()}:{string.Join(",", h.Value)}")
|
|
125
|
+
.ToList();
|
|
126
|
+
|
|
127
|
+
return string.Join("\n", headerKeys);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private async Task<bool> SendRequest(HttpRequestMessage request)
|
|
131
|
+
{
|
|
132
|
+
HttpResponseMessage response;
|
|
133
|
+
try
|
|
134
|
+
{
|
|
135
|
+
response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
|
136
|
+
request.Dispose();
|
|
137
|
+
}
|
|
138
|
+
catch (HttpRequestException e)
|
|
139
|
+
{
|
|
140
|
+
log.Warning($"Request error", e.ToString());
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (response.IsSuccessStatusCode || (response.StatusCode >= HttpStatusCode.BadRequest && response.StatusCode < HttpStatusCode.InternalServerError))
|
|
145
|
+
{
|
|
146
|
+
response.Dispose();
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
else
|
|
150
|
+
{
|
|
151
|
+
log.Warning($"SendOpenlog failed", response.StatusCode.ToString());
|
|
152
|
+
response.Dispose();
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private string BuildUrl(string path)
|
|
158
|
+
{
|
|
159
|
+
string url = $"https://{GetHost()}/{path}?client_id={TapCoreStandalone.coreOptions.clientId}";
|
|
160
|
+
return url;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
#endif
|