com.taptap.sdk.login 4.3.0-aplha.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.
Files changed (202) hide show
  1. package/Mobile/Editor/NativeDependencies.xml +20 -0
  2. package/Mobile/Editor/NativeDependencies.xml.meta +7 -0
  3. package/Mobile/Editor/TapLoginIOSProcessor.cs +91 -0
  4. package/Mobile/Editor/TapLoginIOSProcessor.cs.meta +11 -0
  5. package/Mobile/Editor/TapLoginMobileProcessBuild.cs +20 -0
  6. package/Mobile/Editor/TapLoginMobileProcessBuild.cs.meta +11 -0
  7. package/Mobile/Editor/TapSDK.Login.Mobile.Editor.asmdef +17 -0
  8. package/Mobile/Editor/TapSDK.Login.Mobile.Editor.asmdef.meta +7 -0
  9. package/Mobile/Editor.meta +8 -0
  10. package/Mobile/Runtime/AccountWrapper.cs +32 -0
  11. package/Mobile/Runtime/AccountWrapper.cs.meta +3 -0
  12. package/Mobile/Runtime/TapSDK.Login.Mobile.Runtime.asmdef +20 -0
  13. package/Mobile/Runtime/TapSDK.Login.Mobile.Runtime.asmdef.meta +7 -0
  14. package/Mobile/Runtime/TapTapLoginImpl.cs +81 -0
  15. package/Mobile/Runtime/TapTapLoginImpl.cs.meta +3 -0
  16. package/Mobile/Runtime.meta +8 -0
  17. package/Mobile.meta +8 -0
  18. package/Plugins/iOS/TapTapSDKLoginAppDelegate.mm +40 -0
  19. package/Plugins/iOS/TapTapSDKLoginAppDelegate.mm.meta +37 -0
  20. package/Plugins/iOS.meta +8 -0
  21. package/Plugins/zxing.unity.dll +0 -0
  22. package/Plugins/zxing.unity.dll.meta +33 -0
  23. package/Plugins.meta +8 -0
  24. package/Runtime/Internal/ITapTapLoginPlatform.cs +15 -0
  25. package/Runtime/Internal/ITapTapLoginPlatform.cs.meta +3 -0
  26. package/Runtime/Internal/Init/LoginInitTask.cs +20 -0
  27. package/Runtime/Internal/Init/LoginInitTask.cs.meta +11 -0
  28. package/Runtime/Internal/Init.meta +8 -0
  29. package/Runtime/Internal/Region.cs +98 -0
  30. package/Runtime/Internal/Region.cs.meta +11 -0
  31. package/Runtime/Internal/TapTapLoginManager.cs +38 -0
  32. package/Runtime/Internal/TapTapLoginManager.cs.meta +3 -0
  33. package/Runtime/Internal.meta +8 -0
  34. package/Runtime/Public/AccessToken.cs +83 -0
  35. package/Runtime/Public/AccessToken.cs.meta +11 -0
  36. package/Runtime/Public/Profile.cs +51 -0
  37. package/Runtime/Public/Profile.cs.meta +11 -0
  38. package/Runtime/Public/TapTapAccount.cs +70 -0
  39. package/Runtime/Public/TapTapAccount.cs.meta +3 -0
  40. package/Runtime/Public/TapTapLogin.cs +39 -0
  41. package/Runtime/Public/TapTapLogin.cs.meta +3 -0
  42. package/Runtime/Public/TapTapSdk.cs +26 -0
  43. package/Runtime/Public/TapTapSdk.cs.meta +11 -0
  44. package/Runtime/Public.meta +8 -0
  45. package/Runtime/TapSDK.Login.Runtime.asmdef +15 -0
  46. package/Runtime/TapSDK.Login.Runtime.asmdef.meta +7 -0
  47. package/Runtime.meta +8 -0
  48. package/Standalone/Editor/TapLoginStandaloneProcessBuild.cs +22 -0
  49. package/Standalone/Editor/TapLoginStandaloneProcessBuild.cs.meta +11 -0
  50. package/Standalone/Editor/TapSDK.Login.Standalone.Editor.asmdef +17 -0
  51. package/Standalone/Editor/TapSDK.Login.Standalone.Editor.asmdef.meta +7 -0
  52. package/Standalone/Editor.meta +8 -0
  53. package/Standalone/Resources/Prefabs/TapLogin/LoginPanel.prefab +811 -0
  54. package/Standalone/Resources/Prefabs/TapLogin/LoginPanel.prefab.meta +8 -0
  55. package/Standalone/Resources/Prefabs/TapLogin/LoginWithPermissionPanel.prefab +820 -0
  56. package/Standalone/Resources/Prefabs/TapLogin/LoginWithPermissionPanel.prefab.meta +8 -0
  57. package/Standalone/Resources/Prefabs/TapLogin/PermissionItem.prefab +314 -0
  58. package/Standalone/Resources/Prefabs/TapLogin/PermissionItem.prefab.meta +7 -0
  59. package/Standalone/Resources/Prefabs/TapLogin/QRCodeContainer.prefab +1501 -0
  60. package/Standalone/Resources/Prefabs/TapLogin/QRCodeContainer.prefab.meta +7 -0
  61. package/Standalone/Resources/Prefabs/TapLogin/Tips.prefab +286 -0
  62. package/Standalone/Resources/Prefabs/TapLogin/Tips.prefab.meta +7 -0
  63. package/Standalone/Resources/Prefabs/TapLogin/TopBar.prefab +485 -0
  64. package/Standalone/Resources/Prefabs/TapLogin/TopBar.prefab.meta +7 -0
  65. package/Standalone/Resources/Prefabs/TapLogin/WebContainer.prefab +514 -0
  66. package/Standalone/Resources/Prefabs/TapLogin/WebContainer.prefab.meta +7 -0
  67. package/Standalone/Resources/Prefabs/TapLogin/WebWithPermissionContainer.prefab +988 -0
  68. package/Standalone/Resources/Prefabs/TapLogin/WebWithPermissionContainer.prefab.meta +7 -0
  69. package/Standalone/Resources/Prefabs/TapLogin.meta +8 -0
  70. package/Standalone/Resources/Prefabs/TapTapSdkWindow.prefab +175 -0
  71. package/Standalone/Resources/Prefabs/TapTapSdkWindow.prefab.meta +8 -0
  72. package/Standalone/Resources/Prefabs.meta +8 -0
  73. package/Standalone/Resources/Sprites/taptap-client-bg.png +0 -0
  74. package/Standalone/Resources/Sprites/taptap-client-bg.png.meta +92 -0
  75. package/Standalone/Resources/Sprites/taptap-divider.png +0 -0
  76. package/Standalone/Resources/Sprites/taptap-divider.png.meta +146 -0
  77. package/Standalone/Resources/Sprites/taptap-login-android-client.png +0 -0
  78. package/Standalone/Resources/Sprites/taptap-login-android-client.png.meta +128 -0
  79. package/Standalone/Resources/Sprites/taptap-login-auth-bg.png +0 -0
  80. package/Standalone/Resources/Sprites/taptap-login-auth-bg.png.meta +128 -0
  81. package/Standalone/Resources/Sprites/taptap-login-auth-checked-v2.png +0 -0
  82. package/Standalone/Resources/Sprites/taptap-login-auth-checked-v2.png.meta +128 -0
  83. package/Standalone/Resources/Sprites/taptap-login-auth-checked.png +0 -0
  84. package/Standalone/Resources/Sprites/taptap-login-auth-checked.png.meta +128 -0
  85. package/Standalone/Resources/Sprites/taptap-login-auth-unchecked.png +0 -0
  86. package/Standalone/Resources/Sprites/taptap-login-auth-unchecked.png.meta +128 -0
  87. package/Standalone/Resources/Sprites/taptap-login-button-bg.png +0 -0
  88. package/Standalone/Resources/Sprites/taptap-login-button-bg.png.meta +128 -0
  89. package/Standalone/Resources/Sprites/taptap-login-confirm-triangle.png +0 -0
  90. package/Standalone/Resources/Sprites/taptap-login-confirm-triangle.png.meta +128 -0
  91. package/Standalone/Resources/Sprites/taptap-login-ios-client.png +0 -0
  92. package/Standalone/Resources/Sprites/taptap-login-ios-client.png.meta +128 -0
  93. package/Standalone/Resources/Sprites/taptap-login-tips-bg.png +0 -0
  94. package/Standalone/Resources/Sprites/taptap-login-tips-bg.png.meta +128 -0
  95. package/Standalone/Resources/Sprites/taptap-logo.png +0 -0
  96. package/Standalone/Resources/Sprites/taptap-logo.png.meta +130 -0
  97. package/Standalone/Resources/Sprites/taptap-scan-tips-bg.png +0 -0
  98. package/Standalone/Resources/Sprites/taptap-scan-tips-bg.png.meta +128 -0
  99. package/Standalone/Resources/Sprites/taptap-scan-tips-error.png +0 -0
  100. package/Standalone/Resources/Sprites/taptap-scan-tips-error.png.meta +128 -0
  101. package/Standalone/Resources/Sprites/taptap-scan-tips-info.png +0 -0
  102. package/Standalone/Resources/Sprites/taptap-scan-tips-info.png.meta +128 -0
  103. package/Standalone/Resources/Sprites/taptap-scan-tips-success.png +0 -0
  104. package/Standalone/Resources/Sprites/taptap-scan-tips-success.png.meta +128 -0
  105. package/Standalone/Resources/Sprites/taptap-scan-tips-warning.png +0 -0
  106. package/Standalone/Resources/Sprites/taptap-scan-tips-warning.png.meta +128 -0
  107. package/Standalone/Resources/Sprites/taptap-sdk-bg.png +0 -0
  108. package/Standalone/Resources/Sprites/taptap-sdk-bg.png.meta +128 -0
  109. package/Standalone/Resources/Sprites/taptap-sdk-cancel.png +0 -0
  110. package/Standalone/Resources/Sprites/taptap-sdk-cancel.png.meta +128 -0
  111. package/Standalone/Resources/Sprites/taptap-sdk-guide.png +0 -0
  112. package/Standalone/Resources/Sprites/taptap-sdk-guide.png.meta +128 -0
  113. package/Standalone/Resources/Sprites/taptap-sdk-logo.png +0 -0
  114. package/Standalone/Resources/Sprites/taptap-sdk-logo.png.meta +128 -0
  115. package/Standalone/Resources/Sprites/taptap-sdk-qrcode-bg-grey.png +0 -0
  116. package/Standalone/Resources/Sprites/taptap-sdk-qrcode-bg-grey.png.meta +128 -0
  117. package/Standalone/Resources/Sprites/taptap-sdk-qrcode-bg.png +0 -0
  118. package/Standalone/Resources/Sprites/taptap-sdk-qrcode-bg.png.meta +128 -0
  119. package/Standalone/Resources/Sprites/taptap-sdk-refresh-btn-bg.png +0 -0
  120. package/Standalone/Resources/Sprites/taptap-sdk-refresh-btn-bg.png.meta +128 -0
  121. package/Standalone/Resources/Sprites/taptap-sdk-refresh.png +0 -0
  122. package/Standalone/Resources/Sprites/taptap-sdk-refresh.png.meta +128 -0
  123. package/Standalone/Resources/Sprites/taptap-tap-log-v2.png +0 -0
  124. package/Standalone/Resources/Sprites/taptap-tap-log-v2.png.meta +128 -0
  125. package/Standalone/Resources/Sprites/taptap-tap-logo.png +0 -0
  126. package/Standalone/Resources/Sprites/taptap-tap-logo.png.meta +128 -0
  127. package/Standalone/Resources/Sprites/taptap-web-login-icon-v2.png +0 -0
  128. package/Standalone/Resources/Sprites/taptap-web-login-icon-v2.png.meta +128 -0
  129. package/Standalone/Resources/Sprites/taptap-web-login-icon.png +0 -0
  130. package/Standalone/Resources/Sprites/taptap-web-login-icon.png.meta +128 -0
  131. package/Standalone/Resources/Sprites/taptap-web-login.png +0 -0
  132. package/Standalone/Resources/Sprites/taptap-web-login.png.meta +146 -0
  133. package/Standalone/Resources/Sprites.meta +8 -0
  134. package/Standalone/Resources.meta +8 -0
  135. package/Standalone/Runtime/Internal/ContainerWindow.cs +67 -0
  136. package/Standalone/Runtime/Internal/ContainerWindow.cs.meta +11 -0
  137. package/Standalone/Runtime/Internal/LoginLanguage.cs +1117 -0
  138. package/Standalone/Runtime/Internal/LoginLanguage.cs.meta +11 -0
  139. package/Standalone/Runtime/Internal/Net.cs +291 -0
  140. package/Standalone/Runtime/Internal/Net.cs.meta +11 -0
  141. package/Standalone/Runtime/Internal/QRCodeWindow.cs +776 -0
  142. package/Standalone/Runtime/Internal/QRCodeWindow.cs.meta +11 -0
  143. package/Standalone/Runtime/Internal/UI.cs +22 -0
  144. package/Standalone/Runtime/Internal/UI.cs.meta +11 -0
  145. package/Standalone/Runtime/Internal/UIAnimator.cs +77 -0
  146. package/Standalone/Runtime/Internal/UIAnimator.cs.meta +11 -0
  147. package/Standalone/Runtime/Internal/UIBase.cs +27 -0
  148. package/Standalone/Runtime/Internal/UIBase.cs.meta +11 -0
  149. package/Standalone/Runtime/Internal/UIElement.cs +185 -0
  150. package/Standalone/Runtime/Internal/UIElement.cs.meta +11 -0
  151. package/Standalone/Runtime/Internal/UIManager.cs +100 -0
  152. package/Standalone/Runtime/Internal/UIManager.cs.meta +11 -0
  153. package/Standalone/Runtime/Internal/WebLoginRequestManager.cs +185 -0
  154. package/Standalone/Runtime/Internal/WebLoginRequestManager.cs.meta +11 -0
  155. package/Standalone/Runtime/Internal.meta +8 -0
  156. package/Standalone/Runtime/Internal2/AccountManager.cs +87 -0
  157. package/Standalone/Runtime/Internal2/AccountManager.cs.meta +3 -0
  158. package/Standalone/Runtime/Internal2/AuthorizationProviderImpl.cs +13 -0
  159. package/Standalone/Runtime/Internal2/AuthorizationProviderImpl.cs.meta +3 -0
  160. package/Standalone/Runtime/Internal2/Http/LoginHttpClient.cs +139 -0
  161. package/Standalone/Runtime/Internal2/Http/LoginHttpClient.cs.meta +11 -0
  162. package/Standalone/Runtime/Internal2/Http/Response/ErrorResponse.cs +16 -0
  163. package/Standalone/Runtime/Internal2/Http/Response/ErrorResponse.cs.meta +11 -0
  164. package/Standalone/Runtime/Internal2/Http/Response/ProfileResponse.cs +28 -0
  165. package/Standalone/Runtime/Internal2/Http/Response/ProfileResponse.cs.meta +11 -0
  166. package/Standalone/Runtime/Internal2/Http/Response/QRCodeResponse.cs +22 -0
  167. package/Standalone/Runtime/Internal2/Http/Response/QRCodeResponse.cs.meta +11 -0
  168. package/Standalone/Runtime/Internal2/Http/Response/TokenResponse.cs +33 -0
  169. package/Standalone/Runtime/Internal2/Http/Response/TokenResponse.cs.meta +11 -0
  170. package/Standalone/Runtime/Internal2/Http/Response.meta +8 -0
  171. package/Standalone/Runtime/Internal2/Http.meta +8 -0
  172. package/Standalone/Runtime/Internal2/LoginService.cs +127 -0
  173. package/Standalone/Runtime/Internal2/LoginService.cs.meta +11 -0
  174. package/Standalone/Runtime/Internal2/QRCodeUtils.cs +50 -0
  175. package/Standalone/Runtime/Internal2/QRCodeUtils.cs.meta +11 -0
  176. package/Standalone/Runtime/Internal2/TapLoginStandaloneImpl.cs +181 -0
  177. package/Standalone/Runtime/Internal2/TapLoginStandaloneImpl.cs.meta +3 -0
  178. package/Standalone/Runtime/Internal2/UI/ClientButtonListener.cs +20 -0
  179. package/Standalone/Runtime/Internal2/UI/ClientButtonListener.cs.meta +11 -0
  180. package/Standalone/Runtime/Internal2/UI/LoginPanelController.cs +72 -0
  181. package/Standalone/Runtime/Internal2/UI/LoginPanelController.cs.meta +11 -0
  182. package/Standalone/Runtime/Internal2/UI/QRCodeController.cs +180 -0
  183. package/Standalone/Runtime/Internal2/UI/QRCodeController.cs.meta +11 -0
  184. package/Standalone/Runtime/Internal2/UI/TitleController.cs +20 -0
  185. package/Standalone/Runtime/Internal2/UI/TitleController.cs.meta +11 -0
  186. package/Standalone/Runtime/Internal2/UI/WebController.cs +125 -0
  187. package/Standalone/Runtime/Internal2/UI/WebController.cs.meta +11 -0
  188. package/Standalone/Runtime/Internal2/UI.meta +8 -0
  189. package/Standalone/Runtime/Internal2.meta +8 -0
  190. package/Standalone/Runtime/Public/IAuthorizationProvider.cs +9 -0
  191. package/Standalone/Runtime/Public/IAuthorizationProvider.cs.meta +3 -0
  192. package/Standalone/Runtime/Public/IComplianceProvider.cs +7 -0
  193. package/Standalone/Runtime/Public/IComplianceProvider.cs.meta +3 -0
  194. package/Standalone/Runtime/Public/TapTapLoginStandalone.cs +38 -0
  195. package/Standalone/Runtime/Public/TapTapLoginStandalone.cs.meta +3 -0
  196. package/Standalone/Runtime/Public.meta +8 -0
  197. package/Standalone/Runtime/TapSDK.Login.Standalone.Runtime.asmdef +24 -0
  198. package/Standalone/Runtime/TapSDK.Login.Standalone.Runtime.asmdef.meta +7 -0
  199. package/Standalone/Runtime.meta +8 -0
  200. package/Standalone.meta +8 -0
  201. package/package.json +11 -0
  202. package/package.json.meta +7 -0
@@ -0,0 +1,776 @@
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
+ }