com.taptap.sdk.license 4.9.4 → 4.9.5
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.
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Runtime.InteropServices;
|
|
3
|
+
using TapSDK.Core.Internal.Log;
|
|
4
|
+
using TapSDK.Core.Standalone;
|
|
5
|
+
using TapSDK.Core.Standalone.Internal;
|
|
6
|
+
|
|
7
|
+
#if PLATFORM_STANDALONE_WIN
|
|
8
|
+
namespace TapSDK.License.Standalone
|
|
9
|
+
{
|
|
10
|
+
internal class TapLicenseClientBridge
|
|
11
|
+
{
|
|
12
|
+
private static Action<string, bool> currentDlcDelegate;
|
|
13
|
+
private static Action<bool> currentLicenseDelegate;
|
|
14
|
+
|
|
15
|
+
/// 查询是否购买 DLC , 未调用 isLaunchFromPC 会抛异常
|
|
16
|
+
public static bool QueryDLC(string skuId)
|
|
17
|
+
{
|
|
18
|
+
if (!TapClientStandalone.isPassedInLaunchedFromTapTapPCCheck())
|
|
19
|
+
{
|
|
20
|
+
throw new Exception(
|
|
21
|
+
"queryDLC must be invoked after IsLaunchedFromTapTapPC success"
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
bool success = LicenseNativeBridge.TapDLC_IsOwned(skuId);
|
|
25
|
+
return success;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/// 跳转到 TapTap 客户端 DLC 购买页面 , 未调用 isLaunchFromPC 会抛异常
|
|
29
|
+
public static bool ShowStore(string skuId)
|
|
30
|
+
{
|
|
31
|
+
if (!TapClientStandalone.isPassedInLaunchedFromTapTapPCCheck())
|
|
32
|
+
{
|
|
33
|
+
throw new Exception(
|
|
34
|
+
"purchaseDLC must be invoked after IsLaunchedFromTapTapPC success"
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
TapLog.Log("purchaseDLC start = " + skuId);
|
|
38
|
+
return LicenseNativeBridge.TapDLC_ShowStore(skuId);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// 注册 DLC 购买状态变更回调,包括购买成功和退款
|
|
42
|
+
public static void RegisterDLCOwnedCallback(Action<string, bool> dlcDelegate)
|
|
43
|
+
{
|
|
44
|
+
currentDlcDelegate = dlcDelegate;
|
|
45
|
+
LicenseNativeBridge.RegisterCallback(
|
|
46
|
+
LicenseNativeBridge.TapEventID.DLCPlayableStatusChanged,
|
|
47
|
+
DLCCallbackDelegate
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// DLC 回调
|
|
52
|
+
[AOT.MonoPInvokeCallback(typeof(TapClientBridge.CallbackDelegate))]
|
|
53
|
+
static void DLCCallbackDelegate(int id, IntPtr userData)
|
|
54
|
+
{
|
|
55
|
+
TapLog.Log("queryDlC recevie callback " + id);
|
|
56
|
+
if (currentDlcDelegate != null)
|
|
57
|
+
{
|
|
58
|
+
LicenseNativeBridge.DLCPlayableStatusChangedResponse response =
|
|
59
|
+
Marshal.PtrToStructure<LicenseNativeBridge.DLCPlayableStatusChangedResponse>(
|
|
60
|
+
userData
|
|
61
|
+
);
|
|
62
|
+
TapLog.Log(
|
|
63
|
+
"queryDlC callback = " + response.dlc_id + " isOwn = " + response.is_playable
|
|
64
|
+
);
|
|
65
|
+
currentDlcDelegate(response.dlc_id, response.is_playable != 0);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/// 注册 License 购买状态变更回调,包括购买成功和退款
|
|
70
|
+
public static void RegisterLicenseCallback(Action<bool> licensecDelegate)
|
|
71
|
+
{
|
|
72
|
+
currentLicenseDelegate = licensecDelegate;
|
|
73
|
+
LicenseNativeBridge.RegisterCallback(
|
|
74
|
+
LicenseNativeBridge.TapEventID.GamePlayableStatusChanged,
|
|
75
|
+
LicenseCallbackDelegate
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/// License 回调
|
|
80
|
+
[AOT.MonoPInvokeCallback(typeof(TapClientBridge.CallbackDelegate))]
|
|
81
|
+
static void LicenseCallbackDelegate(int id, IntPtr userData)
|
|
82
|
+
{
|
|
83
|
+
TapLog.Log("License recevie callback " + id);
|
|
84
|
+
if (currentLicenseDelegate != null)
|
|
85
|
+
{
|
|
86
|
+
LicenseNativeBridge.GamePlayableStatusChangedResponse response =
|
|
87
|
+
Marshal.PtrToStructure<LicenseNativeBridge.GamePlayableStatusChangedResponse>(
|
|
88
|
+
userData
|
|
89
|
+
);
|
|
90
|
+
TapLog.Log("License callback isOwn changed " + response.is_playable);
|
|
91
|
+
currentLicenseDelegate(response.is_playable != 0);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public static bool HasLicense()
|
|
96
|
+
{
|
|
97
|
+
if (!TapClientStandalone.isPassedInLaunchedFromTapTapPCCheck())
|
|
98
|
+
{
|
|
99
|
+
throw new Exception(
|
|
100
|
+
"checkLicense must be invoked after IsLaunchedFromTapTapPC success"
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
return LicenseNativeBridge.TapApps_IsOwned();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
internal class LicenseNativeBridge
|
|
108
|
+
{
|
|
109
|
+
internal enum TapEventID
|
|
110
|
+
{
|
|
111
|
+
// [4001, 6000), reserved for TapTap ownership events
|
|
112
|
+
GamePlayableStatusChanged = 4001,
|
|
113
|
+
DLCPlayableStatusChanged = 4002,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
public const string DLL_NAME = "taptap_api";
|
|
117
|
+
|
|
118
|
+
// 检查是否拥有当前游戏
|
|
119
|
+
[DllImport(DLL_NAME, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
|
|
120
|
+
internal static extern bool TapApps_IsOwned();
|
|
121
|
+
|
|
122
|
+
// 游戏本体可玩状态变更事件响应结构体
|
|
123
|
+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
|
124
|
+
public struct GamePlayableStatusChangedResponse
|
|
125
|
+
{
|
|
126
|
+
public byte is_playable; // 游戏本体是否可玩
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// 显示指定 DLC 的商店页面
|
|
130
|
+
[DllImport(DLL_NAME, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
|
|
131
|
+
internal static extern bool TapDLC_ShowStore([MarshalAs(UnmanagedType.LPStr)] string dlcId);
|
|
132
|
+
|
|
133
|
+
// 查询用户是否拥有指定的 DLC
|
|
134
|
+
[DllImport(DLL_NAME, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
|
|
135
|
+
internal static extern bool TapDLC_IsOwned([MarshalAs(UnmanagedType.LPStr)] string dlcId);
|
|
136
|
+
|
|
137
|
+
// DLC 授权完成响应结果
|
|
138
|
+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
|
139
|
+
public struct DLCPlayableStatusChangedResponse
|
|
140
|
+
{
|
|
141
|
+
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
|
142
|
+
public string dlc_id; // DLC ID
|
|
143
|
+
|
|
144
|
+
public byte is_playable; // 是否可玩,当用户购买 DLC (外置 DLC 为购买且下载完成后),此值返回 true。其他情况返回 false
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 预防 GC 回收的静态变量
|
|
148
|
+
private static TapClientBridge.CallbackDelegate _dlcCallbackInstance;
|
|
149
|
+
|
|
150
|
+
private static TapClientBridge.CallbackDelegate _licenseCallbackInstance;
|
|
151
|
+
|
|
152
|
+
internal static void RegisterCallback(
|
|
153
|
+
TapEventID eventID,
|
|
154
|
+
TapClientBridge.CallbackDelegate callback
|
|
155
|
+
)
|
|
156
|
+
{
|
|
157
|
+
IntPtr funcPtr = Marshal.GetFunctionPointerForDelegate(callback);
|
|
158
|
+
switch (eventID)
|
|
159
|
+
{
|
|
160
|
+
case TapEventID.DLCPlayableStatusChanged:
|
|
161
|
+
if (_dlcCallbackInstance != null)
|
|
162
|
+
{
|
|
163
|
+
UnRegisterCallback(eventID, _dlcCallbackInstance);
|
|
164
|
+
}
|
|
165
|
+
_dlcCallbackInstance = callback;
|
|
166
|
+
break;
|
|
167
|
+
case TapEventID.GamePlayableStatusChanged:
|
|
168
|
+
if (_licenseCallbackInstance != null)
|
|
169
|
+
{
|
|
170
|
+
UnRegisterCallback(eventID, _licenseCallbackInstance);
|
|
171
|
+
}
|
|
172
|
+
_licenseCallbackInstance = callback;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
TapClientBridge.TapSDK_RegisterCallback((int)eventID, funcPtr);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 移除回调
|
|
180
|
+
internal static void UnRegisterCallback(
|
|
181
|
+
TapEventID eventID,
|
|
182
|
+
TapClientBridge.CallbackDelegate callback
|
|
183
|
+
)
|
|
184
|
+
{
|
|
185
|
+
IntPtr funcPtr = Marshal.GetFunctionPointerForDelegate(callback);
|
|
186
|
+
TapClientBridge.TapSDK_UnregisterCallback((int)eventID, funcPtr);
|
|
187
|
+
switch (eventID)
|
|
188
|
+
{
|
|
189
|
+
case TapEventID.DLCPlayableStatusChanged:
|
|
190
|
+
_dlcCallbackInstance = null;
|
|
191
|
+
break;
|
|
192
|
+
case TapEventID.GamePlayableStatusChanged:
|
|
193
|
+
_licenseCallbackInstance = null;
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
#endif
|
|
@@ -1,19 +1,14 @@
|
|
|
1
|
-
using
|
|
2
|
-
using TapSDK.License.Internal;
|
|
3
|
-
using TapSDK.Core;
|
|
4
|
-
using TapSDK.Core.Standalone;
|
|
1
|
+
using System;
|
|
5
2
|
using System.Collections.Generic;
|
|
6
|
-
using
|
|
7
|
-
using
|
|
8
|
-
using
|
|
9
|
-
using TapSDK.Core.Internal.Log;
|
|
10
|
-
|
|
11
|
-
#if PLATFORM_STANDALONE_WIN
|
|
12
|
-
namespace TapSDK.License.Standalone {
|
|
3
|
+
using TapSDK.Core.Standalone;
|
|
4
|
+
using TapSDK.License;
|
|
5
|
+
using TapSDK.License.Internal;
|
|
13
6
|
|
|
7
|
+
#if PLATFORM_STANDALONE_WIN
|
|
8
|
+
namespace TapSDK.License.Standalone
|
|
9
|
+
{
|
|
14
10
|
public class TapLicenseStandalone : ITapLicenseBridge
|
|
15
11
|
{
|
|
16
|
-
|
|
17
12
|
private List<ITapDlcCallback> currentDLCCallbacks;
|
|
18
13
|
|
|
19
14
|
private List<ITapLicenseCallback> currentLicenseCallbacks;
|
|
@@ -29,6 +24,7 @@ namespace TapSDK.License.Standalone {
|
|
|
29
24
|
{
|
|
30
25
|
TaplicenseTracker.Instance.TrackInit();
|
|
31
26
|
}
|
|
27
|
+
|
|
32
28
|
public void CheckLicense()
|
|
33
29
|
{
|
|
34
30
|
if (!CheckInit())
|
|
@@ -37,17 +33,26 @@ namespace TapSDK.License.Standalone {
|
|
|
37
33
|
}
|
|
38
34
|
currentSessionId = Guid.NewGuid().ToString();
|
|
39
35
|
string method = "checkLicense";
|
|
40
|
-
Dictionary<string, string> props = new Dictionary<string, string>
|
|
36
|
+
Dictionary<string, string> props = new Dictionary<string, string>
|
|
37
|
+
{
|
|
38
|
+
{ "license_type", "tap_license" },
|
|
39
|
+
};
|
|
41
40
|
TaplicenseTracker.Instance.TrackStart(method, currentSessionId, props);
|
|
42
41
|
bool isOwned = false;
|
|
43
42
|
try
|
|
44
43
|
{
|
|
45
|
-
isOwned =
|
|
44
|
+
isOwned = TapLicenseClientBridge.HasLicense();
|
|
46
45
|
}
|
|
47
46
|
catch (Exception e)
|
|
48
47
|
{
|
|
49
|
-
TaplicenseTracker.Instance.TrackFailure(
|
|
50
|
-
|
|
48
|
+
TaplicenseTracker.Instance.TrackFailure(
|
|
49
|
+
method,
|
|
50
|
+
currentSessionId,
|
|
51
|
+
props,
|
|
52
|
+
-1,
|
|
53
|
+
e.Message ?? ""
|
|
54
|
+
);
|
|
55
|
+
throw;
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
if (isOwned)
|
|
@@ -56,7 +61,13 @@ namespace TapSDK.License.Standalone {
|
|
|
56
61
|
}
|
|
57
62
|
else
|
|
58
63
|
{
|
|
59
|
-
TaplicenseTracker.Instance.TrackFailure(
|
|
64
|
+
TaplicenseTracker.Instance.TrackFailure(
|
|
65
|
+
method,
|
|
66
|
+
currentSessionId,
|
|
67
|
+
props,
|
|
68
|
+
0,
|
|
69
|
+
"NOT_PURCHASED"
|
|
70
|
+
);
|
|
60
71
|
}
|
|
61
72
|
|
|
62
73
|
if (currentLicenseCallbacks != null)
|
|
@@ -72,7 +83,6 @@ namespace TapSDK.License.Standalone {
|
|
|
72
83
|
callback?.OnLicenseFailed();
|
|
73
84
|
}
|
|
74
85
|
}
|
|
75
|
-
|
|
76
86
|
}
|
|
77
87
|
}
|
|
78
88
|
|
|
@@ -81,7 +91,6 @@ namespace TapSDK.License.Standalone {
|
|
|
81
91
|
CheckLicense();
|
|
82
92
|
}
|
|
83
93
|
|
|
84
|
-
|
|
85
94
|
public void QueryDLC(string[] skus)
|
|
86
95
|
{
|
|
87
96
|
if (!CheckInit())
|
|
@@ -94,21 +103,30 @@ namespace TapSDK.License.Standalone {
|
|
|
94
103
|
}
|
|
95
104
|
currentSessionId = Guid.NewGuid().ToString();
|
|
96
105
|
string method = "queryDLC";
|
|
97
|
-
Dictionary<string, string> props = new Dictionary<string, string>
|
|
106
|
+
Dictionary<string, string> props = new Dictionary<string, string>
|
|
107
|
+
{
|
|
108
|
+
{ "sku_ids", string.Join(",", skus) },
|
|
109
|
+
};
|
|
98
110
|
TaplicenseTracker.Instance.TrackStart(method, currentSessionId, props);
|
|
99
111
|
Dictionary<string, object> dlcResult = new Dictionary<string, object>();
|
|
100
112
|
try
|
|
101
113
|
{
|
|
102
114
|
foreach (string skuId in skus)
|
|
103
115
|
{
|
|
104
|
-
bool isOwned =
|
|
116
|
+
bool isOwned = TapLicenseClientBridge.QueryDLC(skuId);
|
|
105
117
|
dlcResult.Add(skuId, isOwned ? 1 : 0);
|
|
106
118
|
}
|
|
107
119
|
}
|
|
108
120
|
catch (Exception e)
|
|
109
121
|
{
|
|
110
|
-
TaplicenseTracker.Instance.TrackFailure(
|
|
111
|
-
|
|
122
|
+
TaplicenseTracker.Instance.TrackFailure(
|
|
123
|
+
method,
|
|
124
|
+
currentSessionId,
|
|
125
|
+
props,
|
|
126
|
+
-1,
|
|
127
|
+
e.Message ?? ""
|
|
128
|
+
);
|
|
129
|
+
throw;
|
|
112
130
|
}
|
|
113
131
|
TaplicenseTracker.Instance.TrackSuccess(method, currentSessionId, props);
|
|
114
132
|
if (currentDLCCallbacks != null)
|
|
@@ -130,11 +148,10 @@ namespace TapSDK.License.Standalone {
|
|
|
130
148
|
if (!HasRegisterNativeDLCCallback)
|
|
131
149
|
{
|
|
132
150
|
HasRegisterNativeDLCCallback = true;
|
|
133
|
-
|
|
151
|
+
TapLicenseClientBridge.RegisterDLCOwnedCallback(DLCCallbackDelegate);
|
|
134
152
|
}
|
|
135
153
|
}
|
|
136
154
|
|
|
137
|
-
|
|
138
155
|
public void RegisterLicencesCallback(ITapLicenseCallback callback)
|
|
139
156
|
{
|
|
140
157
|
if (currentLicenseCallbacks == null)
|
|
@@ -145,7 +162,7 @@ namespace TapSDK.License.Standalone {
|
|
|
145
162
|
if (!HasRegisterNativeLicenseCallback)
|
|
146
163
|
{
|
|
147
164
|
HasRegisterNativeLicenseCallback = true;
|
|
148
|
-
|
|
165
|
+
TapLicenseClientBridge.RegisterLicenseCallback(LicenseCallbackDelegate);
|
|
149
166
|
}
|
|
150
167
|
}
|
|
151
168
|
|
|
@@ -157,16 +174,25 @@ namespace TapSDK.License.Standalone {
|
|
|
157
174
|
}
|
|
158
175
|
currentSessionId = Guid.NewGuid().ToString();
|
|
159
176
|
string method = "purchaseDLC";
|
|
160
|
-
Dictionary<string, string> props = new Dictionary<string, string>
|
|
177
|
+
Dictionary<string, string> props = new Dictionary<string, string>
|
|
178
|
+
{
|
|
179
|
+
{ "sku_id", skuId },
|
|
180
|
+
};
|
|
161
181
|
TaplicenseTracker.Instance.TrackStart(method, currentSessionId, props);
|
|
162
182
|
bool isSuccess = false;
|
|
163
183
|
try
|
|
164
184
|
{
|
|
165
|
-
isSuccess =
|
|
185
|
+
isSuccess = TapLicenseClientBridge.ShowStore(skuId);
|
|
166
186
|
}
|
|
167
187
|
catch (Exception e)
|
|
168
188
|
{
|
|
169
|
-
TaplicenseTracker.Instance.TrackFailure(
|
|
189
|
+
TaplicenseTracker.Instance.TrackFailure(
|
|
190
|
+
method,
|
|
191
|
+
currentSessionId,
|
|
192
|
+
props,
|
|
193
|
+
-1,
|
|
194
|
+
e.Message ?? ""
|
|
195
|
+
);
|
|
170
196
|
throw;
|
|
171
197
|
}
|
|
172
198
|
if (isSuccess)
|
|
@@ -175,7 +201,13 @@ namespace TapSDK.License.Standalone {
|
|
|
175
201
|
}
|
|
176
202
|
else
|
|
177
203
|
{
|
|
178
|
-
TaplicenseTracker.Instance.TrackFailure(
|
|
204
|
+
TaplicenseTracker.Instance.TrackFailure(
|
|
205
|
+
method,
|
|
206
|
+
currentSessionId,
|
|
207
|
+
props,
|
|
208
|
+
-1,
|
|
209
|
+
"ShowStoreFailed"
|
|
210
|
+
);
|
|
179
211
|
}
|
|
180
212
|
}
|
|
181
213
|
|
|
@@ -185,12 +217,16 @@ namespace TapSDK.License.Standalone {
|
|
|
185
217
|
{
|
|
186
218
|
foreach (ITapDlcCallback callback in currentDLCCallbacks)
|
|
187
219
|
{
|
|
188
|
-
callback?.OnOrderCallBack(
|
|
220
|
+
callback?.OnOrderCallBack(
|
|
221
|
+
skuId,
|
|
222
|
+
isOwned
|
|
223
|
+
? TapLicensePurchasedCode.DLC_PURCHASED
|
|
224
|
+
: TapLicensePurchasedCode.DLC_NOT_PURCHASED
|
|
225
|
+
);
|
|
189
226
|
}
|
|
190
227
|
}
|
|
191
228
|
}
|
|
192
229
|
|
|
193
|
-
|
|
194
230
|
private void LicenseCallbackDelegate(bool isOwned)
|
|
195
231
|
{
|
|
196
232
|
if (currentLicenseCallbacks != null)
|
|
@@ -206,7 +242,6 @@ namespace TapSDK.License.Standalone {
|
|
|
206
242
|
callback?.OnLicenseFailed();
|
|
207
243
|
}
|
|
208
244
|
}
|
|
209
|
-
|
|
210
245
|
}
|
|
211
246
|
}
|
|
212
247
|
|
|
@@ -218,7 +253,6 @@ namespace TapSDK.License.Standalone {
|
|
|
218
253
|
}
|
|
219
254
|
return true;
|
|
220
255
|
}
|
|
221
|
-
|
|
222
256
|
}
|
|
223
257
|
}
|
|
224
|
-
#endif
|
|
258
|
+
#endif
|
package/package.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"name": "com.taptap.sdk.license",
|
|
3
3
|
"displayName": "TapTapSDK License",
|
|
4
4
|
"description": "TapTapSDK License",
|
|
5
|
-
"version": "4.9.
|
|
6
|
-
"unity": "
|
|
5
|
+
"version": "4.9.5",
|
|
6
|
+
"unity": "2019.4",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"com.taptap.sdk.core": "4.9.
|
|
9
|
+
"com.taptap.sdk.core": "4.9.5"
|
|
10
10
|
}
|
|
11
11
|
}
|