com.xd.sdk.account 7.3.3 → 7.6.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.
Files changed (37) hide show
  1. package/Editor/Android/XDAccountAndroidGradleProcessor.cs +35 -0
  2. package/Editor/Android/XDAccountAndroidGradleProcessor.cs.meta +11 -0
  3. package/{Plugins → Editor}/Android.meta +1 -1
  4. package/{Plugins/Android/libs.meta → Editor.meta} +1 -1
  5. package/Plugins/iOS/XDAccountSDK.framework/Headers/TDSGlobalThirdPartyLoginHelper.h +0 -17
  6. package/Plugins/iOS/XDAccountSDK.framework/Headers/XDGAccount.h +0 -2
  7. package/Plugins/iOS/XDAccountSDK.framework/Headers/XDGAccountVersion.h +3 -3
  8. package/Plugins/iOS/XDAccountSDK.framework/Info.plist +0 -0
  9. package/Plugins/iOS/XDAccountSDK.framework/XDAccountSDK +0 -0
  10. package/Runtime/Internal/Mobile/AccountFeaturesImpl.cs +2 -61
  11. package/Runtime/Internal/Standalone/AccessToken/AccessTokenModule.cs +1 -1
  12. package/Runtime/Internal/Standalone/AccountFeaturesImpl.cs +2 -2
  13. package/Runtime/Internal/Standalone/Auth/UrlSchemeAuth.cs +149 -0
  14. package/Runtime/Internal/Standalone/Auth/UrlSchemeAuth.cs.meta +11 -0
  15. package/Runtime/Internal/Standalone/Auth/WebAuth.cs +72 -29
  16. package/Runtime/Internal/Standalone/LoginModule/Email/EmailModule.cs +1 -1
  17. package/Runtime/Internal/Standalone/LoginModule/Phone/PhoneModule.cs +1 -1
  18. package/Runtime/Internal/Standalone/LoginModule/Phone/PhoneModuleIO.cs +1 -1
  19. package/Runtime/Internal/Standalone/SupportModule/SupportModule.cs +86 -44
  20. package/Runtime/Internal/Standalone/SupportModule/SupportResponse.cs +5 -2
  21. package/Runtime/Internal/Standalone/UI/CodeUnbindAlert.cs +1 -1
  22. package/Runtime/Internal/Standalone/UI/Email/EmailAlert.cs +1 -1
  23. package/Runtime/Internal/Standalone/UI/PhoneIO/AreaCodeCell.cs +1 -1
  24. package/Runtime/Internal/Standalone/UI/PhoneIO/PhoneAlertIO.cs +1 -1
  25. package/Runtime/Internal/Standalone/UI/PhoneVerification/RiskControlAlert.cs +2 -2
  26. package/Runtime/Internal/Standalone/UI/PhoneVerification/VerifyCodeInputAlert.cs +1 -1
  27. package/Runtime/Internal/Standalone/UserModule.cs +6 -6
  28. package/Runtime/Internal/Standalone/WebFunction/GetUserInfoWebFunction.cs +62 -0
  29. package/Runtime/Internal/Standalone/WebFunction/GetUserInfoWebFunction.cs.meta +11 -0
  30. package/package.json +3 -3
  31. package/Plugins/Android/libs/XDGAccount_7.3.3.aar +0 -0
  32. package/Plugins/Android/libs/XDGAccount_7.3.3.aar.meta +0 -32
  33. package/Plugins/Android/libs/XDGBridgeAccount_v7_7.3.3.aar +0 -0
  34. package/Plugins/Android/libs/XDGBridgeAccount_v7_7.3.3.aar.meta +0 -32
  35. package/Plugins/Android/libs/XDGSupport_7.3.3.aar +0 -0
  36. package/Plugins/Android/libs/XDGSupport_7.3.3.aar.meta +0 -32
  37. package/Runtime/Internal/Mobile/Http/LoginSyncResponse.cs +0 -14
@@ -0,0 +1,35 @@
1
+ using System.Collections.Generic;
2
+ using XD.SDK.Foundation.Mobile.Editor;
3
+ using XD.SDK.Foundation.Mobile.Editor.Android;
4
+
5
+ namespace XD.SDK.Account.Editor
6
+ {
7
+ public class XDAccountAndroidGradleProcessor : XDAndroidProjectProcessor
8
+ {
9
+ protected override List<AndroidGradleProjectConfig.Dependency> GenerateDependencies()
10
+ {
11
+ var sdkVersion = VersionCatalog.XDAndroidSdkVersion;
12
+ var result = new List<AndroidGradleProjectConfig.Dependency>
13
+ {
14
+ new AndroidGradleProjectConfig.Dependency(group: "com.xd.sdk.android", module: "account-bridge",
15
+ version: sdkVersion),
16
+ new AndroidGradleProjectConfig.Dependency(group: "com.xd.sdk.android", module: "support",
17
+ version: sdkVersion),
18
+ };
19
+
20
+ var regionType = configModel?.region_type;
21
+ if (string.Equals(regionType, "global", System.StringComparison.OrdinalIgnoreCase))
22
+ {
23
+ result.Add(new AndroidGradleProjectConfig.Dependency(group: "com.xd.sdk.android", module: "account-global",
24
+ version: sdkVersion));
25
+ }
26
+ else if (string.Equals(regionType, "cn", System.StringComparison.OrdinalIgnoreCase))
27
+ {
28
+ result.Add(new AndroidGradleProjectConfig.Dependency(group: "com.xd.sdk.android", module: "account-cn",
29
+ version: sdkVersion));
30
+ }
31
+
32
+ return result;
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: e385e136493a8410a9bb62ea591d2d5b
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,5 +1,5 @@
1
1
  fileFormatVersion: 2
2
- guid: 58732c81d2494ed99ea8503943c66921
2
+ guid: 906fa2426dfff47beb86c6feccd9c891
3
3
  folderAsset: yes
4
4
  DefaultImporter:
5
5
  externalObjects: {}
@@ -1,5 +1,5 @@
1
1
  fileFormatVersion: 2
2
- guid: 0e8d623d5ea147b3807cebee8455ab6a
2
+ guid: fedd6c2bb601f46939a148ef7ac45497
3
3
  folderAsset: yes
4
4
  DefaultImporter:
5
5
  externalObjects: {}
@@ -16,23 +16,6 @@ typedef void(^TDSGlobalAuthCancelCallback)(void);
16
16
  typedef void(^TDSGlobalAuthWatingCallback)(void);
17
17
  typedef void(^TDSGlobalAuthErrorCallback)(NSError *_Nullable error);
18
18
 
19
- // 后台登录方式枚举
20
- typedef NS_ENUM(NSInteger,XDGLoginInfoType) {
21
- XDGLoginInfoTypeGuest = 0,
22
- XDGLoginInfoTypeWeChat,
23
- XDGLoginInfoTypeApple,
24
- XDGLoginInfoTypeGoogle,
25
- XDGLoginInfoTypeFacebook,
26
- XDGLoginInfoTypeTapTap,
27
- XDGLoginInfoTypeLine,
28
- XDGLoginInfoTypeTwitter,
29
- XDGLoginInfoTypeQQ,
30
- XDGLoginInfoTypeTwitch,
31
- XDGLoginInfoTypeSteam,
32
- XDGLoginInfoTypePhone,
33
- XDGLoginInfoTypeEmail,
34
- };
35
-
36
19
  @interface TDSGlobalThirdPartyLoginHelper : NSObject
37
20
 
38
21
  + (void)authByType:(LoginEntryType)authType
@@ -54,8 +54,6 @@ NS_ASSUME_NONNULL_BEGIN
54
54
  /// @param handler 绑定结果回调
55
55
  + (void)bindByType:(LoginEntryType)bindType bindHandler:(XDGBindManagerRequestCallback)handler DEPRECATED_MSG_ATTRIBUTE("未来可能会废弃,使用该接口请和平台同事确认需求");
56
56
 
57
- + (BOOL)isTokenActiveWithType:(LoginEntryType)type;
58
-
59
57
  @end
60
58
 
61
59
  NS_ASSUME_NONNULL_END
@@ -4,6 +4,6 @@
4
4
  //
5
5
  // Created by Fattycat on 2023/4/14.
6
6
  //
7
- #define XDGAccount_VERSION @"7.3.1"
8
- #define XDSAccount_VERSION_CODE @"7030100"
9
- // HASH e51483ce
7
+ #define XDGAccount_VERSION @"7.6.0"
8
+ #define XDSAccount_VERSION_CODE @"7060000"
9
+ // HASH 2fd78d92
@@ -6,12 +6,9 @@ using System.Runtime.InteropServices;
6
6
  using System.Threading.Tasks;
7
7
  using Newtonsoft.Json;
8
8
  using UnityEngine;
9
- using XD.SDK.Account.Internal.Http;
10
9
  using XD.SDK.Common;
11
10
  using XD.SDK.Common.Internal;
12
11
  using XD.SDK.Common.Internal.Events;
13
- using XD.SDK.Common.Internal.Http;
14
- using XD.SDK.Common.Internal.Mobile;
15
12
  using XD.SDK.Common.Internal.Mobile.Bridge;
16
13
 
17
14
  namespace XD.SDK.Account.Internal.Mobile
@@ -22,27 +19,6 @@ namespace XD.SDK.Account.Internal.Mobile
22
19
 
23
20
  private static readonly object LockObj = new object();
24
21
 
25
- private const string LoginSynUrl = "/api/login/v1/syn";
26
-
27
- private readonly Lazy<IHttpClient> defaultClient = new Lazy<IHttpClient>(() =>
28
- XDHttpClientFactory.GetClient(nameof(AccountFeaturesImpl),
29
- () =>
30
- {
31
- return XDHttpClientFactory.CreateClient(XDGHost.CreateBaseHost(XDGCommonInternal.IsCn()), builder =>
32
- {
33
- builder
34
- .Timeout(TimeSpan.FromSeconds(10))
35
- .WithLogging()
36
- .AddInterceptor(new CommonParamsInterceptor())
37
- .AddInterceptor(new UrlBuildInterceptor())
38
- .AddInterceptor(new MacAuthenticationInterceptor())
39
- .Build();
40
- });
41
- })
42
- );
43
-
44
- private IHttpClient HttpClient => defaultClient.Value;
45
-
46
22
  public static AccountFeaturesImpl Instance
47
23
  {
48
24
  get
@@ -101,7 +77,7 @@ namespace XD.SDK.Account.Internal.Mobile
101
77
  .OnceTime(true)
102
78
  .CommandBuilder();
103
79
 
104
- EngineBridge.GetInstance().CallHandler(command, async result =>
80
+ EngineBridge.GetInstance().CallHandler(command, result =>
105
81
  {
106
82
  var xdgError = result.Parse2XDGError();
107
83
  if (xdgError != null)
@@ -115,7 +91,6 @@ namespace XD.SDK.Account.Internal.Mobile
115
91
  if (userDic != null)
116
92
  {
117
93
  var user = new XDGUser(userDic);
118
- await SyncTdsUser(user);
119
94
  if (loginType == LoginType.Default)
120
95
  {
121
96
  RefreshFacebookToken();
@@ -288,40 +263,6 @@ namespace XD.SDK.Account.Internal.Mobile
288
263
  private static extern IntPtr XDAccountBridgeGetAuthorization(string url, string method, long timestamp);
289
264
  #endif
290
265
 
291
- private async Task SyncTdsUser(XDGUser user)
292
- {
293
- var bHasTdsUser = ReflectionUtils.FindType("TapTap.Bootstrap.TDSUser", "XD.SDK.TDSWrapper") != null;
294
- if (!bHasTdsUser)
295
- {
296
- return;
297
- }
298
-
299
- try
300
- {
301
- var result = await XDGEventBus.PublishAsync<Dictionary<string, object>>(XDGEvents.TdsSDKGetUser);
302
- var objectId = XDDictionary.GetValue<string>(result.GetValueOrThrow(), "objectId");
303
- if (objectId == user.UserId)
304
- {
305
- return;
306
- }
307
-
308
- XDGEventBus.Publish(XDGEvents.TdsSDKLogout);
309
- var response = await HttpClient.PostAsync<LoginSyncResponse>(LoginSynUrl);
310
- var sessionToken = XDDictionary.GetValue<string>(response.Data, "sessionToken");
311
- if (string.IsNullOrEmpty(sessionToken))
312
- {
313
- XDGLogger.Warn("[SyncTDSUser] sessionToken is Null!", XDGLoggerTag.Bridge);
314
- return;
315
- }
316
-
317
- XDGEventBus.Publish(XDGEvents.TdsSDKSyncUser, sessionToken, user.UserId);
318
- }
319
- catch (XDGError e)
320
- {
321
- XDGLogger.Warn($"[SyncTDSUser] error:{e.ErrorMsg}", XDGLoggerTag.Bridge);
322
- }
323
- }
324
-
325
266
  private void RefreshFacebookToken()
326
267
  {
327
268
  #if UNITY_ANDROID
@@ -344,4 +285,4 @@ namespace XD.SDK.Account.Internal.Mobile
344
285
  }
345
286
  }
346
287
 
347
- #endif
288
+ #endif
@@ -116,7 +116,7 @@ namespace XD.SDK.Account.Internal.Standalone
116
116
  if (xdException.Code == ResponseCode.Account.TokenExpired || xdException.HttpStatusCode == 401)
117
117
  errorMsg = "XD_TOKEN_EXPIRED";
118
118
  // 触发风控以及登陆频繁不需要发送 PreFail
119
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
119
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
120
120
  if (xdException.Code != PhoneModule.INVALID_VERIFY_CODE &&
121
121
  xdException.Code != PhoneModule.LOGIN_REQUEST_FREQUENTLY)
122
122
  {
@@ -117,7 +117,7 @@ namespace XD.SDK.Account.Internal.Standalone
117
117
 
118
118
  public async void OpenUserDashboard(XDGRoleInfo roleInfo)
119
119
  {
120
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
120
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
121
121
  try
122
122
  {
123
123
  if (!XDGCommonInternal.IsCn())
@@ -331,7 +331,7 @@ namespace XD.SDK.Account.Internal.Standalone
331
331
 
332
332
  private async Task CancelAccount()
333
333
  {
334
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
334
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
335
335
  var current = UserModule.current;
336
336
  if (current == null)
337
337
  {
@@ -0,0 +1,149 @@
1
+ #if UNITY_EDITOR || UNITY_STANDALONE
2
+ using System;
3
+ using System.Collections.Generic;
4
+ using System.Net;
5
+ using System.Threading;
6
+ using System.Threading.Tasks;
7
+ using UnityEngine;
8
+ using XD.SDK.Common;
9
+ using XD.SDK.Common.Internal;
10
+ using XD.SDK.Common.Internal.Standalone;
11
+
12
+ namespace XD.SDK.Account.Internal.Standalone
13
+ {
14
+ internal static class UrlSchemeAuth
15
+ {
16
+ internal const string RedirectSchemeKey = "redirect_scheme";
17
+
18
+ private const string DefaultUrlSchemePath = "oauth";
19
+
20
+ private const string StateKey = "state";
21
+
22
+ internal static string TryGetRedirectScheme()
23
+ {
24
+ #if UNITY_STANDALONE_WIN && !UNITY_EDITOR
25
+ var scheme = StandaloneDeeplinkRegistrar.TryGetSchemeForCurrentGame();
26
+ if (string.IsNullOrEmpty(scheme))
27
+ {
28
+ return null;
29
+ }
30
+ return $"{scheme}://{DefaultUrlSchemePath}";
31
+ #else
32
+ return null;
33
+ #endif
34
+ }
35
+
36
+ internal static async Task<Dictionary<string, object>> WaitForFirstCallbackAsync(
37
+ List<HttpListener> servers,
38
+ LoginType loginType,
39
+ string state,
40
+ Func<Task<Dictionary<string, object>>> httpFallback)
41
+ {
42
+ if (string.IsNullOrEmpty(state))
43
+ {
44
+ // state 缺失时无法做会话隔离:直接走 http
45
+ return httpFallback != null
46
+ ? await httpFallback()
47
+ : new Dictionary<string, object> { { "type", (int)loginType } };
48
+ }
49
+
50
+ var deepLinkTcs = new TaskCompletionSource<Dictionary<string, object>>(
51
+ TaskCreationOptions.RunContinuationsAsynchronously);
52
+ var cleaned = 0;
53
+
54
+ void StopAllListeners()
55
+ {
56
+ try
57
+ {
58
+ foreach (var svr in servers)
59
+ {
60
+ svr.Stop();
61
+ }
62
+ servers.Clear();
63
+ }
64
+ catch
65
+ {
66
+ // ignore
67
+ }
68
+ }
69
+
70
+ #if UNITY_STANDALONE_WIN && !UNITY_EDITOR
71
+ Action<string> onDeepLink = deepLinkUrl =>
72
+ {
73
+ if (string.IsNullOrEmpty(deepLinkUrl)) return;
74
+
75
+ XDGLogger.Debug($"[Auth][DeepLink] url: {deepLinkUrl}", XDGLoggerTag.Account);
76
+
77
+ // 不用 new Uri(),直接截取 query,避免 Uri 对自定义 scheme 做编码归一化
78
+ int qIdx = deepLinkUrl.IndexOf('?');
79
+ if (qIdx < 0 || qIdx >= deepLinkUrl.Length - 1) return;
80
+
81
+ int fragIdx = deepLinkUrl.IndexOf('#', qIdx);
82
+ string query = fragIdx >= 0
83
+ ? deepLinkUrl.Substring(qIdx + 1, fragIdx - qIdx - 1)
84
+ : deepLinkUrl.Substring(qIdx + 1);
85
+
86
+ if (string.IsNullOrEmpty(query)) return;
87
+
88
+ var parsed = WebAuth.ParseQueryStringToDict(query);
89
+ var authData = new Dictionary<string, object> { { "type", (int)loginType } };
90
+ foreach (var kv in parsed) authData[kv.Key] = kv.Value;
91
+
92
+ if (!authData.TryGetValue(StateKey, out object st) || (st?.ToString() != state))
93
+ {
94
+ XDGLogger.Debug($"[Auth][DeepLink] state mismatch, expected: {state}, got: {st}", XDGLoggerTag.Account);
95
+ return;
96
+ }
97
+ AliyunTrack.LoginAuthorizeSuccess();
98
+ deepLinkTcs.TrySetResult(authData);
99
+ };
100
+
101
+ StandaloneDeepLinkReceiver.OnDeepLinkReceived += onDeepLink;
102
+ #endif
103
+
104
+ var httpTask = httpFallback != null
105
+ ? httpFallback()
106
+ : Task.FromResult(new Dictionary<string, object> { { "type", (int)loginType } });
107
+
108
+ var timeout = Task.Delay(TimeSpan.FromMinutes(2));
109
+ var done = await Task.WhenAny(deepLinkTcs.Task, httpTask, timeout);
110
+
111
+ try
112
+ {
113
+ if (done == deepLinkTcs.Task)
114
+ {
115
+ XDGLogger.Debug("[Auth] DeepLink auth succeeded (won race)", XDGLoggerTag.Account);
116
+ StopAllListeners();
117
+ return await deepLinkTcs.Task;
118
+ }
119
+
120
+ if (done == httpTask)
121
+ {
122
+ XDGLogger.Debug("[Auth] HTTP auth succeeded (won race)", XDGLoggerTag.Account);
123
+ return await httpTask;
124
+ }
125
+
126
+ XDGLogger.Debug("[Auth] Auth timeout (2min)", XDGLoggerTag.Account);
127
+ StopAllListeners();
128
+ return new Dictionary<string, object> { { "type", (int)loginType } };
129
+ }
130
+ finally
131
+ {
132
+ if (Interlocked.CompareExchange(ref cleaned, 1, 0) == 0)
133
+ {
134
+ #if UNITY_STANDALONE_WIN && !UNITY_EDITOR
135
+ try
136
+ {
137
+ StandaloneDeepLinkReceiver.OnDeepLinkReceived -= onDeepLink;
138
+ }
139
+ catch
140
+ {
141
+ // ignore
142
+ }
143
+ #endif
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+ #endif
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: d926b2f11657440ac90e85bdf06eb13f
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -1,8 +1,8 @@
1
1
  #if UNITY_EDITOR || UNITY_STANDALONE
2
2
  using System;
3
3
  using System.Collections.Generic;
4
- using System.Linq;
5
4
  using System.Net;
5
+ using System.Threading;
6
6
  using System.Threading.Tasks;
7
7
  using UnityEngine;
8
8
  using XD.SDK.Common;
@@ -14,6 +14,28 @@ namespace XD.SDK.Account.Internal.Standalone
14
14
  {
15
15
  public class WebAuth
16
16
  {
17
+ private const string StateKey = "state";
18
+
19
+ internal static Dictionary<string, object> ParseQueryStringToDict(string queryString)
20
+ {
21
+ var result = new Dictionary<string, object>();
22
+ if (string.IsNullOrEmpty(queryString)) return result;
23
+
24
+ foreach (var pair in queryString.Split('&'))
25
+ {
26
+ if (string.IsNullOrEmpty(pair)) continue;
27
+ var idx = pair.IndexOf('=');
28
+ if (idx <= 0 || idx >= pair.Length - 1) continue;
29
+
30
+ var key = pair.Substring(0, idx);
31
+ // 用 UnescapeDataString 而非 WebUtility.UrlDecode(后者会把 + 当空格)
32
+ var value = Uri.UnescapeDataString(pair.Substring(idx + 1));
33
+ result[key] = value;
34
+ }
35
+
36
+ return result;
37
+ }
38
+
17
39
  protected static async Task<Dictionary<string, object>> StartListener(List<HttpListener> servers,
18
40
  LoginType loginType,
19
41
  Dictionary<string, object> queryParams)
@@ -23,6 +45,8 @@ namespace XD.SDK.Account.Internal.Standalone
23
45
  string lang = XDLocalization.GetLanguageKey();
24
46
 
25
47
  string url = ConfigModule.IsGlobal ? AuthConstants.GLOBAL_AUTH_HOST : AuthConstants.CN_AUTH_HOST;
48
+ string state = null;
49
+ string urlSchemeRedirect = UrlSchemeAuth.TryGetRedirectScheme();
26
50
  Dictionary<string, object> queryParameters = new Dictionary<string, object>
27
51
  {
28
52
  { "redirect_uri", redirectUri },
@@ -52,14 +76,30 @@ namespace XD.SDK.Account.Internal.Standalone
52
76
  }
53
77
  }
54
78
 
55
- IEnumerable<string> queryPairs = queryParameters.Select(kv => $"{kv.Key}={kv.Value}");
56
- string authRequest = $"{url}?{string.Join("&", queryPairs)}";
79
+ // 约定:外部必传 state(SDK 不再自动生成)
80
+ if (queryParameters.TryGetValue(StateKey, out object existingState))
81
+ {
82
+ state = existingState?.ToString();
83
+ }
84
+
85
+ // UrlScheme 主通道:Web 收到该参数后可在登录成功时主动唤起 UrlScheme 回传 token/code
86
+ if (!string.IsNullOrEmpty(urlSchemeRedirect))
87
+ {
88
+ queryParameters[UrlSchemeAuth.RedirectSchemeKey] = urlSchemeRedirect;
89
+ }
90
+
91
+ // 注意:redirect_scheme 的值包含 ://,必须单独对 query 做编码,否则 authRequest 会被破坏
92
+ string authRequest = $"{url}?{XDUrlUtils.ToQueryString(queryParameters)}";
57
93
 
58
94
  // 弹出授权页
59
- XDGLogger.Debug($"auth: {authRequest}", XDGLoggerTag.Account);
95
+ XDGLogger.Debug($"[Auth] url: {url}", XDGLoggerTag.Account);
96
+ XDGLogger.Debug($"[Auth] state: {state}", XDGLoggerTag.Account);
97
+ XDGLogger.Debug($"[Auth] urlSchemeRedirect: {urlSchemeRedirect}", XDGLoggerTag.Account);
98
+ XDGLogger.Debug($"[Auth] redirectUri(http): {redirectUri}", XDGLoggerTag.Account);
99
+ XDGLogger.Debug($"[Auth] authRequest: {authRequest}", XDGLoggerTag.Account);
60
100
  AliyunTrack.LoginAuthorize();
61
- // 登陆跳转授权 Track
62
- Application.OpenURL(Uri.EscapeUriString(authRequest));
101
+ // authRequest 的 query 已经过 XDUrlUtils.ToQueryString 编码,避免二次转义导致参数异常
102
+ Application.OpenURL(authRequest);
63
103
 
64
104
  // 启动监听
65
105
  HttpListener server = new HttpListener();
@@ -68,6 +108,25 @@ namespace XD.SDK.Account.Internal.Standalone
68
108
 
69
109
  servers.Add(server);
70
110
 
111
+ // UrlScheme 竞速需要同时满足:平台支持 + scheme 可用 + state 存在(用于会话隔离)
112
+ // state 为空时直接走 HttpListener 兜底(UrlSchemeAuth 内部也会检查并回退)
113
+ Task<Dictionary<string, object>> HttpFallback()
114
+ {
115
+ return WaitForHttpCallbackAsync(servers, server, loginType);
116
+ }
117
+
118
+ return await UrlSchemeAuth.WaitForFirstCallbackAsync(
119
+ servers,
120
+ loginType,
121
+ state,
122
+ HttpFallback);
123
+ }
124
+
125
+ private static async Task<Dictionary<string, object>> WaitForHttpCallbackAsync(
126
+ List<HttpListener> servers,
127
+ HttpListener server,
128
+ LoginType loginType)
129
+ {
71
130
  Dictionary<string, object> authData = new Dictionary<string, object>
72
131
  {
73
132
  { "type", (int)loginType }
@@ -97,45 +156,29 @@ namespace XD.SDK.Account.Internal.Standalone
97
156
 
98
157
  servers.Clear();
99
158
 
100
- // 解析 Web 像 SDK 传递的参数
101
159
  string[] urlSegments = context.Request.RawUrl.Split('?');
102
160
  if (urlSegments.Length < 2)
103
161
  {
104
- return new Dictionary<string, object>();
162
+ return authData;
105
163
  }
106
164
 
107
- string queryString = urlSegments[1];
108
- string[] queries = queryString.Split('&');
109
-
110
- foreach (string query in queries)
165
+ var dict = ParseQueryStringToDict(urlSegments[1]);
166
+ foreach (var kv in dict)
111
167
  {
112
- if (string.IsNullOrEmpty(query))
113
- {
114
- continue;
115
- }
116
-
117
- string[] kv = query.Split('=');
118
- if (kv.Length < 2)
119
- {
120
- continue;
121
- }
122
-
123
- authData[kv[0]] = kv[1];
168
+ authData[kv.Key] = kv.Value;
124
169
  }
125
170
 
126
- // 登陆授权成功
127
171
  AliyunTrack.LoginAuthorizeSuccess();
128
172
  return authData;
129
173
  }
130
174
  catch (Exception e)
131
175
  {
132
176
  XDGLogger.Debug(e.Message, XDGLoggerTag.Account);
133
- // 异常结果则一直 pending
134
- // 登陆授权失败
177
+ // 异常结果则一直 pending(保持原行为)
135
178
  AliyunTrack.LoginAuthorizeFail(e.Message);
136
- TaskCompletionSource<Dictionary<string, object>> tcs =
179
+ TaskCompletionSource<Dictionary<string, object>> pending_tcs =
137
180
  new TaskCompletionSource<Dictionary<string, object>>();
138
- return await tcs.Task;
181
+ return await pending_tcs.Task;
139
182
  }
140
183
  }
141
184
  }
@@ -1,4 +1,4 @@
1
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
1
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
2
2
  using System;
3
3
  using System.Collections.Generic;
4
4
  using System.Threading.Tasks;
@@ -1,4 +1,4 @@
1
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
1
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
2
2
  using System;
3
3
  using System.Collections.Generic;
4
4
  using System.Threading.Tasks;
@@ -1,4 +1,4 @@
1
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
1
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
2
2
  using System;
3
3
  using System.Collections.Generic;
4
4
  using System.Threading.Tasks;
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
7
7
  using Newtonsoft.Json;
8
8
  using UnityEngine;
9
9
  using XD.SDK.Common;
10
+ using XD.SDK.Common.Internal;
10
11
  using XD.SDK.Common.Internal.Standalone;
11
12
 
12
13
  namespace XD.SDK.Account.Internal.Standalone
@@ -49,9 +50,9 @@ namespace XD.SDK.Account.Internal.Standalone
49
50
  XDGLogger.Debug("XSupportManager is disabled by config, skipping polling start", XDGLoggerTag.Support);
50
51
  }
51
52
 
52
- private const string XdgSupportUserUnreadCheck = "api/support/v1/user/unread/check";
53
+ private const string XdgSupportUserUnreadCheck = "api/support/v2/user/unread/check";
53
54
 
54
- private const string XdgSupportAnonymousUnreadCheck = "api/support/v1/user/anonymous/unread/check";
55
+ private const string XdgSupportAnonymousUnreadCheck = "api/support/v2/user/anonymous/unread/check";
55
56
 
56
57
  private const string XdgSupportUserGetURL = "api/support/v1/user/url/get";
57
58
 
@@ -74,8 +75,11 @@ namespace XD.SDK.Account.Internal.Standalone
74
75
 
75
76
  if (xd)
76
77
  {
77
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
78
- WebRequest.OpenWebPage(url, (code, data) => { });
78
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
79
+ WebRequest.OpenWebPage(url, (code, data) =>
80
+ {
81
+
82
+ });
79
83
  #else
80
84
  Application.OpenURL(url);
81
85
  #endif
@@ -89,49 +93,99 @@ namespace XD.SDK.Account.Internal.Standalone
89
93
 
90
94
  private static async void CheckUnRead()
91
95
  {
96
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
92
97
  XDGLogger.Debug("Support check unread", XDGLoggerTag.Support);
93
98
  try
94
99
  {
95
- string requestUrl;
96
- Dictionary<string, object> queryMap;
97
- if (UserModule.GetCurrentUser() != null)
98
- {
99
- requestUrl = XdgSupportUserUnreadCheck;
100
- queryMap = null;
101
- }
102
- else
103
- {
104
- requestUrl = XdgSupportAnonymousUnreadCheck;
105
- queryMap = new Dictionary<string, object>()
100
+ var loggedIn = UserModule.GetCurrentUser() != null;
101
+ var requestUrl = loggedIn ? XdgSupportUserUnreadCheck : XdgSupportAnonymousUnreadCheck;
102
+ var queryMap = loggedIn
103
+ ? null
104
+ : new Dictionary<string, object>
106
105
  {
107
106
  { "anonymousId", SystemInfo.deviceUniqueIdentifier }
108
107
  };
109
- }
110
108
 
111
109
  var response = await XDHttpClient.Client.GetAsync<SupportBaseResponse<SupportUnReadResponse>>(
112
110
  requestUrl, null, queryMap);
113
111
 
114
- var bHasUnRead = response.Data.HasUnread;
115
- var bUnReadStatusChange = bHasUnRead != Instance.bLastHasRead;
116
- Instance.bLastHasRead = bHasUnRead;
117
- var nextTimeInterval = bUnReadStatusChange ? 10 : IncreaseTimeInterval();
118
- Instance.nextCheckUnreadTime = response.Data.IntervalSec > 0 ? response.Data.IntervalSec : nextTimeInterval;
119
- XDGLogger.Debug($"Support Check UnRead Success, hasUnread:{response.Data.HasUnread} interval:{response.Data.IntervalSec}", XDGLoggerTag.Support);
120
- if (bUnReadStatusChange)
112
+ var type = response.Data?.Type?.ToLowerInvariant();
113
+ if (type == "lc")
121
114
  {
122
- AccountFeaturesImpl.Instance.GetUserStatusCallback()
123
- .Invoke(response.Data.HasUnread ? XDGUserStatusCodeType.SupportHasUnRead : XDGUserStatusCodeType.SupportNoUnRead, null);
115
+ var innerData = response.Data?.Lc;
116
+ if (innerData == null || innerData.Count == 0)
117
+ {
118
+ HandleUnreadFail("server data is nil");
119
+ return;
120
+ }
121
+ HandleUnreadData(innerData);
122
+ }
123
+ else if (type == "pn")
124
+ {
125
+ var innerData = response.Data?.Pn;
126
+ var targetUrl = innerData != null && innerData.TryGetValue("targetUrl", out var u) ? u as string : null;
127
+ if (string.IsNullOrEmpty(targetUrl))
128
+ {
129
+ HandleUnreadFail("targetUrl is empty");
130
+ return;
131
+ }
132
+
133
+ XDGLogger.Debug($"Support check unread success, targetUrl:{targetUrl}", XDGLoggerTag.Support);
134
+ WebRequest.OpenWebPage(targetUrl, (action, data) =>
135
+ {
136
+ if (action != WebActionEnum.CLOSE) return;
137
+ if (data == null || data.Count == 0)
138
+ {
139
+ HandleUnreadFail("web data is null");
140
+ return;
141
+ }
142
+ HandleUnreadData(data);
143
+ });
144
+ }
145
+ else
146
+ {
147
+ HandleUnreadFail("server empty");
124
148
  }
125
149
  }
126
150
  catch (XDGError e)
127
151
  {
128
- UIManager.ShowToast(e.ErrorMsg);
129
- Instance.nextCheckUnreadTime = IncreaseTimeInterval();
152
+ HandleUnreadFail(e.ErrorMsg);
153
+ }
154
+ #else
155
+ XDGLogger.Debug("Support check unread skipped: vuplex disabled", XDGLoggerTag.Support);
156
+ #endif
157
+ }
158
+
159
+ private static void HandleUnreadData(Dictionary<string, object> data)
160
+ {
161
+ var currentUnread = Instance.bLastHasRead;
162
+ var hasUnread = data.TryGetValue("hasUnread", out var hu) && hu is bool b ? b : currentUnread;
163
+ var webInterval = data.TryGetValue("intervalSec", out var iv) ? Convert.ToInt32(iv) : 0;
164
+
165
+ var unreadChanged = hasUnread != currentUnread;
166
+ Instance.bLastHasRead = hasUnread;
167
+ Instance.nextCheckUnreadTime = webInterval > 0
168
+ ? webInterval
169
+ : (unreadChanged ? 10 : IncreaseTimeInterval());
170
+
171
+ XDGLogger.Debug($"Support probe unread success, hasUnread:{hasUnread} nextCheckInterval:{Instance.nextCheckUnreadTime}", XDGLoggerTag.Support);
172
+
173
+ if (unreadChanged)
174
+ {
175
+ AccountFeaturesImpl.Instance.GetUserStatusCallback()
176
+ .Invoke(hasUnread ? XDGUserStatusCodeType.SupportHasUnRead : XDGUserStatusCodeType.SupportNoUnRead, null);
130
177
  }
131
178
 
132
179
  StartCheckUnRead();
133
180
  }
134
181
 
182
+ private static void HandleUnreadFail(string reason)
183
+ {
184
+ Instance.nextCheckUnreadTime = IncreaseTimeInterval();
185
+ XDGLogger.Warn($"Support check unread failed, nextCheckInterval:{Instance.nextCheckUnreadTime} reason:{reason}", XDGLoggerTag.Support);
186
+ StartCheckUnRead();
187
+ }
188
+
135
189
  private static int IncreaseTimeInterval()
136
190
  {
137
191
  var currentInterval = Instance.nextCheckUnreadTime;
@@ -179,27 +233,15 @@ namespace XD.SDK.Account.Internal.Standalone
179
233
  path = path ?? "";
180
234
  extra = extra ?? new Dictionary<string, object>();
181
235
 
182
- // 构建 URL-encoded 查询串(更简洁)
183
- string Enc(string s)
184
- {
185
- return Uri.EscapeDataString(s ?? string.Empty);
186
- }
187
-
188
- var parts = new List<string>();
189
-
236
+ var paramsObj = new Dictionary<string, object>(extra);
190
237
  if (roleInfo != null)
191
238
  {
192
- if (!string.IsNullOrEmpty(roleInfo.RoleId)) parts.Add($"{Enc("role_id")}={Enc(roleInfo.RoleId)}");
193
- if (!string.IsNullOrEmpty(roleInfo.RoleName)) parts.Add($"{Enc("role_name")}={Enc(roleInfo.RoleName)}");
194
- if (!string.IsNullOrEmpty(roleInfo.ServerId)) parts.Add($"{Enc("server_id")}={Enc(roleInfo.ServerId)}");
195
- }
196
-
197
- foreach (var kv in extra)
198
- {
199
- parts.Add($"{Enc(kv.Key)}={Enc(kv.Value != null ? kv.Value.ToString() : string.Empty)}");
239
+ if (!string.IsNullOrEmpty(roleInfo.RoleId)) paramsObj["role_id"] = roleInfo.RoleId;
240
+ if (!string.IsNullOrEmpty(roleInfo.RoleName)) paramsObj["role_name"] = roleInfo.RoleName;
241
+ if (!string.IsNullOrEmpty(roleInfo.ServerId)) paramsObj["server_id"] = roleInfo.ServerId;
200
242
  }
201
243
 
202
- var urlParams = string.Join("&", parts);
244
+ var urlParams = Uri.EscapeDataString(JsonConvert.SerializeObject(paramsObj));
203
245
 
204
246
  var data = new Dictionary<string, object>
205
247
  {
@@ -1,5 +1,6 @@
1
1
  #if UNITY_EDITOR || UNITY_STANDALONE
2
2
 
3
+ using System.Collections.Generic;
3
4
  using Newtonsoft.Json;
4
5
  using XD.SDK.Common.Internal;
5
6
 
@@ -12,9 +13,11 @@ namespace XD.SDK.Account.Internal.Standalone
12
13
 
13
14
  public class SupportUnReadResponse
14
15
  {
15
- [JsonProperty("hasUnread")] public bool HasUnread { get; set; }
16
+ [JsonProperty("type")] public string Type { get; set; }
16
17
 
17
- [JsonProperty("intervalSec")] public int IntervalSec { get; set; }
18
+ [JsonProperty("lc")] public Dictionary<string, object> Lc { get; set; }
19
+
20
+ [JsonProperty("pn")] public Dictionary<string, object> Pn { get; set; }
18
21
  }
19
22
 
20
23
  public class SupportUrlResponse
@@ -1,4 +1,4 @@
1
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
1
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
2
2
  using System;
3
3
  using System.Collections.Generic;
4
4
  using TMPro;
@@ -1,4 +1,4 @@
1
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
1
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
2
2
  using System;
3
3
  using System.Collections.Generic;
4
4
  using System.Linq;
@@ -1,4 +1,4 @@
1
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
1
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
2
2
  using System;
3
3
  using UnityEngine;
4
4
  using UnityEngine.UI;
@@ -1,4 +1,4 @@
1
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
1
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
2
2
  using System;
3
3
  using System.Collections.Generic;
4
4
  using System.Linq;
@@ -1,4 +1,4 @@
1
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
1
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
2
2
  using System;
3
3
  using System.Threading.Tasks;
4
4
  using System.Collections.Generic;
@@ -72,7 +72,7 @@ namespace XD.SDK.Account.Internal.Standalone
72
72
  {
73
73
  // 滑动验证失败
74
74
  await alert.Reload();
75
- UIManager.ShowToast(e.Message);
75
+ UIManager.ShowToast(ex.ErrorMsg);
76
76
  }
77
77
  else
78
78
  {
@@ -1,4 +1,4 @@
1
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
1
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
2
2
  using System;
3
3
  using System.Threading.Tasks;
4
4
  using System.Collections;
@@ -108,7 +108,7 @@ namespace XD.SDK.Account.Internal.Standalone
108
108
  if (loginType == LoginType.Phone)
109
109
  {
110
110
  AliyunTrack.ResetPhoneLoginData();
111
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
111
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
112
112
  if (XDGCommonInternal.IsCn())
113
113
  {
114
114
  await PhoneModule.Bind();
@@ -132,7 +132,7 @@ namespace XD.SDK.Account.Internal.Standalone
132
132
  }
133
133
  else
134
134
  {
135
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
135
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
136
136
  await EmailModule.LoginOrBind(false);
137
137
  #else
138
138
  throw new XDGError(ResponseCode.Common.Failed, "This function need vuplex enabled");
@@ -151,7 +151,7 @@ namespace XD.SDK.Account.Internal.Standalone
151
151
  if (loginType == LoginType.Phone)
152
152
  {
153
153
  AliyunTrack.ResetPhoneLoginData();
154
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
154
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
155
155
  // 手机号解绑需要验证码
156
156
  if (XDGCommonInternal.IsCn())
157
157
  {
@@ -174,7 +174,7 @@ namespace XD.SDK.Account.Internal.Standalone
174
174
  }
175
175
  else
176
176
  {
177
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
177
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
178
178
  return EmailModule.Unbind(extras);
179
179
  #else
180
180
  throw new XDGError(ResponseCode.Common.Failed, "This function need vuplex enabled");
@@ -265,7 +265,7 @@ namespace XD.SDK.Account.Internal.Standalone
265
265
  {
266
266
  AliyunTrack.ResetPhoneLoginData();
267
267
  AliyunTrack.LoginEnableSDKLoginTrack();
268
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
268
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
269
269
  if (XDGCommonInternal.IsCn())
270
270
  {
271
271
  await PhoneModule.Login();
@@ -284,7 +284,7 @@ namespace XD.SDK.Account.Internal.Standalone
284
284
  {
285
285
  AliyunTrack.ResetEmailLoginData();
286
286
  AliyunTrack.LoginEnableSDKLoginTrack();
287
- #if (UNITY_EDITOR || UNITY_STANDALONE) && !XDSDK_DISABLE_VUPLEX
287
+ #if (UNITY_STANDALONE || (UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS)) && !XDSDK_DISABLE_VUPLEX
288
288
  await EmailModule.LoginOrBind(true);
289
289
  UIManager.ShowLoading();
290
290
  #else
@@ -0,0 +1,62 @@
1
+ #if UNITY_EDITOR || UNITY_STANDALONE
2
+
3
+ using System;
4
+ using System.Collections.Generic;
5
+ using XD.SDK.Common;
6
+ using XD.SDK.Common.Internal;
7
+ using XD.SDK.Common.Internal.Standalone;
8
+
9
+ namespace XD.SDK.Account.Internal.Standalone
10
+ {
11
+ public class GetUserInfoWebFunction : IWebFunction
12
+ {
13
+ public string GetName()
14
+ {
15
+ return "getUserInfo";
16
+ }
17
+
18
+ public async void Handler(IBridgeWebView webView, string data, Action<object> callbackFunction)
19
+ {
20
+ XDGLogger.Debug($"message from javascript by:{GetName()} with data:{data}", XDGLoggerTag.Web);
21
+
22
+ var user = await UserModule.GetLocalUser();
23
+ if (user == null || string.IsNullOrEmpty(user.UserId))
24
+ {
25
+ callbackFunction(new WebBridgeResponse.Failed
26
+ {
27
+ Msg = "current user is null"
28
+ });
29
+ return;
30
+ }
31
+
32
+ var result = new Dictionary<string, object>
33
+ {
34
+ { "userId", user.UserId },
35
+ { "username", user.UserName },
36
+ { "loginTypeEntryName", user.LoginTypeName },
37
+ { "loginList", user.BoundAccounts ?? new List<string>() },
38
+ { "nickName", user.NickName },
39
+ { "avatar", user.Avatar }
40
+ };
41
+
42
+ var token = await AccessTokenModule.GetLocalAccessToken();
43
+ if (token != null)
44
+ {
45
+ result["accessToken"] = new Dictionary<string, object>
46
+ {
47
+ { "kid", token.Kid },
48
+ { "macKey", token.MacKey },
49
+ { "macAlgorithm", token.MacAlgorithm },
50
+ { "tokenType", token.TokenType },
51
+ { "expireIn", token.ExpireIn }
52
+ };
53
+ }
54
+
55
+ callbackFunction(new WebBridgeResponse.Success
56
+ {
57
+ Data = result
58
+ });
59
+ }
60
+ }
61
+ }
62
+ #endif
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 68093f9e3912b4c3daedf16bd91ea20f
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "com.xd.sdk.account",
3
3
  "displayName": "XDGSDK Account",
4
- "version": "7.3.3",
4
+ "version": "7.6.0",
5
5
  "description": "XDGSDK",
6
6
  "unity": "2019.3",
7
7
  "license": "MIT",
8
8
  "dependencies": {
9
- "com.xd.sdk.common": "7.3.3"
9
+ "com.xd.sdk.common": "7.6.0"
10
10
  }
11
- }
11
+ }
@@ -1,32 +0,0 @@
1
- fileFormatVersion: 2
2
- guid: 3fb7e7b9b8ed449d8382477b70b810a1
3
- PluginImporter:
4
- externalObjects: {}
5
- serializedVersion: 2
6
- iconMap: {}
7
- executionOrder: {}
8
- defineConstraints: []
9
- isPreloaded: 0
10
- isOverridable: 1
11
- isExplicitlyReferenced: 0
12
- validateReferences: 1
13
- platformData:
14
- - first:
15
- Android: Android
16
- second:
17
- enabled: 1
18
- settings: {}
19
- - first:
20
- Any:
21
- second:
22
- enabled: 0
23
- settings: {}
24
- - first:
25
- Editor: Editor
26
- second:
27
- enabled: 0
28
- settings:
29
- DefaultValueInitialized: true
30
- userData:
31
- assetBundleName:
32
- assetBundleVariant:
@@ -1,32 +0,0 @@
1
- fileFormatVersion: 2
2
- guid: c384e2e57d3c54ea79502c23b2a03280
3
- PluginImporter:
4
- externalObjects: {}
5
- serializedVersion: 2
6
- iconMap: {}
7
- executionOrder: {}
8
- defineConstraints: []
9
- isPreloaded: 0
10
- isOverridable: 1
11
- isExplicitlyReferenced: 0
12
- validateReferences: 1
13
- platformData:
14
- - first:
15
- Android: Android
16
- second:
17
- enabled: 1
18
- settings: {}
19
- - first:
20
- Any:
21
- second:
22
- enabled: 0
23
- settings: {}
24
- - first:
25
- Editor: Editor
26
- second:
27
- enabled: 0
28
- settings:
29
- DefaultValueInitialized: true
30
- userData:
31
- assetBundleName:
32
- assetBundleVariant:
@@ -1,32 +0,0 @@
1
- fileFormatVersion: 2
2
- guid: 7620e2432939c4e67a4ffb7db19d1322
3
- PluginImporter:
4
- externalObjects: {}
5
- serializedVersion: 2
6
- iconMap: {}
7
- executionOrder: {}
8
- defineConstraints: []
9
- isPreloaded: 0
10
- isOverridable: 1
11
- isExplicitlyReferenced: 0
12
- validateReferences: 1
13
- platformData:
14
- - first:
15
- Android: Android
16
- second:
17
- enabled: 1
18
- settings: {}
19
- - first:
20
- Any:
21
- second:
22
- enabled: 0
23
- settings: {}
24
- - first:
25
- Editor: Editor
26
- second:
27
- enabled: 0
28
- settings:
29
- DefaultValueInitialized: true
30
- userData:
31
- assetBundleName:
32
- assetBundleVariant:
@@ -1,14 +0,0 @@
1
- #if UNITY_IOS || UNITY_ANDROID
2
-
3
- using System.Collections.Generic;
4
- using Newtonsoft.Json;
5
- using XD.SDK.Common.Internal;
6
-
7
- namespace XD.SDK.Account.Internal.Http
8
- {
9
- public class LoginSyncResponse : BaseResponse
10
- {
11
- [JsonProperty("data")] public Dictionary<string, object> Data;
12
- }
13
- }
14
- #endif