com.taptap.sdk.login 4.3.12 → 4.4.0

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.
@@ -4,13 +4,13 @@
4
4
  <repositories>
5
5
  <repository>https://repo.maven.apache.org/maven2</repository>
6
6
  </repositories>
7
- <androidPackage spec="com.taptap.sdk:tap-login-unity:4.3.12"/>
7
+ <androidPackage spec="com.taptap.sdk:tap-login-unity:4.4.0"/>
8
8
  </androidPackages>
9
9
  <iosPods>
10
10
  <sources>
11
11
  <source>https://github.com/CocoaPods/Specs.git</source>
12
12
  </sources>
13
13
  <iosPod name="Kingfisher" version="~> 6.0" bitcodeEnabled="false" addToAllTargets="false"/>
14
- <iosPod name="TapTapLoginSDK" version="~> 4.3.10" bitcodeEnabled="false" addToAllTargets="false"/>
14
+ <iosPod name="TapTapLoginSDK" version="~> 4.4.0" bitcodeEnabled="false" addToAllTargets="false"/>
15
15
  </iosPods>
16
16
  </dependencies>
@@ -6,7 +6,7 @@ namespace TapSDK.Login.Mobile.Editor {
6
6
  public class TapLoginMobileProcessBuild : SDKLinkProcessBuild {
7
7
  public override int callbackOrder => 0;
8
8
 
9
- public override string LinkPath => "TapTap/Login/link.xml";
9
+ public override string LinkPath => "TapSDK/Login/link.xml";
10
10
 
11
11
  public override LinkedAssembly[] LinkedAssemblies => new LinkedAssembly[] {
12
12
  new LinkedAssembly { Fullname = "TapSDK.Login.Runtime" },
@@ -7,7 +7,7 @@ namespace TapSDK.Login
7
7
  public class TapTapLogin
8
8
  {
9
9
 
10
- public static readonly string Version = "4.3.12";
10
+ public static readonly string Version = "4.4.0";
11
11
 
12
12
  public const string TAP_LOGIN_SCOPE_BASIC_INFO = "basic_info";
13
13
  public const string TAP_LOGIN_SCOPE_PUBLIC_PROFILE = "public_profile";
@@ -5,14 +5,18 @@ using System.Security.Cryptography;
5
5
  using System.Text;
6
6
  using UnityEngine;
7
7
  using TapSDK.Login.Internal.Http;
8
+ using TapSDK.Core.Standalone.Internal.Service;
8
9
 
9
- namespace TapSDK.Login.Internal {
10
- public static class LoginService {
10
+ namespace TapSDK.Login.Internal
11
+ {
12
+ public static class LoginService
13
+ {
11
14
  private static readonly LoginHttpClient httpClient = new LoginHttpClient();
12
15
 
13
16
  public static LoginHttpClient HttpClient => httpClient;
14
17
 
15
- public static async Task<QRCodeData> GetQRCodeUrl(string clientId, string[] scopes) {
18
+ public static async Task<QRCodeData> GetQRCodeUrl(string clientId, string[] scopes)
19
+ {
16
20
  Dictionary<string, object> data = new Dictionary<string, object> {
17
21
  { "client_id", clientId },
18
22
  { "response_type", "device_code" },
@@ -21,12 +25,13 @@ namespace TapSDK.Login.Internal {
21
25
  { "platform", "unity" },
22
26
  { "info", "{\"device_id\":\"" + SystemInfo.deviceModel + "\"}" }
23
27
  };
24
- QRCodeResponse response = await httpClient.Post<QRCodeResponse>(TapTapSdk.CurrentRegion.CodeUrl(),
28
+ QRCodeResponse response = await httpClient.Post<QRCodeResponse>(TapTapSdk.CurrentRegion.CodeUrl(),
25
29
  data: data);
26
30
  return response.Data;
27
31
  }
28
32
 
29
- public static async Task<TokenData> Authorize(string clientId, string code) {
33
+ public static async Task<TokenData> Authorize(string clientId, string code)
34
+ {
30
35
  Dictionary<string, string> data = new Dictionary<string, string> {
31
36
  { "client_id", clientId },
32
37
  { "grant_type", "authorization_code" },
@@ -35,12 +40,13 @@ namespace TapSDK.Login.Internal {
35
40
  { "redirect_uri", WebLoginRequestManager.Instance.GetCurrentRequest().GetRedirectUri() },
36
41
  { "code_verifier", WebLoginRequestManager.Instance.GetCodeVerifier() }
37
42
  };
38
- TokenResponse response = await httpClient.Post<TokenResponse>(TapTapSdk.CurrentRegion.TokenUrl(),
43
+ TokenResponse response = await httpClient.Post<TokenResponse>(TapTapSdk.CurrentRegion.TokenUrl(),
39
44
  data: data);
40
45
  return response.Data;
41
46
  }
42
47
 
43
- public static async Task<TokenData> RequestScanQRCodeResult(string clientId, string deviceCode) {
48
+ public static async Task<TokenData> RequestScanQRCodeResult(string clientId, string deviceCode)
49
+ {
44
50
  Dictionary<string, string> data = new Dictionary<string, string> {
45
51
  { "grant_type", "device_token" },
46
52
  { "client_id", clientId },
@@ -50,16 +56,18 @@ namespace TapSDK.Login.Internal {
50
56
  { "platform", "unity" },
51
57
  { "info", "{\"device_id\":\"" + SystemInfo.deviceModel + "\"}" }
52
58
  };
53
- TokenResponse response = await httpClient.Post<TokenResponse>(TapTapSdk.CurrentRegion.TokenUrl(),
59
+ TokenResponse response = await httpClient.Post<TokenResponse>(TapTapSdk.CurrentRegion.TokenUrl(),
54
60
  data: data);
55
61
  return response.Data;
56
62
  }
57
63
 
58
- public static async Task<ProfileData> GetProfile(string clientId, AccessToken token, int timestamp = 0) {
64
+ public static async Task<ProfileData> GetProfile(string clientId, AccessToken token, int timestamp = 0)
65
+ {
59
66
  string url = TapTapSdk.CurrentRegion.ProfileUrl(token.scopeSet.Contains(TapTapLogin.TAP_LOGIN_SCOPE_PUBLIC_PROFILE)) + clientId;
60
67
  var uri = new Uri(url);
61
68
  var ts = timestamp;
62
- if (ts == 0) {
69
+ if (ts == 0)
70
+ {
63
71
  var dt = DateTime.UtcNow - new DateTime(1970, 1, 1);
64
72
  ts = (int)dt.TotalSeconds;
65
73
  }
@@ -76,7 +84,7 @@ namespace TapSDK.Login.Internal {
76
84
  ProfileResponse response = await httpClient.Get<ProfileResponse>(url, headers: headers);
77
85
  return response.Data;
78
86
  }
79
-
87
+
80
88
  public static string GetAuthorizationHeader(string kid,
81
89
  string macKey,
82
90
  string macAlgorithm,
@@ -84,13 +92,15 @@ namespace TapSDK.Login.Internal {
84
92
  string uri,
85
93
  string host,
86
94
  string port,
87
- int timestamp) {
95
+ int timestamp)
96
+ {
88
97
  var nonce = new System.Random().Next().ToString();
89
98
 
90
99
  var normalizedString = $"{timestamp}\n{nonce}\n{method}\n{uri}\n{host}\n{port}\n\n";
91
100
 
92
101
  HashAlgorithm hashGenerator;
93
- switch (macAlgorithm) {
102
+ switch (macAlgorithm)
103
+ {
94
104
  case "hmac-sha-256":
95
105
  hashGenerator = new HMACSHA256(Encoding.ASCII.GetBytes(macKey));
96
106
  break;
@@ -110,7 +120,8 @@ namespace TapSDK.Login.Internal {
110
120
  return authorizationHeader.ToString();
111
121
  }
112
122
 
113
- public static async Task<TokenData> RefreshToken(string clientId, string accessToken) {
123
+ public static async Task<TokenData> RefreshToken(string clientId, string accessToken)
124
+ {
114
125
  Dictionary<string, object> data = new Dictionary<string, object> {
115
126
  { "client_id", clientId },
116
127
  { "grant_type", "refresh_token" },
@@ -119,7 +130,7 @@ namespace TapSDK.Login.Internal {
119
130
  { "platform", "unity" },
120
131
  { "info", "{\"device_id\":\"" + SystemInfo.deviceModel + "\"}" }
121
132
  };
122
- TokenResponse response = await httpClient.Post<TokenResponse>(TapTapSdk.CurrentRegion.TokenUrl(),
133
+ TokenResponse response = await httpClient.Post<TokenResponse>(TapTapSdk.CurrentRegion.TokenUrl(),
123
134
  data: data);
124
135
  return response.Data;
125
136
  }
@@ -0,0 +1,45 @@
1
+ using System;
2
+ using System.Threading.Tasks;
3
+ using TapSDK.Core.Internal.Log;
4
+ using TapSDK.Core.Standalone.Internal.Service;
5
+ using TapSDK.Login.Internal;
6
+
7
+ namespace TapSDK.Login.Standalone.Internal
8
+ {
9
+ internal class TapLoginService : ITapLoginService
10
+ {
11
+ public string ObtainAuthorizationAsync(string url, string method)
12
+ {
13
+ TapTapAccount tapAccount = AccountManager.Instance.Account;
14
+ if (tapAccount == null)
15
+ {
16
+ return null;
17
+ }
18
+ AccessToken token = tapAccount.accessToken;
19
+ if (token == null)
20
+ {
21
+ return null;
22
+ }
23
+ var dt = DateTime.UtcNow - new DateTime(1970, 1, 1);
24
+ var ts = (int)dt.TotalSeconds;
25
+ string port = "443";
26
+ if (url.StartsWith("http://"))
27
+ {
28
+ port = "80";
29
+ }
30
+ UriBuilder uri = new UriBuilder(url);
31
+ string host = uri.Host;
32
+ string pathAndQuery = url.Substring(url.LastIndexOf(host) + host.Length);
33
+ var sign = "MAC " + LoginService.GetAuthorizationHeader(
34
+ token.kid,
35
+ token.macKey,
36
+ token.macAlgorithm,
37
+ method,
38
+ pathAndQuery,
39
+ host,
40
+ port,
41
+ ts);
42
+ return sign;
43
+ }
44
+ }
45
+ }
@@ -1,5 +1,5 @@
1
1
  fileFormatVersion: 2
2
- guid: cdf561f46b3c346708bd7de2f21c56da
2
+ guid: b5641596ac5084807a736c29246e2fe4
3
3
  MonoImporter:
4
4
  externalObjects: {}
5
5
  serializedVersion: 2
@@ -36,7 +36,7 @@ namespace TapSDK.Login.Internal
36
36
  {
37
37
  TapTapSdk.SDKInitialize(clientId, regionType == TapTapRegionType.CN);
38
38
  AccountManager.Instance.Init();
39
- CheckAndRefreshToken();
39
+ _ = CheckAndRefreshToken();
40
40
  TapLoginTracker.Instance.TrackInit();
41
41
  }
42
42
 
@@ -18,13 +18,13 @@ namespace TapSDK.Login.Internal {
18
18
  private readonly static string DEMO_IMAGE_URL_IOS_EN = $"{DEMO_IMAGE_IO_HOST}/scan-guide/ios.png";
19
19
  private readonly static string DEMO_IMAGE_URL_ANDROID_EN = $"{DEMO_IMAGE_IO_HOST}/scan-guide/android.png";
20
20
 
21
- private readonly static string DEFAULT_IOS_CLIENT = "Sprites/taptap-login-ios-client";
22
- private readonly static string DEFAULT_ANDROID_CLIENT = "Sprites/taptap-login-android-client";
21
+ // private readonly static string DEFAULT_IOS_CLIENT = "Sprites/taptap-login-ios-client";
22
+ // private readonly static string DEFAULT_ANDROID_CLIENT = "Sprites/taptap-login-android-client";
23
23
 
24
24
  private readonly static string AUTH_PENDING = "authorization_pending";
25
25
  private readonly static string AUTH_WAITING = "authorization_waiting";
26
26
  private readonly static string AUTH_DENIED = "access_denied";
27
- private readonly static string AUTH_SUCCESS = "";
27
+ // private readonly static string AUTH_SUCCESS = "";
28
28
 
29
29
  private readonly Action<TokenData, String> onAuth;
30
30
 
package/link.xml ADDED
@@ -0,0 +1,4 @@
1
+ <linker>
2
+ <assembly fullname="TapSDK.Login.Runtime" preserve="all" />
3
+ <assembly fullname="TapSDK.Login.Mobile.Runtime" preserve="all" />
4
+ </linker>
package/link.xml.meta ADDED
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: be71b67c0945c40c0817e128f2bff96a
3
+ TextScriptImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
package/package.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "name": "com.taptap.sdk.login",
3
3
  "displayName": "TapTapSDK Login",
4
4
  "description": "TapTapSDK Login",
5
- "version": "4.3.12",
5
+ "version": "4.4.0",
6
6
  "unity": "2019.4",
7
7
  "license": "MIT",
8
8
  "dependencies": {
9
- "com.taptap.sdk.core": "4.3.12"
9
+ "com.taptap.sdk.core": "4.4.0"
10
10
  }
11
11
  }
@@ -1,291 +0,0 @@
1
- using System;
2
- using System.Collections;
3
- using System.Collections.Generic;
4
- using System.Collections.Specialized;
5
- using System.Text;
6
- using System.Text.RegularExpressions;
7
- using TapSDK.Core;
8
- using UnityEngine;
9
-
10
- namespace TapSDK.Login.Internal
11
- {
12
- public class Net : MonoBehaviour
13
- {
14
- public delegate void Action();
15
-
16
- // ReSharper disable Unity.PerformanceAnalysis
17
- public void PostAsync(string url, Dictionary<string, string> queryParams, Dictionary<string, string> formParams, Action<string> methodForResult, Action<int, string> methodForError)
18
- {
19
- if (string.IsNullOrEmpty(url))
20
- {
21
- methodForError(-1, "empty url");
22
- return;
23
- }
24
- StartCoroutine(Post(url, queryParams, formParams, methodForResult, methodForError));
25
- }
26
-
27
- // ReSharper disable Unity.PerformanceAnalysis
28
- public void GetAsync(string url, string authorization, Dictionary<string, string> queryParams, Action<string> methodForResult, Action<int, string> methodForError)
29
- {
30
- if (string.IsNullOrEmpty(url))
31
- {
32
- methodForError(-1, "empty url");
33
- return;
34
- }
35
- StartCoroutine(Get(url, authorization, queryParams, methodForResult, methodForError));
36
- }
37
-
38
- // ReSharper disable Unity.PerformanceAnalysis
39
- private IEnumerator Get(string url, string authorization, Dictionary<string, string> queryParams, Action<string> methodForResult, Action<int, string> methodForError)
40
- {
41
- string baseUrl;
42
- Dictionary<string, string> finalQueryParams = queryParams ?? new Dictionary<string, string>();
43
- NameValueCollection collection = new NameValueCollection();
44
- ParseUrl(url, out baseUrl, out collection);
45
- foreach (string key in collection.AllKeys)
46
- {
47
- foreach (string value in collection.GetValues(key))
48
- {
49
- finalQueryParams.Add(key, value);
50
- }
51
- }
52
- string finalUrl;
53
- if (finalQueryParams.Count == 0)
54
- {
55
- finalUrl = baseUrl;
56
- }
57
- else
58
- {
59
- finalUrl = baseUrl + "?" + DictToQueryString(finalQueryParams);
60
- }
61
-
62
-
63
- Dictionary<string, string> headers = new Dictionary<string, string>();
64
- headers.Add("User-Agent", "TapTapUnitySDK/" + TapTapSdk.Version + " " + "UnityPlayer/" + Application.unityVersion);
65
- headers.Add("Authorization", authorization);
66
- WWW w = new WWW(finalUrl, null, headers);
67
- PrintRequest(w, "GET", null, headers);
68
- yield return w;
69
- PrintResponse(w);
70
- if (!string.IsNullOrEmpty(w.error))
71
- {
72
- string data = w.text;
73
- if (data != null)
74
- {
75
- methodForError(GetResponseCode(w), data);
76
- }
77
- else
78
- {
79
- methodForError(GetResponseCode(w), w.error);
80
- }
81
-
82
- w.Dispose();
83
- yield break;
84
- }
85
- else
86
- {
87
- string data = w.text;
88
- if (data != null)
89
- {
90
- methodForResult(w.text);
91
- yield break;
92
- }
93
- else
94
- {
95
- methodForError(GetResponseCode(w), "Empyt response from server : " + url);
96
- }
97
- }
98
- }
99
-
100
- // ReSharper disable Unity.PerformanceAnalysis
101
- private IEnumerator Post(string url, Dictionary<string, string> queryParams, Dictionary<string, string> formParams, Action<string> methodForResult, Action<int, string> methodForError)
102
- {
103
- string baseUrl;
104
- Dictionary<string, string> finalQueryParams = queryParams ?? new Dictionary<string, string>();
105
- NameValueCollection collection = new NameValueCollection();
106
- ParseUrl(url, out baseUrl, out collection);
107
- foreach (string key in collection.AllKeys)
108
- {
109
- foreach (string value in collection.GetValues(key))
110
- {
111
- finalQueryParams.Add(key, value);
112
- }
113
- }
114
- string finalUrl;
115
- if(finalQueryParams.Count == 0)
116
- {
117
- finalUrl = baseUrl;
118
- } else
119
- {
120
- finalUrl = baseUrl + "?" + DictToQueryString(finalQueryParams);
121
- }
122
- WWWForm wwwForm = new WWWForm();
123
- Dictionary<string, string> finalFormParams = formParams ?? new Dictionary<string, string>();
124
- foreach (KeyValuePair<string, string> kv in finalFormParams)
125
- {
126
- // Debug.Log($"kv.key:{kv.Key} value:{kv.Value}");
127
- wwwForm.AddField(kv.Key, kv.Value);
128
- ; }
129
-
130
-
131
- Dictionary<string, string> headers = new Dictionary<string, string>();
132
- headers.Add("User-Agent", "TapTapUnitySDK/1.0 " + "UnityPlayer/" + Application.unityVersion);
133
- WWW w = new WWW(finalUrl, wwwForm.data, headers);
134
- PrintRequest(w, "POST", wwwForm, headers);
135
- yield return w;
136
- PrintResponse(w);
137
- if (!string.IsNullOrEmpty(w.error))
138
- {
139
- string data = w.text;
140
- if (data != null)
141
- {
142
- methodForError(GetResponseCode(w), data);
143
- }
144
- else
145
- {
146
- methodForError(GetResponseCode(w), w.error);
147
- }
148
-
149
- w.Dispose();
150
- yield break;
151
- }
152
- else
153
- {
154
- string data = w.text;
155
- if (data != null)
156
- {
157
- methodForResult(w.text);
158
- yield break;
159
- }
160
- else
161
- {
162
- methodForError(GetResponseCode(w), "Empyt response from server : " + url);
163
- }
164
- }
165
- }
166
- public static void PrintRequest(WWW request, string method, WWWForm wwwFrom, Dictionary<string, string> headers) {
167
- if (TapLogger.LogDelegate == null) {
168
- return;
169
- }
170
- if (request == null) {
171
- return;
172
- }
173
- StringBuilder sb = new StringBuilder();
174
- sb.AppendLine("=== HTTP Request Start ===");
175
- sb.AppendLine($"URL: {request.url}");
176
- sb.AppendLine($"Method: {method}");
177
-
178
- sb.AppendLine($"Headers: \t");
179
- if (wwwFrom?.headers != null)
180
- {
181
- foreach (var header in wwwFrom.headers) {
182
- sb.AppendLine($"{header.Key}: {header.Value}");
183
- }
184
- }
185
-
186
- if (headers != null)
187
- {
188
- foreach (var header in headers) {
189
- sb.AppendLine($"{header.Key}: {header.Value}");
190
- }
191
- }
192
- sb.AppendLine("=== HTTP Request End ===");
193
- TapLogger.Debug(sb.ToString());
194
- }
195
-
196
- private static void PrintResponse(WWW response) {
197
- if (TapLogger.LogDelegate == null) {
198
- return;
199
- }
200
- StringBuilder sb = new StringBuilder();
201
- sb.AppendLine("=== HTTP Response Start ===");
202
- sb.AppendLine($"URL: {response.url}");
203
- sb.AppendLine($"Status Code: {GetResponseCode(response)}");
204
- sb.AppendLine($"error: {response.error}");
205
- if (!string.IsNullOrEmpty(response.text)) {
206
- sb.AppendLine($"Content: {response.text}");
207
- }
208
- sb.AppendLine("=== HTTP Response End ===");
209
- TapLogger.Debug(sb.ToString());
210
- }
211
-
212
- public static int GetResponseCode(WWW request)
213
- {
214
- int ret = 0;
215
- if (request.responseHeaders == null)
216
- {
217
- Debug.LogError("no response headers.");
218
- }
219
- else
220
- {
221
- if (!request.responseHeaders.ContainsKey("STATUS"))
222
- {
223
- Debug.LogError("response headers has no STATUS.");
224
- }
225
- else
226
- {
227
- ret = ParseResponseCode(request.responseHeaders["STATUS"]);
228
- }
229
- }
230
-
231
- return ret;
232
- }
233
-
234
- public static int ParseResponseCode(string statusLine)
235
- {
236
- int ret = 0;
237
-
238
- string[] components = statusLine.Split(' ');
239
- if (components.Length < 3)
240
- {
241
- Debug.LogError("invalid response status: " + statusLine);
242
- }
243
- else
244
- {
245
- if (!int.TryParse(components[1], out ret))
246
- {
247
- Debug.LogError("invalid response code: " + components[1]);
248
- }
249
- }
250
-
251
- return ret;
252
- }
253
-
254
- public static string DictToQueryString(IDictionary<string, string> dict)
255
- {
256
- List<string> list = new List<string>();
257
- foreach (var item in dict)
258
- {
259
- list.Add(item.Key + "=" + item.Value);
260
- }
261
- return string.Join("&", list.ToArray());
262
- }
263
-
264
- public static void ParseUrl(string url, out string baseUrl, out NameValueCollection nvc)
265
- {
266
- if (url == null)
267
- throw new ArgumentNullException("url");
268
- nvc = new NameValueCollection();
269
- baseUrl = "";
270
- if (url == "")
271
- return;
272
- int questionMarkIndex = url.IndexOf('?');
273
- if (questionMarkIndex == -1)
274
- {
275
- baseUrl = url;
276
- return;
277
- }
278
- baseUrl = url.Substring(0, questionMarkIndex);
279
- if (questionMarkIndex == url.Length - 1)
280
- return;
281
- string ps = url.Substring(questionMarkIndex + 1);
282
- Regex re = new Regex(@"(^|&)?(\w+)=([^&]+)(&|$)?", RegexOptions.None);
283
- MatchCollection mc = re.Matches(ps);
284
- foreach (Match m in mc)
285
- {
286
- nvc.Add(m.Result("$2").ToLower(), m.Result("$3"));
287
- }
288
- }
289
-
290
- }
291
- }
@@ -1,776 +0,0 @@
1
- using System;
2
- using System.Collections;
3
- using System.Collections.Generic;
4
- using System.Diagnostics;
5
- using System.Linq;
6
- using System.Net;
7
- using System.Security.Cryptography;
8
- using System.Text;
9
- using System.Threading.Tasks;
10
- using TapSDK.Core;
11
- using UnityEngine;
12
- using UnityEngine.UI;
13
- using ZXing;
14
- using ZXing.Common;
15
- using ZXing.QrCode.Internal;
16
- using Debug = UnityEngine.Debug;
17
- using Random = System.Random;
18
-
19
- namespace TapSDK.Login.Internal
20
- {
21
- internal class QRCodeWindow : UIElement
22
- {
23
- // // \ue90f\ue91c\ue911\ue91a\ue901\ue902\ue903\ue90c 您已取消此次登录
24
- // private static readonly string TEXT_CANCEL_LOGIN = "";
25
- //
26
- // // \ue910\ue91f\ue91b\ue914\ue90d 请重新扫码
27
- // private static readonly string TEXT_PLEASE_RESCRAN = "";
28
- //
29
- // // \ue914\ue90d\ue900\ue907 扫码成功
30
- // private static readonly string TEXT_SCAN_SUCCESS = "";
31
- //
32
- // // \ue910\ue91e\ue917\ue90a\ue915\ue912\ue913 请在手机上确认
33
- // private static readonly string TEXT_CONFIRM_ON_PHONE = "";
34
-
35
- public RawImage QRCodeRawImage;
36
- public Text StatusText;
37
- public Text SubStatusText;
38
- public Image RefreshImage;
39
- public Button RefreshButton;
40
- public Button CloseButton;
41
-
42
- public Button WebLoginButton;
43
-
44
- private string clientId;
45
- private string[] scopes;
46
- private bool isLogin;
47
-
48
- private string deviceCode;
49
- private long expireAt = 0;
50
- private long lastCheckAt = 0;
51
- private long interval = 5;
52
-
53
- private Net net;
54
- private HttpListener _httpListener;
55
-
56
- private long lastWebRequestTime = 0;
57
- private string webRequestMode = "";
58
-
59
- private void SetObjectText(string parentName, string objectName, string text)
60
- {
61
- try
62
- {
63
- var targetTransform = transform;
64
- if (!string.IsNullOrEmpty(parentName))
65
- {
66
- targetTransform = transform.Find(parentName).gameObject.transform;
67
- }
68
-
69
- var targetObject = targetTransform.Find(objectName).gameObject;
70
- var gameText = targetObject.GetComponent<Text>();
71
- gameText.text = text;
72
- }
73
- catch (Exception e)
74
- {
75
- Debug.Log("SetObjectText fail" + parentName + " " + objectName);
76
- Debug.Log("SetObjectText fail\n" + e);
77
- }
78
- }
79
-
80
- void Awake()
81
- {
82
- var qrImageObject = transform.Find("QRImage").gameObject;
83
- QRCodeRawImage = qrImageObject.GetComponent<RawImage>();
84
- var statusObject = transform.Find("Status").gameObject;
85
- StatusText = statusObject.GetComponent<Text>();
86
- var subStatusObject = transform.Find("SubStatus").gameObject;
87
- SubStatusText = subStatusObject.GetComponent<Text>();
88
- var refreshObject = transform.Find("Refresh").gameObject;
89
- RefreshImage = refreshObject.GetComponent<Image>();
90
- var refreshButtonObject = refreshObject.transform.Find("RefreshButton").gameObject;
91
- RefreshButton = refreshButtonObject.GetComponent<Button>();
92
- var closeObject = transform.Find("Close").gameObject;
93
- CloseButton = closeObject.GetComponent<Button>();
94
-
95
- var webLoginButtonObject = transform.Find("WebLoginButton").gameObject;
96
- WebLoginButton = webLoginButtonObject.GetComponent<Button>();
97
-
98
- WebLoginButton.onClick.AddListener(() =>
99
- {
100
- var now = GetCurrentTime();
101
- if (now - lastWebRequestTime > 1)
102
- {
103
- StartWebLogin();
104
- }
105
-
106
- lastWebRequestTime = now;
107
- });
108
- RefreshImage.gameObject.SetActive(false);
109
- RefreshButton.onClick.AddListener(RefreshCode);
110
- SubStatusText.gameObject.SetActive(false);
111
- StatusText.gameObject.SetActive(false);
112
- CloseButton.onClick.AddListener(Close);
113
-
114
- // SetObjectText("TitleContent", "TitleUse", LoginLanguage.GetCurrentLang().TitleUse());
115
- SetObjectText("TitleContent", "TitleAccount", LoginLanguage.GetCurrentLang().TitleLogin());
116
- SetObjectText("", "ScanLogin", LoginLanguage.GetCurrentLang().QrTitleLogin());
117
- SetObjectText("", "ScanLogin", LoginLanguage.GetCurrentLang().QrTitleLogin());
118
- SetObjectText("Notice", "Notice1", LoginLanguage.GetCurrentLang().QrNoticeUse());
119
- SetObjectText("Notice", "Notice2", LoginLanguage.GetCurrentLang().QrNoticeClient());
120
- SetObjectText("", "Notice3", LoginLanguage.GetCurrentLang().QrNoticeScanToLogin());
121
- SetObjectText("", "WebLogin", LoginLanguage.GetCurrentLang().WebLogin());
122
- SetObjectText("", "WebDescription", LoginLanguage.GetCurrentLang().WebNotice());
123
- SetObjectText("WebLoginButton", "Text", LoginLanguage.GetCurrentLang().WebButtonJumpToWeb());
124
-
125
- refreshButtonObject.transform.Find("Text").gameObject.GetComponent<Text>().text =
126
- LoginLanguage.GetCurrentLang().QrRefresh();
127
-
128
- if (string.IsNullOrEmpty(LoginLanguage.GetCurrentLang().QrNoticeUse()) &&
129
- string.IsNullOrEmpty(LoginLanguage.GetCurrentLang().QrNoticeClient())) {
130
- GameObject logoGO = transform.Find("Notice/Logo").gameObject;
131
- logoGO.SetActive(false);
132
- }
133
- }
134
-
135
- public override void OnEnter()
136
- {
137
- base.OnEnter();
138
- gameObject.AddComponent<Net>();
139
- net = gameObject.GetComponent<Net>();
140
- GetCode();
141
- WebLoginRequestManager.Instance.CreateNewLoginRequest(scopes);
142
- StartHttpServer();
143
- }
144
-
145
- public override void OnExit()
146
- {
147
- base.OnExit();
148
- Destroy(net.gameObject);
149
- }
150
-
151
- private void Close()
152
- {
153
- if (_httpListener != null)
154
- {
155
- try
156
- {
157
- _httpListener.Stop();
158
- }
159
- catch (Exception)
160
- {
161
- // ignored
162
- }
163
- }
164
-
165
- OnCallback(UIManager.RESULT_CLOSE, "Close button clicked.");
166
- GetUIManager().Pop();
167
- }
168
-
169
- private void StartHttpServer()
170
- {
171
- if (_httpListener == null)
172
- {
173
- _httpListener = new HttpListener();
174
- _httpListener.Prefixes.Add(WebLoginRequestManager.Instance.GetCurrentRequest().GetRedirectHost());
175
- }
176
-
177
- try
178
- {
179
- _httpListener.Start();
180
- }
181
- catch (Exception)
182
- {
183
- Debug.Log("Http listener start fail, maybe is already started");
184
- }
185
- }
186
-
187
- private void StartWebLogin()
188
- {
189
- ShowStatus("", "");
190
-
191
- Application.OpenURL(WebLoginRequestManager.Instance.GetCurrentRequest().GetWebLoginUrl());
192
- // Waits for the OAuth authorization response.
193
-
194
- _ = StartWaitForRequest();
195
-
196
- // _httpListener.BeginGetContext(HandleHttpRequest, _httpListener);
197
- }
198
-
199
- private async Task StartWaitForRequest()
200
- {
201
- HttpListenerContext context = await _httpListener.GetContextAsync();
202
-
203
- Debug.Log(context.Request.RawUrl);
204
-
205
- if (context.Request.HttpMethod == "OPTIONS") {
206
- // 跨域请求
207
- context.Response.StatusCode = 200;
208
- context.Response.Close();
209
- } else {
210
- webRequestMode = "";
211
- // NOTE@luran:这里负责监听 authorization code 的回调
212
- TapLogger.Debug($"[TapLogin] Get Authorization Code Response: {context.Request.RawUrl}");
213
- var resultCode = UrlCheck(context.Request.RawUrl);
214
-
215
- CodeToTokenFromWeb(resultCode);
216
-
217
- var response = context.Response;
218
- var buffer = Array.Empty<byte>();
219
- if (!string.IsNullOrEmpty(resultCode)) {
220
- switch (webRequestMode) {
221
- case "gif": {
222
- response.StatusCode = 200;
223
- response.AppendHeader("Access-Control-Allow-Origin", "*");
224
- response.ContentType = "image/gif";
225
- const string gif = "R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAICTAEAOw==";
226
- try {
227
- buffer = Convert.FromBase64String(gif);
228
- } catch (Exception) {
229
- buffer = Encoding.UTF8.GetBytes("ok");
230
- }
231
-
232
- break;
233
- }
234
- case "redirect":
235
- response.Redirect(CodeUtil.GetTapTapOAuthRedirectUri());
236
- break;
237
- default:
238
- response.StatusCode = 200;
239
- response.AppendHeader("Access-Control-Allow-Origin", "*");
240
- response.ContentType = "text/plain";
241
- buffer = Encoding.UTF8.GetBytes("ok");
242
- break;
243
- }
244
- } else {
245
- response.StatusCode = 404;
246
- }
247
-
248
- response.ContentLength64 = buffer.Length;
249
- var responseOutput = response.OutputStream;
250
- await responseOutput.WriteAsync(buffer, 0, buffer.Length)
251
- .ContinueWith((task) => { responseOutput.Close(); });
252
- }
253
-
254
- _ = StartWaitForRequest();
255
- }
256
-
257
- private string UrlCheck(string url)
258
- {
259
- // check url
260
- if (string.IsNullOrEmpty(url) || !url.Contains(CodeUtil.GetTapTapOAuthPrefix()))
261
- {
262
- return null;
263
- }
264
-
265
- var urlParams = url.Split('?');
266
- if (urlParams.Length <= 1)
267
- {
268
- return null;
269
- }
270
-
271
- var args = urlParams[1].Split('&');
272
- var dic = args.Select(arg => arg.Split('=')).ToDictionary(kv => kv[0], kv => kv[1]);
273
-
274
- var code = dic.ContainsKey("code") ? dic["code"] : "";
275
- var state = dic.ContainsKey("state") ? dic["state"] : "";
276
- webRequestMode = dic.ContainsKey("mode") ? dic["mode"] : "";
277
- if (string.IsNullOrEmpty(code) || string.IsNullOrEmpty(state))
278
- {
279
- return null;
280
- }
281
-
282
- var content = new StringBuilder();
283
- foreach (var VARIABLE in dic) {
284
- content.AppendLine($"key: {VARIABLE.Key}, value: {VARIABLE.Value}");
285
- }
286
-
287
- TapLogger.Debug($"[TapLogin] Get Authorization Code Response Content:\n {content.ToString()}");
288
-
289
- return !state.Equals(WebLoginRequestManager.Instance.GetCurrentRequest().GetState()) ? null : code;
290
- }
291
-
292
- private void CodeToTokenFromWeb(string code)
293
- {
294
- if (string.IsNullOrEmpty(code)) return;
295
- ShowStatus(LoginLanguage.GetCurrentLang().WebNoticeLogin(), "");
296
- // url is ok, go to get token
297
- var formParams = new Dictionary<string, string>
298
- {
299
- { "client_id", clientId },
300
- { "grant_type", "authorization_code" },
301
- { "secret_type", "hmac-sha-1" },
302
- { "code", code },
303
- { "redirect_uri", WebLoginRequestManager.Instance.GetCurrentRequest().GetRedirectUri() },
304
- { "code_verifier", WebLoginRequestManager.Instance.GetCodeVerifier() }
305
- };
306
- net.PostAsync(TapTapSdk.CurrentRegion.TokenUrl(), null, formParams, (result =>
307
- {
308
- TapLogger.Debug($"[TapLogin] Get Access Token Origin Result: {result}");
309
- if (Json.Deserialize(result) is Dictionary<string, object> resultDict &&
310
- resultDict.ContainsKey("success") && (bool)resultDict["success"])
311
- {
312
- if (resultDict["data"] is Dictionary<string, object> dataDict) {
313
- // convert dataDict content to a format string for debug
314
- #if UNITY_EDITOR
315
- var c = new StringBuilder();
316
- foreach (var kv in dataDict) {
317
- c.AppendLine($"key: {kv.Key}, valuue: {kv.Value.ToString()}");
318
- }
319
- TapLogger.Debug($"[TapLogin] Get Access Token data:\n {c.ToString()}");
320
- #endif
321
- var token = new AccessToken
322
- {
323
- kid = dataDict["kid"] as string,
324
- macKey = dataDict["mac_key"] as string,
325
- tokenType = dataDict["token_type"] as string,
326
- macAlgorithm = dataDict["mac_algorithm"] as string,
327
- scopeSet = new HashSet<string>((dataDict["scope"] as string)?.Split(' '))
328
- };
329
-
330
- // stop http server when success get token
331
- _httpListener.Stop();
332
- Debug.Log("HTTP server stopped.");
333
- GetProfile(token);
334
- return;
335
- }
336
- }
337
-
338
- ShowStatus(LoginLanguage.GetCurrentLang().WebNoticeFail(),
339
- LoginLanguage.GetCurrentLang().WebNoticeFail2());
340
- Debug.Log("CodeToTokenFromWeb success with fail data \n" + result);
341
- }), ((error, msg) =>
342
- {
343
- Debug.Log("CodeToTokenFromWeb fail \n" + msg);
344
- if (Json.Deserialize(msg) is Dictionary<string, object> resultDict &&
345
- resultDict.ContainsKey("data"))
346
- {
347
- if (resultDict["data"] is Dictionary<string, object> dataDict &&
348
- dataDict.ContainsKey("error"))
349
- {
350
- var errorMsg = dataDict["error"] as string;
351
- var errorDesc = dataDict["error_description"] as string;
352
- ShowStatus(LoginLanguage.GetCurrentLang().WebNoticeFail(),
353
- LoginLanguage.GetCurrentLang().WebNoticeFail2());
354
- return;
355
- }
356
- }
357
-
358
- ShowStatus(LoginLanguage.GetCurrentLang().WebNoticeFail(),
359
- LoginLanguage.GetCurrentLang().WebNoticeFail2());
360
- }));
361
- }
362
-
363
- private void RefreshCode()
364
- {
365
- StatusText.gameObject.SetActive(false);
366
- SubStatusText.gameObject.SetActive(false);
367
- GetCode();
368
- }
369
-
370
- private void GetCode() {
371
- RefreshImage.gameObject.SetActive(false);
372
-
373
- var formParams = new Dictionary<string, string>
374
- {
375
- { "client_id", clientId },
376
- { "response_type", "device_code" },
377
- { "scope", string.Join(",", scopes) },
378
- { "version", TapTapSdk.Version },
379
- { "platform", "unity" },
380
- { "info", "{\"device_id\":\"" + SystemInfo.deviceModel + "\"}" }
381
- };
382
- net.PostAsync(TapTapSdk.CurrentRegion.CodeUrl(),
383
- null,
384
- formParams,
385
- (result) =>
386
- {
387
- if (Json.Deserialize(result) is Dictionary<string, object> resultDict &&
388
- resultDict.ContainsKey("success") && (bool)resultDict["success"])
389
- {
390
- if (resultDict["data"] is Dictionary<string, object> dataDict &&
391
- dataDict.ContainsKey("qrcode_url"))
392
- {
393
- var qrCodeUrl = dataDict["qrcode_url"] as string;
394
- EncodeQrImage(qrCodeUrl, 309, 309);
395
- if (dataDict.ContainsKey("device_code"))
396
- {
397
- deviceCode = dataDict["device_code"] as string;
398
- }
399
-
400
- if (dataDict.ContainsKey("expires_in"))
401
- {
402
- var expireIn = (long)dataDict["expires_in"];
403
- var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
404
- expireAt = Convert.ToInt64(ts.TotalSeconds) + expireIn;
405
- }
406
-
407
- if (dataDict.ContainsKey("interval"))
408
- {
409
- interval = (long)dataDict["interval"];
410
- }
411
-
412
- StartCheck();
413
- Debug.Log("QRCODE Get");
414
- }
415
- else
416
- {
417
- //StatusText.text = "获取二维码失败";
418
- ShowQrRefresh();
419
- Debug.Log("QRCODE Get Fail 1");
420
- }
421
- }
422
- else
423
- {
424
- //StatusText.text = "获取二维码失败";
425
- ShowQrRefresh();
426
- Debug.Log("QRCODE Get Fail 2");
427
- }
428
- },
429
- (error, msg) =>
430
- {
431
- //StatusText.text = "获取二维码失败";
432
- ShowQrRefresh();
433
- Debug.Log("QRCODE Get Fail 3");
434
- }
435
- );
436
- }
437
-
438
- private void EncodeQrImage(string content, int width, int height)
439
- {
440
- var writer = new MultiFormatWriter();
441
- var hints = new Dictionary<EncodeHintType, object>
442
- {
443
- { EncodeHintType.CHARACTER_SET, "UTF-8" },
444
- //hints.Add(EncodeHintType.MARGIN, 0);
445
- { EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M }
446
- };
447
- var bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
448
- bitMatrix = DeleteWhite(bitMatrix);
449
- var w = bitMatrix.Width;
450
- var h = bitMatrix.Height;
451
- var texture = new Texture2D(w, h);
452
- for (var x = 0; x < h; x++)
453
- {
454
- for (var y = 0; y < w; y++)
455
- {
456
- texture.SetPixel(y, x, bitMatrix[x, y] ? Color.black : Color.white);
457
- }
458
- }
459
-
460
- texture.Apply();
461
- texture.filterMode = FilterMode.Point;
462
- QRCodeRawImage.texture = texture;
463
- }
464
-
465
- private static BitMatrix DeleteWhite(BitMatrix matrix)
466
- {
467
- var rec = matrix.getEnclosingRectangle();
468
- var resWidth = rec[2];
469
- var resHeight = rec[3];
470
-
471
- var resMatrix = new BitMatrix(resWidth, resHeight);
472
- resMatrix.clear();
473
- for (var i = 0; i < resWidth; i++)
474
- {
475
- for (var j = 0; j < resHeight; j++)
476
- {
477
- if (matrix[i + rec[0], j + rec[1]])
478
- {
479
- resMatrix.flip(i, j);
480
- }
481
- }
482
- }
483
-
484
- return resMatrix;
485
- }
486
-
487
- private void StartCheck()
488
- {
489
- StartCoroutine(nameof(AutoCheck));
490
- }
491
-
492
- private void StopCheck()
493
- {
494
- StopCoroutine(nameof(AutoCheck));
495
- }
496
-
497
- private IEnumerator AutoCheck()
498
- {
499
- while (true)
500
- {
501
- yield return new WaitForSeconds(0.5f);
502
- var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
503
- var now = Convert.ToInt64(ts.TotalSeconds);
504
- //Debug.Log("Now: " + now + " ExpireAt: " + expireAt + " Remain: " + (expireAt - now));
505
- if (now > expireAt)
506
- {
507
- ShowQrRefresh();
508
- StopCheck();
509
- break;
510
- }
511
-
512
- if (now <= lastCheckAt + interval) continue;
513
- var wait = true;
514
- var stop = false;
515
- var formParams = new Dictionary<string, string>
516
- {
517
- { "grant_type", "device_token" },
518
- { "client_id", clientId },
519
- { "secret_type", "hmac-sha-1" },
520
- { "code", deviceCode },
521
- { "version", "1.0" },
522
- { "platform", "unity" },
523
- { "info", "{\"device_id\":\"" + SystemInfo.deviceModel + "\"}" }
524
- };
525
- net.PostAsync(TapTapSdk.CurrentRegion.TokenUrl(),
526
- null,
527
- formParams,
528
- (result) =>
529
- {
530
- //StatusText.text = "";
531
- TapLogger.Debug(string.Format("qr code login result: {0}", result));
532
- if (Json.Deserialize(result) is Dictionary<string, object> resultDict &&
533
- resultDict.ContainsKey("success") && (bool)resultDict["success"])
534
- {
535
- //StatusText.text = "扫码成功";
536
- //SubStatusText.gameObject.SetActive(false);
537
- if (resultDict["data"] is Dictionary<string, object> dataDict)
538
- {
539
- var token = new AccessToken
540
- {
541
- kid = dataDict["kid"] as string,
542
- macKey = dataDict["mac_key"] as string,
543
- tokenType = dataDict["token_type"] as string,
544
- macAlgorithm = dataDict["mac_algorithm"] as string,
545
- scopeSet = new HashSet<string>((dataDict["scope"] as string)?.Split(' '))
546
- };
547
-
548
- GetProfile(token);
549
- }
550
- else
551
- {
552
- ShowQrRefresh();
553
- }
554
- }
555
- else
556
- {
557
- //StatusText.text = "扫描二维码失败";
558
- ShowQrRefresh();
559
- }
560
-
561
- wait = false;
562
- stop = true;
563
- StopCheck();
564
- },
565
- (error, msg) =>
566
- {
567
- wait = false;
568
-
569
- if (Json.Deserialize(msg) is Dictionary<string, object> resultDict &&
570
- resultDict.ContainsKey("data"))
571
- {
572
- if (resultDict["data"] is Dictionary<string, object> dataDict &&
573
- dataDict.ContainsKey("error"))
574
- {
575
- var errorMsg = dataDict["error"] as string;
576
-
577
- // Debug.Log("QRCODE FAIL " + errorMsg);
578
- switch (errorMsg)
579
- {
580
- case "authorization_pending":
581
- //StatusText.text = "扫码二维码登录";
582
- break;
583
- case "authorization_waiting":
584
- ShowStatus(LoginLanguage.GetCurrentLang().QrnNoticeSuccess(),
585
- LoginLanguage.GetCurrentLang().QrnNoticeSuccess2());
586
- break;
587
- case "access_denied":
588
- ShowStatus(LoginLanguage.GetCurrentLang().QrNoticeCancel(),
589
- LoginLanguage.GetCurrentLang().QrNoticeCancel2());
590
- stop = true;
591
- StopCheck();
592
- GetCode();
593
- break;
594
- case "invalid_grant":
595
- ShowQrRefresh();
596
- stop = true;
597
- StopCheck();
598
- break;
599
- case "slow_down":
600
- break;
601
- default:
602
- ShowQrRefresh();
603
- stop = true;
604
- StopCheck();
605
- break;
606
- }
607
-
608
- return;
609
- }
610
- }
611
-
612
- // if false then refresh
613
- ShowQrRefresh();
614
- stop = true;
615
- StopCheck();
616
- }
617
- );
618
- while (wait)
619
- {
620
- yield return new WaitForSeconds(0.5f);
621
- }
622
-
623
- ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
624
- lastCheckAt = Convert.ToInt64(ts.TotalSeconds);
625
- if (stop) break;
626
- }
627
- }
628
-
629
- private void GetProfile(AccessToken accessToken, int timestamp = 0) {
630
- var havePublicProfile = accessToken.scopeSet != null && accessToken.scopeSet.Contains("public_profile");
631
- var url = TapTapSdk.CurrentRegion.ProfileUrl(havePublicProfile) + clientId;
632
- var ts = timestamp;
633
- if (ts == 0)
634
- {
635
- var dt = DateTime.UtcNow - new DateTime(1970, 1, 1);
636
- ts = (int)dt.TotalSeconds;
637
- }
638
-
639
- var uri = new Uri(url);
640
- var sign = "MAC " + GetAuthorizationHeader(accessToken.kid,
641
- accessToken.macKey,
642
- accessToken.macAlgorithm,
643
- "GET",
644
- uri.PathAndQuery,
645
- uri.Host,
646
- "443", ts);
647
-
648
- net.GetAsync(url,
649
- sign,
650
- null,
651
- (result) =>
652
- {
653
- try
654
- {
655
- var tokenDict = new Dictionary<string, string>
656
- {
657
- { "kid", accessToken.kid },
658
- { "mac_key", accessToken.macKey },
659
- { "token_type", accessToken.tokenType },
660
- { "mac_algorithm", accessToken.macAlgorithm },
661
- { "scope", string.Join(" ", accessToken.scopeSet) },
662
- };
663
-
664
- if (Json.Deserialize(result) is Dictionary<string, object> resultDict &&
665
- resultDict.ContainsKey("success") && (bool)resultDict["success"])
666
- {
667
- var dataDict = resultDict["data"] as Dictionary<string, object>;
668
- var profileStr = Json.Serialize(dataDict);
669
- Profile p = new Profile(profileStr);
670
- if (isLogin) {
671
- DataStorage.SaveString("taptapsdk_accesstoken", Json.Serialize(tokenDict));
672
- DataStorage.SaveString("taptapsdk_profile", profileStr);
673
- }
674
- OnCallback(UIManager.RESULT_SUCCESS, new Tuple<AccessToken, Profile>(accessToken, p));
675
- GetUIManager().Pop();
676
- }
677
- else
678
- {
679
- OnCallback(UIManager.RESULT_FAILED, "Get profile error");
680
- GetUIManager().Pop();
681
- }
682
- }
683
- catch (Exception)
684
- {
685
- OnCallback(UIManager.RESULT_FAILED, "Get profile error");
686
- GetUIManager().Pop();
687
- }
688
- },
689
- (error, msg) =>
690
- {
691
- if (timestamp == 0 && !string.IsNullOrEmpty(msg) && msg.Contains("invalid_time") &&
692
- msg.Contains("now"))
693
- {
694
- try
695
- {
696
- if (!(Json.Deserialize(msg) is Dictionary<string, object> json)) return;
697
- var now = (int)(long)json["now"];
698
- GetProfile(accessToken, now);
699
-
700
- return;
701
- }
702
- catch (Exception)
703
- {
704
- // ignored
705
- }
706
- }
707
-
708
- OnCallback(UIManager.RESULT_FAILED, msg);
709
- GetUIManager().Pop();
710
- });
711
- }
712
-
713
- private static string GetAuthorizationHeader(string kid,
714
- string macKey,
715
- string macAlgorithm,
716
- string method,
717
- string uri,
718
- string host,
719
- string port,
720
- int timestamp)
721
- {
722
- var nonce = new Random().Next().ToString();
723
-
724
- var normalizedString = $"{timestamp}\n{nonce}\n{method}\n{uri}\n{host}\n{port}\n\n";
725
-
726
- HashAlgorithm hashGenerator;
727
- switch (macAlgorithm)
728
- {
729
- case "hmac-sha-256":
730
- hashGenerator = new HMACSHA256(Encoding.ASCII.GetBytes(macKey));
731
- break;
732
- case "hmac-sha-1":
733
- hashGenerator = new HMACSHA1(Encoding.ASCII.GetBytes(macKey));
734
- break;
735
- default:
736
- throw new InvalidOperationException("Unsupported MAC algorithm");
737
- }
738
-
739
- var hash = Convert.ToBase64String(hashGenerator.ComputeHash(Encoding.ASCII.GetBytes(normalizedString)));
740
-
741
- var authorizationHeader = new StringBuilder();
742
- authorizationHeader.AppendFormat(@"id=""{0}"",ts=""{1}"",nonce=""{2}"",mac=""{3}""",
743
- kid, timestamp, nonce, hash);
744
-
745
- return authorizationHeader.ToString();
746
- }
747
-
748
- private void ShowQrRefresh()
749
- {
750
- RefreshImage.gameObject.SetActive(true);
751
- SubStatusText.gameObject.SetActive(false);
752
- StatusText.gameObject.SetActive(false);
753
- }
754
-
755
- private void ShowStatus(string statusText, string subStatusText)
756
- {
757
- StatusText.text = statusText;
758
- SubStatusText.text = subStatusText;
759
- if (!string.IsNullOrEmpty(statusText))
760
- {
761
- StatusText.gameObject.SetActive(true);
762
- }
763
-
764
- if (!string.IsNullOrEmpty(subStatusText))
765
- {
766
- SubStatusText.gameObject.SetActive(true);
767
- }
768
- }
769
-
770
- private static long GetCurrentTime()
771
- {
772
- var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
773
- return Convert.ToInt64(ts.TotalSeconds);
774
- }
775
- }
776
- }
@@ -1,11 +0,0 @@
1
- fileFormatVersion: 2
2
- guid: 527cc8535a0b844679c3c21266399f04
3
- MonoImporter:
4
- externalObjects: {}
5
- serializedVersion: 2
6
- defaultReferences: []
7
- executionOrder: 0
8
- icon: {instanceID: 0}
9
- userData:
10
- assetBundleName:
11
- assetBundleVariant: