[M] new call back
[wip]
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@ bin
|
|||||||
bin_BurstDebugInformation_DoNotShip
|
bin_BurstDebugInformation_DoNotShip
|
||||||
sdk-intergration/.vscode
|
sdk-intergration/.vscode
|
||||||
sdk-intergration/'
|
sdk-intergration/'
|
||||||
|
sdk-intergration/Assets/.claude/settings.json
|
||||||
|
|||||||
40
sdk-intergration/Assets/Plugins/Android/SnsTest.java
Normal file
40
sdk-intergration/Assets/Plugins/Android/SnsTest.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package com.unity3d.player;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.tuyoo.gamesdk.api.SDKAPI;
|
||||||
|
import com.tuyoo.gamesdk.api.SDKAPIConstant;
|
||||||
|
import com.tuyoo.gamesdk.api.SDKCallBack;
|
||||||
|
import com.tuyoo.gamesdk.api.SDKWrapper;
|
||||||
|
|
||||||
|
public class SnsTest {
|
||||||
|
static final String TAG = "SNSTEST";
|
||||||
|
|
||||||
|
public static void Bind(String type, String guserId)
|
||||||
|
{
|
||||||
|
SDKAPI.getIns().getSnsInfo(type, (snscode, snsInfo, snsmsg) ->{
|
||||||
|
if(snscode == SDKCallBack.CODE_SUCCESS && snsInfo !=null)
|
||||||
|
{
|
||||||
|
SDKAPI.getIns().bindBySnsId(snsInfo, guserId, (bindcode, bindmsg)->{
|
||||||
|
if(bindcode == SDKCallBack.CODE_SUCCESS)
|
||||||
|
{
|
||||||
|
Log.i(TAG, "LinkSns success");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.i(TAG, String.format("LinkSns failed, code: %d, msg: %s", bindcode, bindmsg));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.i(TAG, "getSnsInfo failed");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Unbind(String type, int userId)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
32
sdk-intergration/Assets/Plugins/Android/SnsTest.java.meta
Normal file
32
sdk-intergration/Assets/Plugins/Android/SnsTest.java.meta
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0e17ee73ac07b4006a871da89b5103ae
|
||||||
|
PluginImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
iconMap: {}
|
||||||
|
executionOrder: {}
|
||||||
|
defineConstraints: []
|
||||||
|
isPreloaded: 0
|
||||||
|
isOverridable: 0
|
||||||
|
isExplicitlyReferenced: 0
|
||||||
|
validateReferences: 1
|
||||||
|
platformData:
|
||||||
|
- first:
|
||||||
|
Android: Android
|
||||||
|
second:
|
||||||
|
enabled: 1
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Any:
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings: {}
|
||||||
|
- first:
|
||||||
|
Editor: Editor
|
||||||
|
second:
|
||||||
|
enabled: 0
|
||||||
|
settings:
|
||||||
|
DefaultValueInitialized: true
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
3321
sdk-intergration/Assets/Scenes/UnbindTest.unity
Normal file
3321
sdk-intergration/Assets/Scenes/UnbindTest.unity
Normal file
File diff suppressed because it is too large
Load Diff
7
sdk-intergration/Assets/Scenes/UnbindTest.unity.meta
Normal file
7
sdk-intergration/Assets/Scenes/UnbindTest.unity.meta
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e55d807d563854943a26ad6dadec548d
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
138
sdk-intergration/Assets/Scripts/UnbindTest.cs
Normal file
138
sdk-intergration/Assets/Scripts/UnbindTest.cs
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using tysdk;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
public class UnbindTest : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField]
|
||||||
|
private Text message;
|
||||||
|
[SerializeField]
|
||||||
|
private Button cleanBtn;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private Button initBtn;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private Dropdown accoutTypeDropdown;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private Button loginBtn;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private Button logoutBtn;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private Button getSnsBtn;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private Button checkSnsBtn;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private Button bindBtn;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private Button unbindBtn;
|
||||||
|
|
||||||
|
private EAccoutType accoutType;
|
||||||
|
|
||||||
|
private const string Cls = "com.unity3d.player.SnsTest";
|
||||||
|
|
||||||
|
// Start is called before the first frame update
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
Screen.sleepTimeout = SleepTimeout.NeverSleep;
|
||||||
|
message.text = string.Empty;
|
||||||
|
accoutType = (EAccoutType)accoutTypeDropdown.value;
|
||||||
|
|
||||||
|
cleanBtn.onClick.AddListener(() => message.text = string.Empty);
|
||||||
|
initBtn.onClick.AddListener(Init);
|
||||||
|
accoutTypeDropdown.onValueChanged.AddListener((index) =>
|
||||||
|
{
|
||||||
|
accoutType = (EAccoutType)index;
|
||||||
|
message.text += $"[Account Type] {accoutType.ToString()}\r\n";
|
||||||
|
}); loginBtn.onClick.AddListener(OnLogin);
|
||||||
|
logoutBtn.onClick.AddListener(OnLogout);
|
||||||
|
getSnsBtn.onClick.AddListener(OnGetSns);
|
||||||
|
checkSnsBtn.onClick.AddListener(OnCheckSns);
|
||||||
|
bindBtn.onClick.AddListener(OnBind);
|
||||||
|
unbindBtn.onClick.AddListener(OnUnbind);
|
||||||
|
|
||||||
|
Debug.Log("========== Init =============");
|
||||||
|
TYSdkFacade.Instance.Init();
|
||||||
|
|
||||||
|
Debug.Log($"AccoutType {accoutType}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Init()
|
||||||
|
{
|
||||||
|
UnityBridgeFunc.UnityResetServerUrl("https://128-hwsfsdk-sdk-test01.qijihdhk.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLogout()
|
||||||
|
{
|
||||||
|
Debug.Log("========== Logout =============");
|
||||||
|
TYSdkFacade.Instance.Logout();
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoginInfo loginInfo;
|
||||||
|
private async void OnLogin()
|
||||||
|
{
|
||||||
|
Debug.Log("========== Login =============");
|
||||||
|
message.text += $"Login {accoutType}\r\n";
|
||||||
|
var info = await TYSdkFacade.Instance.Login(accoutType);
|
||||||
|
message.text = $"Login Success {info.isSuccess}\r\n";
|
||||||
|
if(info.isSuccess)
|
||||||
|
{
|
||||||
|
loginInfo = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGetSns()
|
||||||
|
{
|
||||||
|
Debug.Log("========== Get SNS =============");
|
||||||
|
using (var t = new AndroidJavaClass(Cls))
|
||||||
|
{
|
||||||
|
t.CallStatic("GetSns", accoutType.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCheckSns()
|
||||||
|
{
|
||||||
|
Debug.Log("========== Check SNS =============");
|
||||||
|
using (var t = new AndroidJavaClass(Cls))
|
||||||
|
{
|
||||||
|
t.CallStatic("CheckSns", accoutType.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBind()
|
||||||
|
{
|
||||||
|
Debug.Log("========== Bind =============");
|
||||||
|
using (var t = new AndroidJavaClass(Cls))
|
||||||
|
{
|
||||||
|
t.CallStatic("Bind", accoutType.ToString(), loginInfo.StrUserId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BindCallback(string message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUnbind()
|
||||||
|
{
|
||||||
|
using (var t = new AndroidJavaClass(Cls))
|
||||||
|
{
|
||||||
|
t.CallStatic("Unbind");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnbindCallback(string message)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
11
sdk-intergration/Assets/Scripts/UnbindTest.cs.meta
Normal file
11
sdk-intergration/Assets/Scripts/UnbindTest.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 52192be6b3a3b4555a714c7914c14c2b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
114
sdk-intergration/CLAUDE.md
Normal file
114
sdk-intergration/CLAUDE.md
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This is a Unity 2022.3.53f1c1 mobile game SDK integration testing project for "Fishing Travel" (com.arkgame.ft). The project focuses on validating and testing various mobile SDK integrations including authentication, payments, analytics, and advertising networks.
|
||||||
|
|
||||||
|
## Build Commands
|
||||||
|
|
||||||
|
### Android Builds
|
||||||
|
```bash
|
||||||
|
# Command-line build (CI/CD)
|
||||||
|
/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -quit -projectPath . -executeMethod BuildTool.CIBuildAndroid --out ../Bin/tysdkTest.apk --bundle-type FirstPack --build-type New
|
||||||
|
|
||||||
|
# Manual build via Unity Editor
|
||||||
|
Tools > Build Android
|
||||||
|
```
|
||||||
|
|
||||||
|
### iOS Builds
|
||||||
|
```bash
|
||||||
|
# Command-line build (CI/CD)
|
||||||
|
/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -quit -projectPath . -executeMethod BuildTool.CIBuildIOS --out ../Bin --bundle-type FirstPack --build-type New
|
||||||
|
|
||||||
|
# Manual build via Unity Editor
|
||||||
|
Tools > Build iOS
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build Parameters
|
||||||
|
- `--out`: Output path for build
|
||||||
|
- `--bundle-type`: None, FirstPack, or ALL
|
||||||
|
- `--build-type`: Build type (default: "New")
|
||||||
|
- `--define-symbol`: Custom compilation defines
|
||||||
|
- `--patch`: Enable patch build
|
||||||
|
- `--split`: Enable split APKs
|
||||||
|
- `--aab`: Build Android App Bundle instead of APK
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Core SDK Structure
|
||||||
|
- **TYSdkFacade** (`Packages/tysdk/Runtime/TYSdkFacade.cs`): Main SDK interface using facade pattern
|
||||||
|
- Account management with persistent storage
|
||||||
|
- Multiple social login providers (Google, Facebook, Apple, Guest)
|
||||||
|
- JWT token handling and linked account tracking
|
||||||
|
- Singleton pattern with DontDestroyOnLoad
|
||||||
|
|
||||||
|
- **UnityBridgeFunc** (`Assets/CoreLib/Data/sdk/base/UnityBridgeFunc.cs`): Platform-specific native bridge
|
||||||
|
- Android/iOS native method calls
|
||||||
|
- ATT (App Tracking Transparency) handling
|
||||||
|
- Social sharing functionality
|
||||||
|
|
||||||
|
### Test Infrastructure
|
||||||
|
- **SDKTest.cs** (`Assets/Scripts/SDKTest.cs`): Comprehensive SDK testing UI
|
||||||
|
- Tests all login methods and account linking
|
||||||
|
- Payment testing and ad display
|
||||||
|
- Integrates AppsFlyer, Max SDK, Thinking Analytics
|
||||||
|
- **UnbindTest.cs**: Account unbinding functionality test
|
||||||
|
- **Test Scenes**: SampleScene, UnbindTest, OneLinkTest
|
||||||
|
|
||||||
|
### Package Dependencies
|
||||||
|
Key Unity packages and third-party SDKs:
|
||||||
|
- **UniRx**: Reactive Extensions for Unity
|
||||||
|
- **tysdk**: Custom Tuyoo SDK wrapper (v0.0.1)
|
||||||
|
- **AppsFlyer SDK**: Attribution tracking
|
||||||
|
- **Max SDK**: Ad mediation platform
|
||||||
|
- **Thinking Analytics**: Custom analytics
|
||||||
|
- **Facebook SDK**: Social login and sharing
|
||||||
|
- **Firebase Analytics**: Google analytics
|
||||||
|
- **Google Play Services**: Auth, Billing, Review
|
||||||
|
|
||||||
|
## Platform-Specific Configuration
|
||||||
|
|
||||||
|
### Android
|
||||||
|
- **Target SDK**: 35 (configurable via gradle template)
|
||||||
|
- **Package Name**: com.arkgame.ft
|
||||||
|
- **Deep Linking**: OneLink support and custom URI scheme `zzft://mainactivity`
|
||||||
|
- **Key Files**:
|
||||||
|
- `Assets/Plugins/Android/AndroidManifest.xml`
|
||||||
|
- `Assets/Plugins/Android/mainTemplate.gradle`
|
||||||
|
- `Assets/Plugins/Android/gradleTemplate.properties`
|
||||||
|
|
||||||
|
### iOS
|
||||||
|
- **Build Output**: `../Bin` directory
|
||||||
|
- **Keystore**: Located in `keystore/` directory
|
||||||
|
- **Apple Sign-In**: Supported for iOS platform
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### Testing SDK Features
|
||||||
|
1. Open `SampleScene` or test scenes
|
||||||
|
2. Use SDKTest UI to test:
|
||||||
|
- Initialization
|
||||||
|
- Login methods (Guest, Google, Facebook, Apple, Token)
|
||||||
|
- Account linking/unlinking
|
||||||
|
- Payments and ad display
|
||||||
|
- Analytics events
|
||||||
|
|
||||||
|
### Adding New SDK Tests
|
||||||
|
1. Create test methods in SDKTest.cs
|
||||||
|
2. Add UI buttons in the corresponding scene
|
||||||
|
3. Hook up button listeners in Start() method
|
||||||
|
|
||||||
|
### Modifying Build Configuration
|
||||||
|
1. Edit BuildTool.cs for new build parameters
|
||||||
|
2. Modify mainTemplate.gradle for Android dependencies
|
||||||
|
3. Update AndroidManifest.xml for permissions/activities
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
- The project uses a custom TYApp/TYUnityActivity for Android
|
||||||
|
- Multiple ad network adapters integrated via Max SDK mediation
|
||||||
|
- Server URLs can be configured for test/production environments
|
||||||
|
- Uses PlayerPrefs for account persistence
|
||||||
|
- Implements comprehensive callback management for async operations
|
||||||
210
sdk-intergration/Packages/tysdk/Runtime/TYSDKCallbackManager.cs
Normal file
210
sdk-intergration/Packages/tysdk/Runtime/TYSDKCallbackManager.cs
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace tysdk
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 线程安全的异步Callback管理器
|
||||||
|
/// 解决原有callback系统的线程安全、内存泄漏和超时问题
|
||||||
|
/// </summary>
|
||||||
|
public class TYSDKCallbackManager : IDisposable
|
||||||
|
{
|
||||||
|
private static readonly Lazy<TYSDKCallbackManager> _instance =
|
||||||
|
new Lazy<TYSDKCallbackManager>(() => new TYSDKCallbackManager());
|
||||||
|
|
||||||
|
public static TYSDKCallbackManager Instance => _instance.Value;
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<string, CallbackEntry> _callbacks = new();
|
||||||
|
private readonly object _lock = new();
|
||||||
|
private bool _disposed = false;
|
||||||
|
|
||||||
|
private TYSDKCallbackManager() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册一个callback并返回Task
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Callback数据类型</typeparam>
|
||||||
|
/// <param name="callbackType">Callback类型标识</param>
|
||||||
|
/// <param name="timeout">超时时间,默认15 sec</param>
|
||||||
|
/// <returns>Task用于等待callback结果</returns>
|
||||||
|
public Task<T> RegisterCallback<T>(TimeSpan? timeout = null) where T : class
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException(nameof(TYSDKCallbackManager));
|
||||||
|
|
||||||
|
var callbackId = typeof(T).Name;
|
||||||
|
|
||||||
|
if (_callbacks.TryGetValue(callbackId, out var entry))
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.Log($"[TYSDKCallbackManager] Registered callback exists {callbackId}");
|
||||||
|
return entry.Task as Task<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tcs = new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
|
var actualTimeout = timeout ?? TimeSpan.FromSeconds(15);
|
||||||
|
var cts = new CancellationTokenSource(actualTimeout);
|
||||||
|
|
||||||
|
entry = new CallbackEntry<T>
|
||||||
|
{
|
||||||
|
TaskCompletionSource = tcs,
|
||||||
|
CancellationTokenSource = cts,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 注册到字典
|
||||||
|
_callbacks[callbackId] = entry;
|
||||||
|
|
||||||
|
// 设置超时取消
|
||||||
|
cts.Token.Register(() =>
|
||||||
|
{
|
||||||
|
if (tcs.TrySetCanceled())
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogWarning($"[TYSDKCallbackManager] Callback {callbackId} timed out after {actualTimeout.TotalSeconds}s");
|
||||||
|
}
|
||||||
|
_callbacks.TryRemove(callbackId, out _);
|
||||||
|
});
|
||||||
|
|
||||||
|
UnityEngine.Debug.Log($"[TYSDKCallbackManager] Registered callback {callbackId}");
|
||||||
|
return tcs.Task;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 触发callback
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Callback数据类型</typeparam>
|
||||||
|
/// <param name="callbackType">Callback类型标识</param>
|
||||||
|
/// <param name="callbackData">Callback数据</param>
|
||||||
|
/// <returns>是否成功触发callback</returns>
|
||||||
|
public bool TryTriggerCallback<T>(T callbackData) where T : class
|
||||||
|
{
|
||||||
|
if (_disposed || callbackData == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var key = typeof(T).Name;
|
||||||
|
if (!_callbacks.TryGetValue(key, out var entry))
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogWarning($"[TYSDKCallbackManager] No pending callback found for type: {key}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry == null)
|
||||||
|
{
|
||||||
|
_callbacks.TryRemove(key, out _);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.Task.IsCompleted)
|
||||||
|
{
|
||||||
|
entry.CancellationTokenSource?.Cancel();
|
||||||
|
_callbacks.TryRemove(key, out _);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var actualEntry = entry as CallbackEntry<T>;
|
||||||
|
|
||||||
|
if (actualEntry == null)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogError($"[TYSDKCallbackManager] Callback type mismatch: Expected {typeof(T).Name}, but got {entry.GetType().Name}");
|
||||||
|
entry.CancellationTokenSource?.Cancel();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 尝试设置结果
|
||||||
|
if (actualEntry.TaskCompletionSource.TrySetResult(callbackData))
|
||||||
|
{
|
||||||
|
actualEntry.CancellationTokenSource?.Cancel();
|
||||||
|
UnityEngine.Debug.Log($"[TYSDKCallbackManager] Successfully triggered callback {key}");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogError($"[TYSDKCallbackManager] Error triggering callback {key}: {ex.Message}\n{ex.StackTrace}");
|
||||||
|
actualEntry.TaskCompletionSource.TrySetException(ex);
|
||||||
|
actualEntry.CancellationTokenSource?.Cancel();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 取消指定类型的所有callback
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="callbackType">Callback类型</param>
|
||||||
|
/// <param name="reason">取消原因</param>
|
||||||
|
public void CancelCallbacks<T>()
|
||||||
|
{
|
||||||
|
var key = typeof(T).Name;
|
||||||
|
|
||||||
|
if (!_callbacks.TryGetValue(key, out var entryToRemove))
|
||||||
|
{
|
||||||
|
UnityEngine.Debug.LogWarning($"[TYSDKCallbackManager] No pending callback found for type: {key}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
entryToRemove.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetCallbackNum()
|
||||||
|
{
|
||||||
|
return _callbacks?.Count ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_disposed) return;
|
||||||
|
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
if (_disposed) return;
|
||||||
|
_disposed = true;
|
||||||
|
|
||||||
|
// 取消所有pending callbacks
|
||||||
|
foreach (var entry in _callbacks.Values)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!entry.Task.IsCompleted)
|
||||||
|
{
|
||||||
|
entry.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 忽略取消时的异常
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.CancellationTokenSource?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
_callbacks.Clear();
|
||||||
|
UnityEngine.Debug.Log("[TYSDKCallbackManager] Disposed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract class CallbackEntry
|
||||||
|
{
|
||||||
|
public CancellationTokenSource CancellationTokenSource { get; set; } = null!;
|
||||||
|
public abstract Task Task { get; }
|
||||||
|
public abstract void Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CallbackEntry<T> : CallbackEntry where T : class
|
||||||
|
{
|
||||||
|
public TaskCompletionSource<T> TaskCompletionSource { get; set; } = null!;
|
||||||
|
public override Task Task => TaskCompletionSource.Task;
|
||||||
|
|
||||||
|
public override void Cancel()
|
||||||
|
{
|
||||||
|
TaskCompletionSource.TrySetCanceled();
|
||||||
|
CancellationTokenSource?.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 292a655e788d84d34aac4f83c57706ff
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -19,7 +19,7 @@ namespace tysdk
|
|||||||
public string jwtToken;
|
public string jwtToken;
|
||||||
public string strUserId => userId.ToString();
|
public string strUserId => userId.ToString();
|
||||||
public HashSet<EAccoutType> linkedAccout = new HashSet<EAccoutType>();
|
public HashSet<EAccoutType> linkedAccout = new HashSet<EAccoutType>();
|
||||||
public EAccoutType channel {get; set;}
|
public EAccoutType channel { get; set; }
|
||||||
public string userName;
|
public string userName;
|
||||||
public string avatar;
|
public string avatar;
|
||||||
|
|
||||||
@@ -81,12 +81,12 @@ namespace tysdk
|
|||||||
linkedAccout = jInfo["linkedAccout"].ToString().Split(',').Select(x => ConvertAccoutType(x)).ToHashSet()
|
linkedAccout = jInfo["linkedAccout"].ToString().Split(',').Select(x => ConvertAccoutType(x)).ToHashSet()
|
||||||
};
|
};
|
||||||
|
|
||||||
if(jInfo.TryGetValue("userName", out var userName))
|
if (jInfo.TryGetValue("userName", out var userName))
|
||||||
{
|
{
|
||||||
accountInfo.userName = (string) userName;
|
accountInfo.userName = (string)userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(jInfo.TryGetValue("avatar", out var avatar))
|
if (jInfo.TryGetValue("avatar", out var avatar))
|
||||||
{
|
{
|
||||||
accountInfo.avatar = (string)avatar;
|
accountInfo.avatar = (string)avatar;
|
||||||
}
|
}
|
||||||
@@ -103,8 +103,6 @@ namespace tysdk
|
|||||||
private static AccountInfo _accountInfo;
|
private static AccountInfo _accountInfo;
|
||||||
public static AccountInfo TYAccountInfo => _accountInfo;
|
public static AccountInfo TYAccountInfo => _accountInfo;
|
||||||
|
|
||||||
private static IDictionary<string, Action<ITYSdkCallback>> callbacks = new Dictionary<string, Action<ITYSdkCallback>>();
|
|
||||||
|
|
||||||
private static TYSdkFacade _instance;
|
private static TYSdkFacade _instance;
|
||||||
public static TYSdkFacade Instance
|
public static TYSdkFacade Instance
|
||||||
{
|
{
|
||||||
@@ -118,7 +116,6 @@ namespace tysdk
|
|||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
#if UNITY_ANDROID
|
#if UNITY_ANDROID
|
||||||
@@ -144,7 +141,7 @@ namespace tysdk
|
|||||||
public void Logout()
|
public void Logout()
|
||||||
{
|
{
|
||||||
UnityEngine.Debug.Log("Logout");
|
UnityEngine.Debug.Log("Logout");
|
||||||
if(_accountInfo != null)
|
if (_accountInfo != null)
|
||||||
{
|
{
|
||||||
UnityBridgeFunc.UnityLogOutByChannel(_accountInfo.channel);
|
UnityBridgeFunc.UnityLogOutByChannel(_accountInfo.channel);
|
||||||
}
|
}
|
||||||
@@ -157,7 +154,7 @@ namespace tysdk
|
|||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
await Task.Yield();
|
await Task.Yield();
|
||||||
var deviceId = UnityEngine.Device.SystemInfo.deviceUniqueIdentifier.Split('-')[0].Substring(0,8);
|
var deviceId = UnityEngine.Device.SystemInfo.deviceUniqueIdentifier.Split('-')[0].Substring(0, 8);
|
||||||
|
|
||||||
var userId = (int)ulong.Parse(deviceId, System.Globalization.NumberStyles.HexNumber);
|
var userId = (int)ulong.Parse(deviceId, System.Globalization.NumberStyles.HexNumber);
|
||||||
|
|
||||||
@@ -174,44 +171,53 @@ namespace tysdk
|
|||||||
|
|
||||||
#elif UNITY_ANDROID || UNITY_IOS
|
#elif UNITY_ANDROID || UNITY_IOS
|
||||||
|
|
||||||
var taskSource = new TaskCompletionSource<LoginInfo>();
|
|
||||||
callbacks.Add("LoginResult", (ITYSdkCallback callback) =>
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<LoginInfo>(TimeSpan.FromSeconds(30));
|
||||||
{
|
|
||||||
taskSource.SetResult((LoginInfo)callback);
|
|
||||||
});
|
|
||||||
|
|
||||||
UnityBridgeFunc.UnityLogin(accoutType);
|
UnityBridgeFunc.UnityLogin(accoutType);
|
||||||
|
|
||||||
var loginInfo = await taskSource.Task;
|
try
|
||||||
if(loginInfo.isSuccess)
|
|
||||||
{
|
{
|
||||||
_accountInfo.channel = accoutType;
|
var loginInfo = await task;
|
||||||
_accountInfo.AddLinkedAccount(accoutType);
|
if(loginInfo.isSuccess)
|
||||||
_accountInfo.Save();
|
{
|
||||||
|
_accountInfo.channel = accoutType;
|
||||||
|
_accountInfo.AddLinkedAccount(accoutType);
|
||||||
|
_accountInfo.Save();
|
||||||
|
}
|
||||||
|
return loginInfo;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"[TYSdkFacade] Login failed: {e}");
|
||||||
|
return new LoginInfo(){isSuccess = false};
|
||||||
}
|
}
|
||||||
return loginInfo;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<LoginInfo> LoginByToken()
|
public async Task<LoginInfo> LoginByToken()
|
||||||
{
|
{
|
||||||
var accoutInfo = AccountInfo.GetSavedAccoutInfo();
|
var accoutInfo = AccountInfo.GetSavedAccoutInfo();
|
||||||
if(accoutInfo == null) return new LoginInfo();
|
if (accoutInfo == null) return new LoginInfo();
|
||||||
|
|
||||||
var taskSource = new TaskCompletionSource<LoginInfo>();
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<LoginInfo>(TimeSpan.FromSeconds(30));
|
||||||
callbacks.Add("LoginResult", (ITYSdkCallback callback) =>
|
|
||||||
{
|
|
||||||
taskSource.SetResult((LoginInfo)callback);
|
|
||||||
});
|
|
||||||
|
|
||||||
UnityBridgeFunc.UnityLoginByTokenFun(accoutInfo.token);
|
UnityBridgeFunc.UnityLoginByTokenFun(accoutInfo.token);
|
||||||
|
|
||||||
var loginInfo = await taskSource.Task;
|
try
|
||||||
if(loginInfo.isSuccess)
|
|
||||||
{
|
{
|
||||||
_accountInfo.Save();
|
var loginInfo = await task;
|
||||||
|
if (loginInfo.isSuccess)
|
||||||
|
{
|
||||||
|
_accountInfo.Save();
|
||||||
|
}
|
||||||
|
return loginInfo;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"[TYSdkFacade] Login by token failed: {e}");
|
||||||
|
return new LoginInfo() { isSuccess = false };
|
||||||
}
|
}
|
||||||
return loginInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoginResult(string json)
|
public void LoginResult(string json)
|
||||||
@@ -231,7 +237,7 @@ namespace tysdk
|
|||||||
var jwtToken = (string)loginData["jwttoken"];
|
var jwtToken = (string)loginData["jwttoken"];
|
||||||
|
|
||||||
var savedInfo = AccountInfo.GetSavedAccoutInfo();
|
var savedInfo = AccountInfo.GetSavedAccoutInfo();
|
||||||
if(savedInfo == null || savedInfo.userId != userId)
|
if (savedInfo == null || savedInfo.userId != userId)
|
||||||
{
|
{
|
||||||
_accountInfo = new AccountInfo()
|
_accountInfo = new AccountInfo()
|
||||||
{
|
{
|
||||||
@@ -254,11 +260,7 @@ namespace tysdk
|
|||||||
SetUserInfo();
|
SetUserInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callbacks.TryGetValue("LoginResult", out var action))
|
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
||||||
{
|
|
||||||
action.Invoke(result);
|
|
||||||
callbacks.Remove("LoginResult");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetUserInfo()
|
private void SetUserInfo()
|
||||||
@@ -276,35 +278,36 @@ namespace tysdk
|
|||||||
await Task.Delay(300);
|
await Task.Delay(300);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#elif UNITY_IOS
|
#elif UNITY_IOS || UNITY_ANDROID
|
||||||
|
public async Task<bool> LinkAccount(EAccoutType accoutType)
|
||||||
public async Task<bool> LinkAccount(EAccoutType accoutType)
|
|
||||||
{
|
{
|
||||||
if (_accountInfo == null) return false;
|
if (_accountInfo == null) return false;
|
||||||
if( _accountInfo.linkedAccout.Contains(accoutType)) return true;
|
if (_accountInfo.linkedAccout.Contains(accoutType)) return true;
|
||||||
|
|
||||||
var taskSource = new TaskCompletionSource<LinkResult>();
|
|
||||||
callbacks.Add("LinkAccoutResult", (ITYSdkCallback callback) =>
|
|
||||||
{
|
|
||||||
taskSource.SetResult((LinkResult)callback);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<LinkResult>();
|
||||||
UnityBridgeFunc.LinkAccount(accoutType);
|
UnityBridgeFunc.LinkAccount(accoutType);
|
||||||
|
|
||||||
var result = await taskSource.Task;
|
try
|
||||||
if (result.isSuccess)
|
|
||||||
{
|
{
|
||||||
if(_accountInfo == null)
|
var result = await task;
|
||||||
_accountInfo = AccountInfo.GetSavedAccoutInfo();
|
if (result.isSuccess)
|
||||||
|
|
||||||
if(_accountInfo != null)
|
|
||||||
{
|
{
|
||||||
_accountInfo.AddLinkedAccount(accoutType);
|
if (_accountInfo == null)
|
||||||
_accountInfo.Save();
|
_accountInfo = AccountInfo.GetSavedAccoutInfo();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.isSuccess;
|
if (_accountInfo != null)
|
||||||
|
{
|
||||||
|
_accountInfo.AddLinkedAccount(accoutType);
|
||||||
|
_accountInfo.Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.isSuccess;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"[TYSdkFacade] Link account failed: {e}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LinkAccoutResult(string codestr)
|
public void LinkAccoutResult(string codestr)
|
||||||
@@ -314,44 +317,8 @@ namespace tysdk
|
|||||||
isSuccess = codestr == "1"
|
isSuccess = codestr == "1"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (callbacks.TryGetValue("LinkAccoutResult", out var action))
|
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
||||||
{
|
|
||||||
action.Invoke(result);
|
|
||||||
callbacks.Remove("LinkAccoutResult");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif UNITY_ANDROID
|
|
||||||
|
|
||||||
public async Task<bool> LinkAccount(EAccoutType accoutType)
|
|
||||||
{
|
|
||||||
if (_accountInfo == null) return false;
|
|
||||||
if( _accountInfo.linkedAccout.Contains(accoutType)) return true;
|
|
||||||
|
|
||||||
var taskSource = new TaskCompletionSource<LoginInfo>();
|
|
||||||
callbacks.Add("LoginResult", (ITYSdkCallback callback) =>
|
|
||||||
{
|
|
||||||
taskSource.SetResult((LoginInfo)callback);
|
|
||||||
});
|
|
||||||
|
|
||||||
UnityBridgeFunc.LinkAccount(accoutType);
|
|
||||||
|
|
||||||
var result = await taskSource.Task;
|
|
||||||
if (result.isSuccess)
|
|
||||||
{
|
|
||||||
if(_accountInfo == null)
|
|
||||||
_accountInfo = AccountInfo.GetSavedAccoutInfo();
|
|
||||||
|
|
||||||
if(_accountInfo != null)
|
|
||||||
{
|
|
||||||
_accountInfo.AddLinkedAccount(accoutType);
|
|
||||||
_accountInfo.Save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.isSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -365,41 +332,40 @@ namespace tysdk
|
|||||||
public async Task<bool> LinkCheck(EAccoutType accoutType)
|
public async Task<bool> LinkCheck(EAccoutType accoutType)
|
||||||
{
|
{
|
||||||
if (_accountInfo == null) return false;
|
if (_accountInfo == null) return false;
|
||||||
if( _accountInfo.linkedAccout.Contains(accoutType)) return true;
|
if (_accountInfo.linkedAccout.Contains(accoutType)) return true;
|
||||||
|
|
||||||
var taskSource = new TaskCompletionSource<LinkCheckInfo>();
|
|
||||||
callbacks.Add("CheckLinkResult", (ITYSdkCallback callback) =>
|
|
||||||
{
|
|
||||||
taskSource.SetResult((LinkCheckInfo)callback);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<LinkCheckInfo>(TimeSpan.FromSeconds(30));
|
||||||
UnityBridgeFunc.LinkCheck(accoutType);
|
UnityBridgeFunc.LinkCheck(accoutType);
|
||||||
|
|
||||||
var code = (await taskSource.Task).code;
|
try
|
||||||
|
|
||||||
if (code == 1 && !_accountInfo.linkedAccout.Contains(accoutType))
|
|
||||||
{
|
{
|
||||||
_accountInfo.linkedAccout.Add(accoutType);
|
var result = await task;
|
||||||
_accountInfo.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(code == -1)
|
if (result.code == 1 && !_accountInfo.linkedAccout.Contains(accoutType))
|
||||||
|
{
|
||||||
|
_accountInfo.linkedAccout.Add(accoutType);
|
||||||
|
_accountInfo.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.code == -1)
|
||||||
|
{
|
||||||
|
Debug.LogError("[TYSdkFacade] CheckLinkResult error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.code == 1;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
Debug.LogError("[TYSdkFacade] CheckLinkResult error");
|
Debug.LogWarning($"[TYSdkFacade] CheckLinkResult error: {e}");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return code == 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CheckLinkResult(string codestr)
|
public void CheckLinkResult(string codestr)
|
||||||
{
|
{
|
||||||
if (callbacks.TryGetValue("CheckLinkResult", out var action))
|
var result = new LinkCheckInfo();
|
||||||
{
|
result.code = int.Parse(codestr);
|
||||||
var result = new LinkCheckInfo();
|
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
||||||
result.code = int.Parse(codestr);
|
|
||||||
action.Invoke(result);
|
|
||||||
callbacks.Remove("CheckLinkResult");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Signout()
|
public void Signout()
|
||||||
@@ -411,7 +377,7 @@ namespace tysdk
|
|||||||
var tyurl = config.Get<string>("AGG_SERVER", defaultTyurl);
|
var tyurl = config.Get<string>("AGG_SERVER", defaultTyurl);
|
||||||
|
|
||||||
|
|
||||||
string tycs = tyurl == defaultTyurl ?
|
string tycs = tyurl == defaultTyurl ?
|
||||||
"https://hwcsh.tygameworld.com/template/appCancel/note.html"
|
"https://hwcsh.tygameworld.com/template/appCancel/note.html"
|
||||||
:
|
:
|
||||||
"https://customermanage-feature-test-web-test.tuyougame.cn/appCancel/note.html";
|
"https://customermanage-feature-test-web-test.tuyougame.cn/appCancel/note.html";
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -27,23 +28,22 @@ namespace tysdk
|
|||||||
|
|
||||||
return new ATTInfo(){isAccepted = true};
|
return new ATTInfo(){isAccepted = true};
|
||||||
#elif UNITY_IOS
|
#elif UNITY_IOS
|
||||||
var taskSource = new TaskCompletionSource<ATTInfo>();
|
var task = tysdk.TYSDKCallbackManager.Instance.RegisterCallback<ATTInfo>();
|
||||||
callbacks.Add("RequestATT", (ITYSdkCallback callback) =>
|
|
||||||
{
|
|
||||||
taskSource.SetResult((ATTInfo)callback);
|
|
||||||
});
|
|
||||||
UnityBridgeFunc.RequestATT();
|
UnityBridgeFunc.RequestATT();
|
||||||
return await taskSource.Task;
|
try{
|
||||||
|
return await task;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogWarning(e.Message);
|
||||||
|
return new ATTInfo(){isAccepted = false};
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RequestATTResult(string r)
|
public void RequestATTResult(string r)
|
||||||
{
|
{
|
||||||
if (callbacks.TryGetValue("RequestATT", out var action))
|
TYSDKCallbackManager.Instance.TryTriggerCallback(new ATTInfo(){isAccepted = r == "1"});
|
||||||
{
|
|
||||||
action.Invoke(new ATTInfo(){isAccepted = r == "1"});
|
|
||||||
callbacks.Remove("RequestATT");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,126 +35,4 @@ namespace tysdk
|
|||||||
GA_SDK = 9, //SDK相关事件
|
GA_SDK = 9, //SDK相关事件
|
||||||
GA_ABTest = 10, //abtest相关事件
|
GA_ABTest = 10, //abtest相关事件
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
public class GAEvent : IDisposable
|
|
||||||
{
|
|
||||||
|
|
||||||
private GATrackType eventType;
|
|
||||||
private string eventName;
|
|
||||||
bool AFSend = true;
|
|
||||||
private JObject content = new JObject();
|
|
||||||
public static Dictionary<string, string> extraContent = new Dictionary<string, string>();
|
|
||||||
|
|
||||||
public GAEvent(GATrackType eventType, string eventName, bool AFSend = true)
|
|
||||||
{
|
|
||||||
this.eventType = eventType;
|
|
||||||
this.eventName = eventName;
|
|
||||||
this.AFSend = AFSend;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GAEvent AddContent(string key, string value)
|
|
||||||
{
|
|
||||||
content[key] = value;
|
|
||||||
return this; }
|
|
||||||
|
|
||||||
public GAEvent AddContent(string key, int value)
|
|
||||||
{
|
|
||||||
content[key] = value;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GAEvent AddContent(string key, bool value)
|
|
||||||
{
|
|
||||||
content[key] = value;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GAEvent AddContent(string key, float value)
|
|
||||||
{
|
|
||||||
content[key] = value;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GAEvent AddContent(string key, JToken value)
|
|
||||||
{
|
|
||||||
content[key] = value;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
foreach (var item in extraContent)
|
|
||||||
{
|
|
||||||
content[item.Key] = item.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
string msg = content.ToString();
|
|
||||||
if (msg == String.Empty) return;
|
|
||||||
|
|
||||||
if (AFSend)
|
|
||||||
{
|
|
||||||
SendAfEvent(eventType,eventName,msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
TYSdkFacade.Instance.EventTrack((int)eventType, eventName, msg);
|
|
||||||
|
|
||||||
content.RemoveAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SendAfEvent(GATrackType type,string eventName,string logMessage)
|
|
||||||
{
|
|
||||||
Dictionary<string, string> eventValues = new Dictionary<string, string>();
|
|
||||||
eventValues.Add("GA_TYPE", type.ToString());
|
|
||||||
eventValues.Add(eventName, logMessage);
|
|
||||||
AppsFlyer.sendEvent(AFInAppEvents.GA, eventValues);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
*GA_TRACK(默认类型)
|
|
||||||
*GA_CION(金流相关事件)
|
|
||||||
*GA_PAY(支付相关事件)
|
|
||||||
*GA_GAME(游戏行为)
|
|
||||||
*GA_LOGIN(登录注册相关事件)
|
|
||||||
*GA_PUSH(推送相关事件)
|
|
||||||
*GA_ADBOX(adbox相关事件)
|
|
||||||
*GA_PREFORMANCE(性能上报相关事件)
|
|
||||||
*GA_SDK(SDK相关事件)
|
|
||||||
*GA_ABTest(abtest相关事件)
|
|
||||||
*GA_PROFILE(设置用户特征
|
|
||||||
*/
|
|
||||||
//TOD SDK
|
|
||||||
/*
|
|
||||||
public static GAEvent TackEvent(string eventName, bool afSend = true)
|
|
||||||
{
|
|
||||||
return new GAEvent(GATrackType.GA_TRACK, eventName, afSend);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GAEvent PushEvent(string eventName, bool afSend = true)
|
|
||||||
{
|
|
||||||
return new GAEvent(GATrackType.GA_PUSH, eventName, afSend);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GAEvent CionEvent(string eventName, bool afSend = true)
|
|
||||||
{
|
|
||||||
return new GAEvent(GATrackType.GA_CION, eventName, afSend);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GAEvent PayEvent(string eventName, bool afSend = true)
|
|
||||||
{
|
|
||||||
return new GAEvent(GATrackType.GA_PAY, eventName, afSend);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GAEvent GameEvent(string eventName, bool afSend = true)
|
|
||||||
{
|
|
||||||
return new GAEvent(GATrackType.GA_GAME, eventName, afSend);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GAEvent LoginEvent(string eventName, bool afSend = true)
|
|
||||||
{
|
|
||||||
return new GAEvent(GATrackType.GA_LOGIN, eventName, afSend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,36 +57,44 @@ namespace tysdk
|
|||||||
|
|
||||||
var pType = "googleiab.global.app";
|
var pType = "googleiab.global.app";
|
||||||
|
|
||||||
var taskSource = new TaskCompletionSource<PaymentInfo>();
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<PaymentInfo>(TimeSpan.FromMinutes(1));
|
||||||
callbacks.Add("PayResult", (ITYSdkCallback callback) =>
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
taskSource.SetResult((PaymentInfo)callback);
|
//UnityBridgeFunc.UnityKnow(prodId, prodName, count.ToString(), orderId, extraInfo);
|
||||||
});
|
UnityBridgeFunc.UnityKnowNew(prodId, prodPrice, prodName, count.ToString(), orderId, extraInfo,pType);
|
||||||
|
|
||||||
//UnityBridgeFunc.UnityKnow(prodId, prodName, count.ToString(), orderId, extraInfo);
|
var result = await task;
|
||||||
UnityBridgeFunc.UnityKnowNew(prodId, prodPrice, prodName, count.ToString(), orderId, extraInfo,pType);
|
result.count = count;
|
||||||
|
result.orderId = orderId;
|
||||||
|
result.productId = prodId;
|
||||||
|
result.price = prodPrice;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"[TYSdkFacade::Pay] Faild {e.Message}");
|
||||||
|
return new PaymentInfo(){code = "-1"};
|
||||||
|
}
|
||||||
|
|
||||||
var result = await taskSource.Task;
|
|
||||||
result.count = count;
|
|
||||||
result.orderId = orderId;
|
|
||||||
result.productId = prodId;
|
|
||||||
result.price = prodPrice;
|
|
||||||
return result;
|
|
||||||
|
|
||||||
#elif UNITY_IOS
|
#elif UNITY_IOS
|
||||||
var taskSource = new TaskCompletionSource<PaymentInfo>();
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<PaymentInfo>(TimeSpan.FromMinutes(1));
|
||||||
callbacks.Add("PayResult", (ITYSdkCallback callback) =>
|
|
||||||
{
|
|
||||||
taskSource.SetResult((PaymentInfo)callback);
|
|
||||||
});
|
|
||||||
UnityBridgeFunc.UnityKnow(_accountInfo.strUserId, prodId, prodPrice, prodName, count.ToString(), orderId, extraInfo);
|
UnityBridgeFunc.UnityKnow(_accountInfo.strUserId, prodId, prodPrice, prodName, count.ToString(), orderId, extraInfo);
|
||||||
|
|
||||||
var result = await taskSource.Task;
|
try{
|
||||||
result.count = count;
|
var result = await task;
|
||||||
result.orderId = orderId;
|
result.count = count;
|
||||||
result.productId = prodId;
|
result.orderId = orderId;
|
||||||
result.price = prodPrice;
|
result.productId = prodId;
|
||||||
return result;
|
result.price = prodPrice;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"[TYSdkFacade::Pay] Faild {e.Message}");
|
||||||
|
return new PaymentInfo(){code = "-1"};
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,12 +106,7 @@ namespace tysdk
|
|||||||
var result = new PaymentInfo();
|
var result = new PaymentInfo();
|
||||||
result.code = jresult["code"].ToString();
|
result.code = jresult["code"].ToString();
|
||||||
result.msg = jresult["errStr"].ToString();
|
result.msg = jresult["errStr"].ToString();
|
||||||
|
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
||||||
if (callbacks.TryGetValue("PayResult", out var action))
|
|
||||||
{
|
|
||||||
action.Invoke(result);
|
|
||||||
callbacks.Remove("PayResult");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Pay list
|
// Get Pay list
|
||||||
@@ -117,13 +120,9 @@ namespace tysdk
|
|||||||
var result = new ProductListInfo();
|
var result = new ProductListInfo();
|
||||||
return result;
|
return result;
|
||||||
#elif UNITY_ANDROID || UNITY_IOS
|
#elif UNITY_ANDROID || UNITY_IOS
|
||||||
var taskSource = new TaskCompletionSource<ProductListInfo>();
|
var task = TYSDKCallbackManager.Instance.RegisterCallback<ProductListInfo>();
|
||||||
callbacks.Add("SKUListResult", (ITYSdkCallback callback) =>
|
|
||||||
{
|
|
||||||
taskSource.SetResult((ProductListInfo) callback);
|
|
||||||
});
|
|
||||||
UnityBridgeFunc.GetSKUList();
|
UnityBridgeFunc.GetSKUList();
|
||||||
var result = await taskSource.Task;
|
var result = await task;
|
||||||
return result;
|
return result;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -147,11 +146,7 @@ namespace tysdk
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callbacks.TryGetValue("SKUListResult", out var action))
|
TYSDKCallbackManager.Instance.TryTriggerCallback(result);
|
||||||
{
|
|
||||||
action.Invoke(result);
|
|
||||||
callbacks.Remove("SKUListResult");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ namespace tysdk
|
|||||||
none
|
none
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ITYSdkCallback { }
|
|
||||||
|
|
||||||
public class LoginInfo : ITYSdkCallback
|
public class LoginInfo
|
||||||
{
|
{
|
||||||
public bool isSuccess;
|
public bool isSuccess;
|
||||||
public int userId;
|
public int userId;
|
||||||
@@ -24,17 +23,17 @@ namespace tysdk
|
|||||||
public int code;
|
public int code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LinkResult : ITYSdkCallback
|
public class LinkResult
|
||||||
{
|
{
|
||||||
public bool isSuccess;
|
public bool isSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LinkCheckInfo : ITYSdkCallback
|
public class LinkCheckInfo
|
||||||
{
|
{
|
||||||
public int code;
|
public int code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PaymentInfo : ITYSdkCallback
|
public class PaymentInfo
|
||||||
{
|
{
|
||||||
public bool isSuccessFromSdk => code == "0";
|
public bool isSuccessFromSdk => code == "0";
|
||||||
public bool isSuccess => isSuccessFromSdk && confirmed;
|
public bool isSuccess => isSuccessFromSdk && confirmed;
|
||||||
@@ -62,7 +61,7 @@ namespace tysdk
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProductListInfo: ITYSdkCallback
|
public class ProductListInfo
|
||||||
{
|
{
|
||||||
public int code = 1;
|
public int code = 1;
|
||||||
public string msg = string.Empty;
|
public string msg = string.Empty;
|
||||||
@@ -134,7 +133,7 @@ namespace tysdk
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public class ATTInfo : ITYSdkCallback
|
public class ATTInfo
|
||||||
{
|
{
|
||||||
public bool isAccepted;
|
public bool isAccepted;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,6 @@ EditorBuildSettings:
|
|||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
m_Scenes:
|
m_Scenes:
|
||||||
- enabled: 1
|
- enabled: 1
|
||||||
path: Assets/Scenes/SampleScene.unity
|
path: Assets/Scenes/UnbindTest.unity
|
||||||
guid: 99c9720ab356a0642a771bea13969a05
|
guid: e55d807d563854943a26ad6dadec548d
|
||||||
- enabled: 1
|
|
||||||
path: Assets/Scenes/OneLinkTest.unity
|
|
||||||
guid: 61b7489d20aa24ed1b5cdc4fcfd05a65
|
|
||||||
m_configObjects: {}
|
m_configObjects: {}
|
||||||
|
|||||||
Reference in New Issue
Block a user