diff --git a/Assets/Plugins/Android/AndroidManifest.xml b/Assets/Plugins/Android/AndroidManifest.xml index 8d1ad628..33f628cb 100644 --- a/Assets/Plugins/Android/AndroidManifest.xml +++ b/Assets/Plugins/Android/AndroidManifest.xml @@ -8,6 +8,8 @@ android:name="com.u8.sdk.U8Application" android:allowBackup="true" android:extractNativeLibs="true" + android:hardwareAccelerated="true" + android:largeHeap="true" android:networkSecurityConfig="@xml/network_security_config" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:usesCleartextTraffic="true" @@ -19,8 +21,8 @@ diff --git a/Assets/Plugins/Android/AndroidManifest.xml.meta b/Assets/Plugins/Android/AndroidManifest.xml.meta index 2ccb5aab..46dfa968 100644 --- a/Assets/Plugins/Android/AndroidManifest.xml.meta +++ b/Assets/Plugins/Android/AndroidManifest.xml.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 683ae343e269e401d9aa8d81710ea743 +guid: b2e24f251cb7842debe2bec6232b5b2d TextScriptImporter: externalObjects: {} userData: diff --git a/Assets/TKGSDK/Common/GameInterface/TKGSDKManager.cs b/Assets/TKGSDK/Common/GameInterface/TKGSDKManager.cs index 10abd70c..29c96190 100644 --- a/Assets/TKGSDK/Common/GameInterface/TKGSDKManager.cs +++ b/Assets/TKGSDK/Common/GameInterface/TKGSDKManager.cs @@ -3,6 +3,9 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using Touka; +#if USE_IAP +using UnityEngine.Purchasing; +#endif public class TKGSDKManager : TKGSingleton { @@ -19,6 +22,7 @@ public class TKGSDKManager : TKGSingleton } } } + private bool mIsNoAllAD = false; public bool IsRemoveAds @@ -34,6 +38,7 @@ public class TKGSDKManager : TKGSingleton } } } + private bool mIsRemoveAds = false; public bool IsIAPEnabled @@ -65,6 +70,12 @@ public class TKGSDKManager : TKGSingleton private bool isInit = false; + /// + /// 支付成功时回调 + /// orderID, productName, productID, purchaseResult, gameExtra + /// + public Action OnPurchaseDone; + private ITKGSDK m_sdkInterface; protected override void OnInstanceCreate() @@ -81,17 +92,23 @@ public class TKGSDKManager : TKGSingleton public void InitSDK(Action _initCallback = null) { if (isInit) return; - + +#if USE_IAP + TKGDebugger.LogDebug("USE_IAP = True"); + IAPTool.Instance.PreInitialize(); +#else + TKGDebugger.LogDebug("USE_IAP = False"); +#endif m_sdkInterface.InitSDK(_initCallback); isInit = true; mLoginCount++; - if (IsIAPEnabled) - { + //if (IsIAPEnabled) + //{ #if USE_IAP - IAPTool.Instance.Initialize(); + IAPTool.Instance.Initialize(); #endif - } + //} } /// @@ -109,6 +126,13 @@ public class TKGSDKManager : TKGSingleton m_sdkInterface.SetRewardClickListener(_clickCallback); } + // ads revenue callback + // adsType, price, currency + public void SetAdsRevenueCallback(Action _adsRevenueCallback) + { + TKGSDKCallback.SetAdsRevenueCallback(_adsRevenueCallback); + } + /// /// Get channel /// @@ -128,11 +152,13 @@ public class TKGSDKManager : TKGSingleton } #region Ads + // 去广告接口调用 public void PurchasedRemoveAds() { m_sdkInterface.PurchasedRemoveAds(); } + /// /// Show Interstitial Ad /// @@ -140,6 +166,11 @@ public class TKGSDKManager : TKGSingleton /// Callback of interstitial ad close and show interstitial failed /// IVADType for distinguish interstitial ads frequency, default use iv1 public void ShowInterstitialAd(TKGIVAdPositionName _adPos, Action _callback = null, IVADType _IvType = IVADType.IV1) + { + ShowInterstitialAd(_adPos.ToString(), _callback, _IvType); + } + + public void ShowInterstitialAd(string _adPos, Action _callback = null, IVADType _IvType = IVADType.IV1) { #if UNITY_EDITOR || NO_AD if (null != _callback) @@ -147,6 +178,7 @@ public class TKGSDKManager : TKGSingleton Debug.Log("Need Show IV, in editor directly invoke callback."); _callback.Invoke(); } + return; #endif @@ -166,13 +198,21 @@ public class TKGSDKManager : TKGSingleton /// Name of reward ad placement /// true:reward succ, false: reward failed /// Callback of reward ad show fail - public void ShowRewardAd(TKGRVPositionName _adPos, Action _rewardCallback = null, Action _showFailedCallback = null, bool showSDKToast = false) + public void ShowRewardAd(TKGRVPositionName _adPos, Action _rewardCallback = null, + Action _showFailedCallback = null, bool showSDKToast = false) + { + ShowRewardAd(_adPos.ToString(), _rewardCallback, _showFailedCallback, showSDKToast); + } + + public void ShowRewardAd(string _adPos, Action _rewardCallback = null, Action _showFailedCallback = null, + bool showSDKToast = false) { #if UNITY_EDITOR || NO_AD if (null != _rewardCallback) { _rewardCallback.Invoke(true); } + return; #endif @@ -193,7 +233,7 @@ public class TKGSDKManager : TKGSingleton if (!IsNoAllAD && !IsRemoveAds) { m_sdkInterface.ShowNativeAd(pRect, pCam, pAdPos); - } + } #endif } @@ -203,9 +243,7 @@ public class TKGSDKManager : TKGSingleton /// public bool IsReadyInterstitialAd() { - return m_sdkInterface.IsReadyInterstitialAd(); - } /// @@ -261,11 +299,11 @@ public class TKGSDKManager : TKGSingleton m_sdkInterface.RemoveNativeAd(); } -#endregion + #endregion -#region Log Event + #region Log Event -#region Normal + #region Normal /// /// Log Event @@ -274,7 +312,6 @@ public class TKGSDKManager : TKGSingleton public void LogEvent(string _eventSort) { m_sdkInterface.LogEvent(_eventSort); - } /// @@ -311,9 +348,9 @@ public class TKGSDKManager : TKGSingleton m_sdkInterface.LogEvent(_eventSort, _eventDic); } -#endregion + #endregion -#region Level Event + #region Level Event /// /// Level start @@ -355,7 +392,7 @@ public class TKGSDKManager : TKGSingleton if (_stageResult == StageResult.StageSucc) { mPassCount++; -#if UNITY_IOS//only ios has review popup +#if UNITY_IOS //only ios has review popup return !CheckReviewPop(mPassCount); #endif } @@ -387,9 +424,10 @@ public class TKGSDKManager : TKGSingleton return false; } -#endregion -#region Reward Ad Button Show + #endregion + + #region Reward Ad Button Show /// /// Log Reward ad button show @@ -400,9 +438,9 @@ public class TKGSDKManager : TKGSingleton m_sdkInterface.LogRewardAdBtnShow(_pos); } -#endregion + #endregion -#region Tracking Event + #region Tracking Event /// /// Log Tracking Event @@ -413,20 +451,24 @@ public class TKGSDKManager : TKGSingleton //m_sdkInterface.LogTrackingEvent(_eventType); } -#endregion + #endregion -#endregion + #endregion -#region Online Config + #region Online Config /// /// get config - string /// /// /// + public string GetConfigStr(string _key) + { + return m_sdkInterface.GetConfigStr(_key); + } + public string GetConfigStr(TKGParamKey _key) { - return m_sdkInterface.GetConfigStr(_key.ToString()); } @@ -435,9 +477,13 @@ public class TKGSDKManager : TKGSingleton /// /// /// + public int GetConfigInt(string _key) + { + return m_sdkInterface.GetConfigInt(_key); + } + public int GetConfigInt(TKGParamKey _key) { - return m_sdkInterface.GetConfigInt(_key.ToString()); } @@ -447,14 +493,19 @@ public class TKGSDKManager : TKGSingleton /// /// /// + public bool GetConfigBool(string _key) + { + return m_sdkInterface.GetConfigBool(_key); + } + public bool GetConfigBool(TKGParamKey _key) { return m_sdkInterface.GetConfigBool(_key.ToString()); } -#endregion + #endregion -#region Others (common) + #region Others (common) /// /// review @@ -495,6 +546,38 @@ public class TKGSDKManager : TKGSingleton m_sdkInterface.OpenMoreGame(); } + /// + /// show picture cross + /// + public bool showPictureCross() + { + return m_sdkInterface.showPictureCross(); + } + + /// + /// remove picture cross + /// + public void removePictureCross() + { + m_sdkInterface.removePictureCross(); + } + + /// + /// show more game icon + /// + public bool showMoreGameIcon() + { + return m_sdkInterface.showMoreGameIcon(); + } + + /// + /// remove more game icon + /// + public void removeMoreGameIcon() + { + m_sdkInterface.removeMoreGameIcon(); + } + /// /// open url by browser /// @@ -519,6 +602,40 @@ public class TKGSDKManager : TKGSingleton m_sdkInterface.Shake(_shakeType, _intensity); } + /// + /// if is debug mode + /// + public bool IsDebugMode() + { + return m_sdkInterface.IsDebugMode(); + } + + /// + /// get user name and user id card + /// format will be "Jack_654121199212099999" + /// + public string GetUserNameAndUserIDCard() + { + return m_sdkInterface.GetUserNameAndUserIDCard(); + } + + /// + /// set segment type to sdk + /// + /// segment type + public void SetSegment(SegmentType type) + { + m_sdkInterface.SetSegment(type); + } + + /// + /// get a iap product list for sdk config file + /// + public Dictionary GetIAPProductList() + { + return m_sdkInterface.GetIAPProductList(); + } + /// /// share txt /// @@ -533,7 +650,6 @@ public class TKGSDKManager : TKGSingleton /// public void RegistAPNS() { - m_sdkInterface.RegistAPNS(); } @@ -546,10 +662,10 @@ public class TKGSDKManager : TKGSingleton /// The application badge number. /// The title of the notification. /// The subtitle of the notification. - public void RegistNotification(string notiId, string body, string fireDate, int badge = 1, string title = "", string subTitle = "") + public void RegistNotification(string notiId, string body, string fireDate, int badge = 1, string title = "", + string subTitle = "") { - - m_sdkInterface.RegistNotification(notiId,body,fireDate,badge,title,subTitle); + m_sdkInterface.RegistNotification(notiId, body, fireDate, badge, title, subTitle); } /// @@ -557,7 +673,6 @@ public class TKGSDKManager : TKGSingleton /// public void RemoveAllNotifications() { - m_sdkInterface.RemoveAllNotifications(); } @@ -567,9 +682,9 @@ public class TKGSDKManager : TKGSingleton /// notification identifier public void RemoveNotification(string notiId) { - m_sdkInterface.RemoveNotification(notiId); } + #endregion #region others @@ -609,5 +724,342 @@ public class TKGSDKManager : TKGSingleton m_sdkInterface.SetTKGCommonCallback(_commonCallbackAction); } + /// + /// 注册功能开关回调 + /// + /// 各功能名称 + /// 回调事件,回来每个功能名称及对应开关 + public void SetFunctionSwitchListener(List _functionKeys, + Action _functionSwitchCallback) + { + m_sdkInterface.SetFunctionSwitchListener(_functionKeys, _functionSwitchCallback); + } + + #endregion + + #region 数据中台 + + /// + /// 内购成功后上报价格 + /// + /// 商品价格 + public void LogPurchasePrice(string price, string currency) + { + m_sdkInterface.LogPurchasePrice(price, currency); + } + + /// + /// Robux点击提现按钮 + /// + public void LogRobuxCashOut() + { + m_sdkInterface.LogRobuxCashOut(); + } + + /// + /// 完成新手引导 + /// + public void LogNoviceGuideFinish() + { + m_sdkInterface.LogNoviceGuideFinish(); + } + + #endregion + + #region GooglePlay评论引导 + + /// + /// Pop up GooglePlay Rate guid + /// + public bool GuidGpComment() + { + return m_sdkInterface.GuidGpComment(); + } + + #endregion + + + #region 用户登录 + + /// + /// User Login + /// + /// 登录类型 + /// 登录回调Action<登录状态码,登录类型,登录状态信息,userid,token,邮箱 , 显示名称 , 头像url + public void Login(LoginType _loginType, + Action _loginResultCallback = null) + { + m_sdkInterface.Login(_loginType, _loginResultCallback); + } + + /// + /// 自动根据上次登陆的类型进行登陆,登陆失败需要跳转到登陆界面。 + /// + /// + public void AutoLogin( + Action _loginResultCallback = null) + { + m_sdkInterface.AutoLogin(_loginResultCallback); + } + + /// + /// 获取当前账号类型。 用于显示绑定界面。 + /// + /// + public LoginType GetAccountType() + { + return m_sdkInterface.GetAccountType(); + } + + /// + /// 是否可以自动登陆 + /// + /// + public bool IsCanAutoLogin() + { + return m_sdkInterface.IsCanAutoLogin(); + } + + /// + /// Logout + /// + /// + public void Logout(Action _logoutCallback = null) + { + m_sdkInterface.Logout(_logoutCallback); + } + + /// + /// Obtain a list of login channels, + /// and the game displays the obtained login list for users to choose to log in. + /// + /// available login channels + public List AvailableLoginChannelList() + { + return m_sdkInterface.AvailableLoginChannelList(); + } + + /// + /// user actively deletes account. + /// + /// Return the deleted userId. If the game needs to record it, you can operate it in the action. + /// + /// code Delete userId + public void DeleteAccount(Action deleteAccountCallback = null) + { + m_sdkInterface.DeleteAccount(deleteAccountCallback); + } + + /// + /// Social account binding for Guester. + /// 游客绑定社交账号 + /// + /// 游戏发起社交账号的绑定: + /// 根据 Action中的BindAccountStatus判断 + /// 如果 BindAccountStatus == BindAccountStatus.BIND_CODE_SUCC + /// 需要判断userId和当前userId是否一致,如果不一致,需要切换账号,或者重启游戏。如果一致,无需操作。 + /// 如果 BindAccountStatus == BindAccountStatus.BIND_CODE_SELECT + /// 这个是因为第三方账号已经被绑定过了,string[] 中将会返回已经绑定的userId,和当前userId,游戏需要展示出来提供给玩家选择, + /// 玩家选择完成后,需要将 + /// + /// 其情况,游戏做相应操作 + /// + /// + /// + /// + /// 社交账号类型 + /// 是否强制绑定 + /// 绑定的userId + /// 回调的信息 + private void BindAccount(LoginType type, BindType isForce = BindType.NO_FORCE, string userId = + "", Action bindAccountCallback + = null) + { + m_sdkInterface.BindAccount(type, isForce, userId, bindAccountCallback); + } + + private LoginType bindLoginType = LoginType.LOGIN_BY_GUESTER; + + /// + /// Social account binding for Guester. + /// + /// 情况一 : bindAccountStatusEnum == BindAccountStatus.BIND_CODE_SUCC 绑定成功 + /// 绑定成功的时候,需要获取 userId和当前userId是否一致, 如果不一致,需要重新切换到新的userId账号上来。 (切换账号) + /// 情况二 : BindAccountStatus == BindAccountStatus.BIND_CODE_SELECT 社交账号已经绑定了其他账号 (社交账号已经在其他设备上登陆) + /// 需要获取到userIdList 里面的userId列表,获取到userId对应的角色/关卡信息,展示出来供玩家选择。 玩家选择完成之后调用 `ForceBindAccount` 接口将选中的userId传递进去,进行强制绑定 + /// ⚠️ 如果选择的是当前账号强制绑定,那么社交账号原有的账号将会被删除 + /// 如果选择的是社交账号关联的账号,那么当前账号将会被删除 + /// + /// + /// + /// 社交账号类型 + /// bindAccountStatusEnum, loginTypeEnum, _msg, _userId, _token, _email,_displayName, _photoUrl, userIdList + public void BindAccount(LoginType type, + Action + bindAccountCallback = null) + { + bindLoginType = type; + BindAccount(type, isForce: BindType.NO_FORCE, userId: "", bindAccountCallback); + } + + public void ForceBindAccount(string userId, Action + bindAccountCallback = null) + { + BindAccount(bindLoginType, BindType.FORCE, userId, bindAccountCallback); + } + + #endregion + + #region IAP Event + + /// + /// Log IAP button show + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + public void LogIAPBtnShow(string productName, string productId) + { + m_sdkInterface.LogIAPBtnShow(productName, productId); + } + + #endregion + + #region 保存数据 + + /// + /// 保存数据到账号上去(云存储) + /// + /// string内容存储 + /// 上传结果 + public void SaveCloudArchiving(string content,Action callback) + { + m_sdkInterface.SaveCloudArchiving(content, callback); + } + + /// + /// 获取云存储的当前账号数据 + /// + /// + public void DetailCloudArchiving(Action callback) + { + m_sdkInterface.DetailCloudArchiving(callback); + } + + #endregion + + #region IAP + + /// + /// Add payment result callback; + /// orderID, productName, productID, purchaseResult, gameExtra + /// + /// Purchase result callback + public void SetOnPurchaseDone(Action onPurchaseDoneAction) + { + OnPurchaseDone = onPurchaseDoneAction; + } + +#if USE_IAP + /// + /// Commodity information acquisition callback; + /// + /// All product information + /// ex: + /// Product[0].metadata.localizedTitle + /// Product[0].metadata.localizedPriceString + /// Product[0].metadata.localizedDescription + /// Product[0].metadata.isoCurrencyCode + public void OnGetProductsInfo(Action onGetProductsInfo) + { +#if USE_IAP + IAPTool.Instance.OnGetProductsInfo += onGetProductsInfo; +#endif + } + + + /// + /// Get product info by product id; + /// + /// Product ID + /// Product Info metadata + public Product GetProductInfoByID(string productID) + { +#if USE_IAP + return IAPTool.Instance.GetProductInfoByID(productID); +#else + return null; +#endif + } +#endif + + /// + /// Get product price by product id; + /// + /// Product ID + /// Product price + public string GetPriceByID(string productID) + { +#if USE_IAP + return IAPTool.Instance.GetPriceByID(productID); +#else + return ""; +#endif + } + + #if USE_IAP + /// + ///[In-game props,gold,gift packs, etc.] Purchase products according to the product ID; + /// + /// Product ID + /// Product ID + /// Purchase result callback + /// Product ID + public void BuyProductByID(string productId, string enProductName, string gameExtraParam = "") + { +#if USE_IAP + IAPTool.Instance.BuyProductByID(productId, enProductName, gameExtraParam); +#endif + } +#endif + +#if USE_IAP + /// + /// Add products ID dynamically; + /// + /// Product IDs + /// bool Is it added successfully string Additional Information + public void AddProducts(Dictionary products) + { +#if USE_IAP + IAPTool.Instance.AddProducts(products); +#endif + } +#endif + + /// + /// Restore Purchases; + /// + public void RestorePurchases() + { +#if USE_IAP + IAPTool.Instance.RestorePurchases(); +#endif + } + #endregion -} \ No newline at end of file + +#region serve for wz + + /// + /// Set userid and third account + /// + /// userID (Unique user id) + /// third account + /// third account type + public void SetUserIDAndThirdAccount(string _userID, string _thirdAccount, ThirdAccountType _thirdAccountType) + { + Debug.Log("【TKGNativeInterfaceAndroid】 SetUserIDAndThirdAccount _userID : " + _userID + " , _thirdAccount : " + _thirdAccount + " , _thirdAccountType : " + _thirdAccountType); + TKGNativeInterface.Instance.SetUserIDAndThirdAccount(_userID, _thirdAccount, _thirdAccountType); + } +#endregion + } \ No newline at end of file diff --git a/Assets/TKGSDK/Common/SDKTools/IAPTool.cs b/Assets/TKGSDK/Common/SDKTools/IAPTool.cs index 0baf0bfa..a951bc4e 100644 --- a/Assets/TKGSDK/Common/SDKTools/IAPTool.cs +++ b/Assets/TKGSDK/Common/SDKTools/IAPTool.cs @@ -4,362 +4,729 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.Purchasing; using Touka; +using UnityEngine.Purchasing.Extension; +using Unity.Services.Core; +using Unity.Services.Core.Environments; -public class IAPTool : NormalSingleton, IStoreListener +namespace Touka { - public event Action OnPurchaseBegin; - public event Action OnPurchaseDone; - public event Action OnRestoreDone; + public class IAPTool : NormalSingleton, IDetailedStoreListener + { + /// + /// 获取到在AppStore和Google Play 上配置的商品时回调 + /// 游戏可根据返回的商品列表进行商品UI的展示或隐藏 + /// + public event Action OnGetProductsInfo; - public bool IsRestoring => mIsRestoring; - private bool mIsRestoring = false; + /// + /// 拉起支付窗口,开始支付流程时回调 + /// + public event Action OnPurchaseBegin; - private static IStoreController m_StoreController; // 存储商品信息; - private static IExtensionProvider m_StoreExtensionProvider; // IAP扩展工具; - private bool m_PurchaseInProgress = false; // 是否处于付费中; + - private Dictionary mInitProductDic; - private SubscriptionInfo mSubsInfo = null; + private static string mProductName = ""; + private static string mGameExtraParam = ""; - public void Initialize() - { - if (m_StoreController == null && m_StoreExtensionProvider == null) - InitUnityPurchase(); - } + /// + /// 恢复购买回调 + /// + public event Action OnRestoreDone; - private bool IsInitialized() - { - return m_StoreController != null && m_StoreExtensionProvider != null; - } + public bool IsRestoring => mIsRestoring; + private bool mIsRestoring = false; - public void AddProducts(Dictionary pInitProductDic) - { - mInitProductDic = pInitProductDic; - } + private static IStoreController m_StoreController; // 存储商品信息; + private static IExtensionProvider m_StoreExtensionProvider; // IAP扩展工具; + private bool m_PurchaseInProgress = false; // 是否处于付费中; - // 初始化IAP; - private void InitUnityPurchase() - { - if (IsInitialized()) return; + private Dictionary mInitProductDic; + private SubscriptionInfo mSubsInfo = null; - // 标准采购模块; - StandardPurchasingModule module = StandardPurchasingModule.Instance(); + private const string Environment = "production"; + private bool mServiceInit = false; - // 配置模式; - ConfigurationBuilder builder = ConfigurationBuilder.Instance(module); + private bool IsFetchingAdditionalProducts = false; - // 注意ProductType的类型,Consumable是可以无限购买(比如水晶),NonConsumable是只能购买一次(比如关卡),Subscription是每月订阅(比如VIP); - // 这里初始化没有添加平台信息,因为平台信息有的时候还存在bug,如果必须添加,也可以添加,没有问题,确保平台信息添加正确就行了。 + private Dictionary mAddProductsDic; - foreach (string tID in IAPProducts.ProductDic.Keys) - { - builder.AddProduct(tID, IAPProducts.ProductDic[tID]); - } - if (mInitProductDic != null && mInitProductDic.Count > 0) - { - foreach (string tID in mInitProductDic.Keys) - { - builder.AddProduct(tID, mInitProductDic[tID]); - } - } - - //初始化; - UnityPurchasing.Initialize(this, builder); - } + /// + /// 初始化UnityServices + /// + public void PreInitialize() + { + TKGDebugger.LogDebug("PreInitialize() mServiceInit: " + mServiceInit); + if (!mServiceInit) + { + InitializeUnityServices(OnSuccess, OnError); + } + } + + /// + /// 初始化IAP + /// + public void Initialize() + { + TKGDebugger.LogDebug("IAP Initialize() m_StoreController:" + m_StoreController + + " m_StoreExtensionProvider: " + m_StoreExtensionProvider); + if (m_StoreController == null && m_StoreExtensionProvider == null) + InitUnityPurchase(); + } + + private bool IsInitialized() + { + return m_StoreController != null && m_StoreExtensionProvider != null; + } + + /// + /// IAP初始化后,可使用此接口,添加新增商品id + /// + /// 商品IDs + /// bool:添加新增商品id结果 string:附加信息 + [Obsolete( + "AddProducts(Dictionary products, Action onProductsResult = null) is deprecated, please use TKGSDKManager.Instance.BuyProductByID(string productId) instead.")] + public void AddProducts(Dictionary products, Action onProductsResult = null) + { + mInitProductDic = products; + + FetchAdditionalProducts(products, onProductsResult); + } + + /// + /// 初始化UnityServices + /// + /// + /// + private void InitializeUnityServices(Action onSuccess, Action onError) + { + try + { + var options = new InitializationOptions().SetEnvironmentName(Environment); + + UnityServices.InitializeAsync(options).ContinueWith(task => onSuccess()); + } + catch (Exception exception) + { + onError(exception.Message); + } + } + + void OnSuccess() + { + var text = "Congratulations!\nUnity Gaming Services has been successfully initialized."; + TKGDebugger.LogDebug(text); + mServiceInit = true; + } + + void OnError(string message) + { + var text = $"Unity Gaming Services failed to initialize with error: {message}."; + TKGDebugger.LogError(text); + } + + + // 初始化IAP; + private void InitUnityPurchase() + { + TKGDebugger.LogDebug("IAP InitUnityPurchase() IsInitialized: " + IsInitialized()); + if (IsInitialized()) return; + + // 标准采购模块; + StandardPurchasingModule module = StandardPurchasingModule.Instance(); + + // 配置模式; + ConfigurationBuilder builder = ConfigurationBuilder.Instance(module); + + // 注意ProductType的类型,Consumable是可以无限购买(比如水晶),NonConsumable是只能购买一次(比如关卡),Subscription是每月订阅(比如VIP); + // 这里初始化没有添加平台信息,因为平台信息有的时候还存在bug,如果必须添加,也可以添加,没有问题,确保平台信息添加正确就行了。 + int productsNum = 0; + foreach (string tID in IAPProducts.ProductDic.Keys) + { + productsNum++; + if (!string.IsNullOrEmpty(tID)) + { + TKGDebugger.LogDebug($"Add IAPProducts IAPProducts: {tID}"); + builder.AddProduct(tID, IAPProducts.ProductDic[tID]); + } + } + + if (mInitProductDic != null && mInitProductDic.Count > 0) + { + foreach (string tID in mInitProductDic.Keys) + { + productsNum++; + if (!string.IsNullOrEmpty(tID)) + { + TKGDebugger.LogDebug($"Add InitProductDic APProducts: {tID}"); + builder.AddProduct(tID, mInitProductDic[tID]); + } + } + } + + if (mAddProductsDic != null && mAddProductsDic.Count > 0) + { + foreach (string tID in mAddProductsDic.Keys) + { + productsNum++; + if (!string.IsNullOrEmpty(tID)) + { + TKGDebugger.LogDebug($"Add AddProductsDic IAPProducts: {tID}"); + builder.AddProduct(tID, mAddProductsDic[tID]); + } + } + } + + if (productsNum > 0) + { + //初始化; + UnityPurchasing.Initialize(this, builder); + } + else + { + TKGDebugger.LogDebug( + "UnityPurchasing will not initialize.Products is empty,please invoke TKGSDKManager.Instance.BuyProductByID(string productId) add product."); + } + } + + /// + /// 批量获取其他产品 + /// + private void FetchAdditionalProducts(Dictionary ProductDic, + Action onProductsResult = null) + { + if (!IsInitialized()) + { + mAddProductsDic = ProductDic; + TKGDebugger.LogDebug("IAP not init.Now InitUnityPurchase"); + InitUnityPurchase(); + return; + } + + if (IsFetchingAdditionalProducts) + { + TKGDebugger.LogDebug("Now fetching additional products,don't call repeatedly"); + if (onProductsResult != null) + { + onProductsResult(false, "Now fetching additional products,don't call repeatedly"); + } + + return; + } + + IsFetchingAdditionalProducts = true; + if (ProductDic != null) + { + var additional = new HashSet(); + foreach (string tID in ProductDic.Keys) + { + additional.Add(new ProductDefinition(tID, ProductDic[tID])); + } + + Action onSuccess = () => + { + IsFetchingAdditionalProducts = false; + + TKGDebugger.LogDebug("Fetched successfully!"); + if (OnGetProductsInfo != null) + { + OnGetProductsInfo(m_StoreController.products.all); + } + + foreach (var product in m_StoreController.products.all) + { + TKGDebugger.LogDebug(product.metadata.localizedTitle + + "|" + product.metadata.localizedPriceString + + "|" + product.metadata.localizedDescription + + "|" + product.metadata.isoCurrencyCode); + } + + if (onProductsResult != null) + { + onProductsResult(true, "Fetched successfully!"); + } + }; + + Action onFailure = (InitializationFailureReason i, string msg) => + { + IsFetchingAdditionalProducts = false; + if (onProductsResult != null) + { + onProductsResult(true, "Fetching failed for the specified reason: " + i + " msg: " + msg); + } + + Debug.Log("Fetching failed for the specified reason: " + i + " msg: " + msg); + }; + + m_StoreController.FetchAdditionalProducts(additional, onSuccess, onFailure); + } + } + #region Public Func - // 根据ID给购买商品; - public void BuyProductByID(string productId) - { - if (IsInitialized()) - { - if (m_PurchaseInProgress == true) return; - Product product = m_StoreController.products.WithID(productId); - if (product != null && product.availableToPurchase) - { - OnPurchaseBegin?.Invoke(); - m_PurchaseInProgress = true; - TKGDebugger.LogDebug(string.Format("Purchasing product asychronously: '{0}'", product.definition.id)); - m_StoreController.InitiatePurchase(product); - } - else - { - TKGDebugger.LogDebug("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase"); - } - } - else - { - TKGDebugger.LogDebug("BuyProductID FAIL. Not initialized."); - } - } + /// + /// 根据商品ID 购买商品; + /// + /// 商品ID + [Obsolete( + "BuyProductByID(string productId) is deprecated, please use TKGSDKManager.Instance.BuyProductByID(string productId) instead.")] + public void BuyProductByID(string productId, string productName, string gameExtraParam) + { + mProductName = productName; + mGameExtraParam = gameExtraParam; - // 确认购买产品成功; - public void DoConfirmPendingPurchaseByID(string productId) - { - Product product = m_StoreController.products.WithID(productId); - if (product != null && product.availableToPurchase) - { - if (m_PurchaseInProgress) - { - m_StoreController.ConfirmPendingPurchase(product); - m_PurchaseInProgress = false; - } - } - } + TKGNativeInterface.Instance.LogIAPBtnClick(productName, productId); + + // 设置监听购买二次验证的回调 + TKGSDKCallback.SetSecondPurchaseCallback(TKGSDKManager.Instance.OnPurchaseDone); + + if (IsInitialized()) + { + if (m_PurchaseInProgress) + { + TKGDebugger.LogDebug("The payment is in progress, please do not initiate the payment repeatedly."); + return; + } + + Product product = m_StoreController.products.WithID(productId); + if (product != null && product.availableToPurchase) + { + OnPurchaseBegin?.Invoke(); + m_PurchaseInProgress = true; + TKGDebugger.LogDebug( + string.Format("Purchasing product asychronously: '{0}'", product.definition.id)); + m_StoreController.InitiatePurchase(product); + } + else + { + TKGDebugger.LogDebug( + "BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase"); + TKGNativeInterface.Instance.ClientIAPFailed(mProductName, productId, "", "", "", "", mGameExtraParam, IAPClientFailReasonType.NotInit); + + } + } + else + { + TKGDebugger.LogDebug("BuyProductID FAIL. IAP Not initialized or Not add product."); + //OnPurchaseDone?.Invoke(productId, false, "", ""); + + TKGDebugger.LogDebug("OnPurchaseFailed -> productId : " + productId + " , transactionID : " + "" + " , localizedPrice : " + "" + " , isoCurrencyCode : " + ""); + TKGNativeInterface.Instance.ClientIAPFailed(mProductName, productId, "", "", "", "", mGameExtraParam, IAPClientFailReasonType.NotInit); + + } + } + + // 确认购买产品成功; + private void DoConfirmPendingPurchaseByID(string productId) + { + Product product = m_StoreController.products.WithID(productId); + if (product != null && product.availableToPurchase) + { + if (m_PurchaseInProgress) + { + m_StoreController.ConfirmPendingPurchase(product); + m_PurchaseInProgress = false; + } + } + } + + /// + /// 恢复购买 + /// + [Obsolete("RestorePurchases() is deprecated, please use TKGSDKManager.Instance.RestorePurchases() instead.")] + public void RestorePurchases() + { + if (!IsInitialized()) + { + OnRestoreDone?.Invoke(false); + TKGDebugger.LogDebug("RestorePurchases FAIL. Not initialized."); + return; + } + + if (Application.platform == RuntimePlatform.IPhonePlayer || + Application.platform == RuntimePlatform.OSXPlayer) + { + TKGDebugger.LogDebug("RestorePurchases started ..."); + mIsRestoring = true; + var apple = m_StoreExtensionProvider.GetExtension(); + apple.RestoreTransactions((result, msg) => + { + mIsRestoring = false; + OnRestoreDone?.Invoke(result); + // 返回一个bool值,如果成功,则会多次调用支付回调,然后根据支付回调中的参数得到商品id,最后做处理(ProcessPurchase); + TKGDebugger.LogDebug("RestorePurchases continuing: " + result + "msg:" + msg + + " If no further messages, no purchases available to restore."); + }); + } + else + { + TKGDebugger.LogDebug("RestorePurchases FAIL. Not supported on this platform. Current = " + + Application.platform); + } + } - // 恢复购买; - public void RestorePurchases() - { - if (!IsInitialized()) - { - OnRestoreDone?.Invoke(false); - TKGDebugger.LogDebug("RestorePurchases FAIL. Not initialized."); - return; - } - if (Application.platform == RuntimePlatform.IPhonePlayer || - Application.platform == RuntimePlatform.OSXPlayer) - { - TKGDebugger.LogDebug("RestorePurchases started ..."); - mIsRestoring = true; - var apple = m_StoreExtensionProvider.GetExtension(); - apple.RestoreTransactions((result) => { - mIsRestoring = false; - OnRestoreDone?.Invoke(result); - // 返回一个bool值,如果成功,则会多次调用支付回调,然后根据支付回调中的参数得到商品id,最后做处理(ProcessPurchase); - TKGDebugger.LogDebug("RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore."); - }); - } - else - { - TKGDebugger.LogDebug("RestorePurchases FAIL. Not supported on this platform. Current = " + Application.platform); - } - } #endregion #region IStoreListener Callback - // IAP初始化成功回掉函数; - public void OnInitialized(IStoreController controller, IExtensionProvider extensions) - { - TKGDebugger.LogDebug("IAP initialize Succeed!"); - m_StoreController = controller; - m_StoreExtensionProvider = extensions; + // IAP初始化成功回调函数; + public void OnInitialized(IStoreController controller, IExtensionProvider extensions) + { + TKGDebugger.LogDebug("IAP initialize Succeed!"); - // 这里可以获取您在AppStore和Google Play 上配置的商品; - ProductCollection products = m_StoreController.products; - Product[] all = products.all; - for (int i = 0; i < all.Length; i++) - { - TKGDebugger.LogDebug(all[i].metadata.localizedTitle + "|" + all[i].metadata.localizedPriceString + "|" + all[i].metadata.localizedDescription + "|" + all[i].metadata.isoCurrencyCode); - } + m_StoreController = controller; + m_StoreExtensionProvider = extensions; + + // 这里可以获取您在AppStore和Google Play 上配置的商品; + if (OnGetProductsInfo != null) + { + OnGetProductsInfo(m_StoreController.products.all); + } + + + foreach (var product in m_StoreController.products.all) + { + TKGDebugger.LogDebug(product.metadata.localizedTitle + + "|" + product.metadata.localizedPriceString + + "|" + product.metadata.localizedDescription + + "|" + product.metadata.isoCurrencyCode); + } #if UNITY_IOS m_StoreExtensionProvider.GetExtension().RegisterPurchaseDeferredListener(OnDeferred); #endif -/* - Dictionary introductory_info_dict = null; + /* + Dictionary introductory_info_dict = null; #if UNITY_IOS - introductory_info_dict = m_StoreExtensionProvider.GetExtension().GetIntroductoryPriceDictionary(); + introductory_info_dict = m_StoreExtensionProvider.GetExtension().GetIntroductoryPriceDictionary(); #endif - TKGDebugger.LogDebug("IAP - Available items:"); - foreach (var item in controller.products.all) - { - if (item.availableToPurchase) - { - TKGDebugger.LogDebug("IAP - " + string.Join(" - ", - new[] - { - item.metadata.localizedTitle, - item.metadata.localizedDescription, - item.metadata.isoCurrencyCode, - item.metadata.localizedPrice.ToString(), - item.metadata.localizedPriceString, - item.transactionID, - item.receipt - })); + TKGDebugger.LogDebug("IAP - Available items:"); + foreach (var item in controller.products.all) + { + if (item.availableToPurchase) + { + TKGDebugger.LogDebug("IAP - " + string.Join(" - ", + new[] + { + item.metadata.localizedTitle, + item.metadata.localizedDescription, + item.metadata.isoCurrencyCode, + item.metadata.localizedPrice.ToString(), + item.metadata.localizedPriceString, + item.transactionID, + item.receipt + })); - // this is the usage of SubscriptionManager class - if (item.receipt != null) - { - if (item.definition.type == ProductType.Subscription) - { - if (CheckIfProductIsAvailableForSubscriptionManagerC(item.receipt)) - { - string intro_json = (introductory_info_dict == null || !introductory_info_dict.ContainsKey(item.definition.storeSpecificId)) ? null : introductory_info_dict[item.definition.storeSpecificId]; - SubscriptionManager p = new SubscriptionManager(item, intro_json); - SubscriptionInfo info = p.getSubscriptionInfo(); - mSubsInfo = info; - TKGDebugger.LogDebug("product id is: " + info.getProductId()); - TKGDebugger.LogDebug("purchase date is: " + info.getPurchaseDate()); - TKGDebugger.LogDebug("subscription next billing date is: " + info.getExpireDate()); - TKGDebugger.LogDebug("is subscribed? " + info.isSubscribed().ToString()); - TKGDebugger.LogDebug("is expired? " + info.isExpired().ToString()); - TKGDebugger.LogDebug("is cancelled? " + info.isCancelled()); - TKGDebugger.LogDebug("product is in free trial peroid? " + info.isFreeTrial()); - TKGDebugger.LogDebug("product is auto renewing? " + info.isAutoRenewing()); - TKGDebugger.LogDebug("subscription remaining valid time until next billing date is: " + info.getRemainingTime()); - TKGDebugger.LogDebug("is this product in introductory price period? " + info.isIntroductoryPricePeriod()); - TKGDebugger.LogDebug("the product introductory localized price is: " + info.getIntroductoryPrice()); - TKGDebugger.LogDebug("the product introductory price period is: " + info.getIntroductoryPricePeriod()); - TKGDebugger.LogDebug("the number of product introductory price period cycles is: " + info.getIntroductoryPricePeriodCycles()); - } - else - { - TKGDebugger.LogDebug("This product is not available for SubscriptionManager class, only products that are purchase by 1.19+ SDK can use this class."); + // this is the usage of SubscriptionManager class + if (item.receipt != null) + { + if (item.definition.type == ProductType.Subscription) + { + if (CheckIfProductIsAvailableForSubscriptionManagerC(item.receipt)) + { + string intro_json = (introductory_info_dict == null || !introductory_info_dict.ContainsKey(item.definition.storeSpecificId)) ? null : introductory_info_dict[item.definition.storeSpecificId]; + SubscriptionManager p = new SubscriptionManager(item, intro_json); + SubscriptionInfo info = p.getSubscriptionInfo(); + mSubsInfo = info; + TKGDebugger.LogDebug("product id is: " + info.getProductId()); + TKGDebugger.LogDebug("purchase date is: " + info.getPurchaseDate()); + TKGDebugger.LogDebug("subscription next billing date is: " + info.getExpireDate()); + TKGDebugger.LogDebug("is subscribed? " + info.isSubscribed().ToString()); + TKGDebugger.LogDebug("is expired? " + info.isExpired().ToString()); + TKGDebugger.LogDebug("is cancelled? " + info.isCancelled()); + TKGDebugger.LogDebug("product is in free trial peroid? " + info.isFreeTrial()); + TKGDebugger.LogDebug("product is auto renewing? " + info.isAutoRenewing()); + TKGDebugger.LogDebug("subscription remaining valid time until next billing date is: " + info.getRemainingTime()); + TKGDebugger.LogDebug("is this product in introductory price period? " + info.isIntroductoryPricePeriod()); + TKGDebugger.LogDebug("the product introductory localized price is: " + info.getIntroductoryPrice()); + TKGDebugger.LogDebug("the product introductory price period is: " + info.getIntroductoryPricePeriod()); + TKGDebugger.LogDebug("the number of product introductory price period cycles is: " + info.getIntroductoryPricePeriodCycles()); + } + else + { + TKGDebugger.LogDebug("This product is not available for SubscriptionManager class, only products that are purchase by 1.19+ SDK can use this class."); + } + } + else + { + TKGDebugger.LogDebug("the product is not a subscription product"); + } + } + else + { + TKGDebugger.LogDebug("the product should have a valid receipt"); + } } } - else - { - TKGDebugger.LogDebug("the product is not a subscription product"); - } - } - else - { - TKGDebugger.LogDebug("the product should have a valid receipt"); - } - } - } -*/ - } - - // IAP初始化失败回掉函数(没有网络的情况下并不会调起,而是一直等到有网络连接再尝试初始化); - public void OnInitializeFailed(InitializationFailureReason error) - { - switch (error) - { - case InitializationFailureReason.AppNotKnown: - TKGDebugger.LogError("Is your App correctly uploaded on the relevant publisher console?"); - break; - case InitializationFailureReason.PurchasingUnavailable: - TKGDebugger.LogDebug("Billing disabled! Ask the user if billing is disabled in device settings."); - break; - case InitializationFailureReason.NoProductsAvailable: - TKGDebugger.LogDebug("No products available for purchase! Developer configuration error; check product metadata!"); - break; - } - } - - private bool CheckIfProductIsAvailableForSubscriptionManagerC(string receipt) - { - var receipt_wrapper = (Dictionary)MiniJson.JsonDecode(receipt); - if (!receipt_wrapper.ContainsKey("Store") || !receipt_wrapper.ContainsKey("Payload")) - { - TKGDebugger.LogDebug("The product receipt does not contain enough information"); - return false; + */ } - var store = (string)receipt_wrapper ["Store"]; - var payload = (string)receipt_wrapper ["Payload"]; - if (payload != null ) - { - switch (store) - { - case GooglePlay.Name: - { - var payload_wrapper = (Dictionary)MiniJson.JsonDecode(payload); - if (!payload_wrapper.ContainsKey("json")) { - TKGDebugger.LogDebug("The product receipt does not contain enough information, the 'json' field is missing"); - return false; - } - var original_json_payload_wrapper = (Dictionary)MiniJson.JsonDecode((string)payload_wrapper["json"]); - if (original_json_payload_wrapper == null || !original_json_payload_wrapper.ContainsKey("developerPayload")) { - TKGDebugger.LogDebug("The product receipt does not contain enough information, the 'developerPayload' field is missing"); - return false; - } - var developerPayloadJSON = (string)original_json_payload_wrapper["developerPayload"]; - var developerPayload_wrapper = (Dictionary)MiniJson.JsonDecode(developerPayloadJSON); - if (developerPayload_wrapper == null || !developerPayload_wrapper.ContainsKey("is_free_trial") || !developerPayload_wrapper.ContainsKey("has_introductory_price_trial")) { - TKGDebugger.LogDebug("The product receipt does not contain enough information, the product is not purchased using 1.19 or later"); - return false; - } - return true; - } - case AppleAppStore.Name: - case AmazonApps.Name: - case MacAppStore.Name: - { - return true; - } - default: - { - return false; - } + public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription) + { + TKGDebugger.LogError(product.transactionID + "," + failureDescription.productId + "," + + failureDescription.message); + m_PurchaseInProgress = false; + //OnPurchaseDone?.Invoke(product.definition.id, false, "", ""); + + TKGDebugger.LogDebug("productId : " + failureDescription.productId + " , transactionID : " + product.transactionID + " , localizedPrice : " + product.metadata.localizedPriceString + " , isoCurrencyCode : " + product.metadata.isoCurrencyCode); + TKGNativeInterface.Instance.ClientIAPFailed(mProductName, failureDescription.productId, product.transactionID, "", product.metadata.isoCurrencyCode,product.metadata.localizedPrice.ToString(), mGameExtraParam, IAPClientFailReasonType.PurchaseFailed); + } + + public void OnInitializeFailed(InitializationFailureReason error) + { + OnInitializeFailed(error, ""); + } + + // IAP初始化失败回掉函数(没有网络的情况下并不会调起,而是一直等到有网络连接再尝试初始化); +#pragma warning disable CS8632 // 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。 + public void OnInitializeFailed(InitializationFailureReason error, string? message) +#pragma warning restore CS8632 // 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。 + { + TKGDebugger.LogDebug("IAP OnInitializeFailed error:" + error.ToString()); + TKGDebugger.LogDebug("IAP OnInitializeFailed message:" + message); + switch (error) + { + case InitializationFailureReason.AppNotKnown: + TKGDebugger.LogError("Is your App correctly uploaded on the relevant publisher console?"); + break; + case InitializationFailureReason.PurchasingUnavailable: + TKGDebugger.LogDebug("Billing disabled! Ask the user if billing is disabled in device settings."); + break; + case InitializationFailureReason.NoProductsAvailable: + TKGDebugger.LogDebug( + "No products available for purchase! Developer configuration error; check product metadata!"); + break; } } - return false; - } - // 支付成功处理函数; - public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) - { - m_PurchaseInProgress = false; + private bool CheckIfProductIsAvailableForSubscriptionManagerC(string receipt) + { + var receipt_wrapper = (Dictionary)MiniJson.JsonDecode(receipt); + if (!receipt_wrapper.ContainsKey("Store") || !receipt_wrapper.ContainsKey("Payload")) + { + TKGDebugger.LogDebug("The product receipt does not contain enough information"); + return false; + } - TKGDebugger.LogDebug("Purchase OK: " + e.purchasedProduct.definition.id); + var store = (string)receipt_wrapper["Store"]; + var payload = (string)receipt_wrapper["Payload"]; - // 消息结构 : Receipt: {"Store":"fake","TransactionID":"9c5c16a5-1ae4-468f-806d-bc709440448a","Payload":"{ \"this\" : \"is a fake receipt\" }"}; - TKGDebugger.LogDebug("Receipt: " + e.purchasedProduct.receipt); + if (payload != null) + { + switch (store) + { + case GooglePlay.Name: + { + var payload_wrapper = (Dictionary)MiniJson.JsonDecode(payload); + if (!payload_wrapper.ContainsKey("json")) + { + TKGDebugger.LogDebug( + "The product receipt does not contain enough information, the 'json' field is missing"); + return false; + } - OnPurchaseDone?.Invoke(e.purchasedProduct.definition.id, true); + var original_json_payload_wrapper = + (Dictionary)MiniJson.JsonDecode((string)payload_wrapper["json"]); + if (original_json_payload_wrapper == null || + !original_json_payload_wrapper.ContainsKey("developerPayload")) + { + TKGDebugger.LogDebug( + "The product receipt does not contain enough information, the 'developerPayload' field is missing"); + return false; + } - // 我们自己后台完毕的话,通过代码设置成功(如果是不需要后台设置直接设置完毕,不要设置Pending); - return PurchaseProcessingResult.Complete; - } + var developerPayloadJSON = (string)original_json_payload_wrapper["developerPayload"]; + var developerPayload_wrapper = + (Dictionary)MiniJson.JsonDecode(developerPayloadJSON); + if (developerPayload_wrapper == null || + !developerPayload_wrapper.ContainsKey("is_free_trial") || + !developerPayload_wrapper.ContainsKey("has_introductory_price_trial")) + { + TKGDebugger.LogDebug( + "The product receipt does not contain enough information, the product is not purchased using 1.19 or later"); + return false; + } - // 支付失败回掉函数; - public void OnPurchaseFailed(Product item, PurchaseFailureReason r) - { - TKGDebugger.LogDebug("Purchase OK: " + item.definition.id); - m_PurchaseInProgress = false; - OnPurchaseDone?.Invoke(item.definition.id, false); - } + return true; + } + case AppleAppStore.Name: + case AmazonApps.Name: + case MacAppStore.Name: + { + return true; + } + default: + { + return false; + } + } + } - // 购买延迟提示(这个看自己项目情况是否处理); - public void OnDeferred(Product item) - { - TKGDebugger.LogDebug("Purchase deferred: " + item.definition.id); - OnPurchaseDone?.Invoke(item.definition.id, false); - } + return false; + } + + // + /// + /// 支付成功处理函数; + /// 在支持交易恢复功能的平台上(例如 Google Play 和通用 Windows 应用程序), + /// Unity IAP 会在重新安装后的第一次初始化期间自动恢复用户拥有的任何商品; + /// 系统将为每项拥有的商品调用 IStoreListener 的 ProcessPurchase 方法。 + /// + /// + /// + public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) + { + m_PurchaseInProgress = false; + + TKGDebugger.LogDebug("Purchase OK: " + e.purchasedProduct.definition.id); + + // 消息结构 : Receipt: {"Store":"fake","TransactionID":"9c5c16a5-1ae4-468f-806d-bc709440448a","Payload":"{ \"this\" : \"is a fake receipt\" }"}; + TKGDebugger.LogDebug("Receipt: " + e.purchasedProduct.receipt); + + TKGSDKManager.Instance.SetSegment(SegmentType.Purchase); + + //获取并解析你需要上传的数据。解析成string类型 + var wrapper = (Dictionary)MiniJson.JsonDecode(e.purchasedProduct.receipt); + + // Corresponds to http://docs.unity3d.com/Manual/UnityIAPPurchaseReceipts.html + // 正在使用的商店的名称,例如 GooglePlay 或 AppleAppStore + var store = (string)wrapper["Store"]; + TKGDebugger.LogDebug("Purchase OK: store" + store); + //下面的payload 验证商品信息的数据。即我们需要上传的部分。 + // For Apple this will be the base64 encoded ASN.1 receipt + // 对于苹果来说,这将是base64编码的ASN.1收据 + var payload = (string)wrapper["Payload"]; + TKGDebugger.LogDebug("Purchase OK: payload" + payload); + + + string token; + string orderId; + if (Application.platform == RuntimePlatform.Android) + { + // For GooglePlay payload contains more JSON + // 对于GooglePlay有效负载包含更多JSON + var gpDetails = (Dictionary)MiniJson.JsonDecode(payload); + var gpJson = (string)gpDetails["json"]; + var tokenJson = (Dictionary)MiniJson.JsonDecode(gpJson); + token = (string)tokenJson["purchaseToken"]; + orderId = (string)tokenJson["orderId"]; + + TKGDebugger.LogDebug("ClientIAPSuccess productId : " + e.purchasedProduct.definition.id + " , transactionID : " + orderId + " , token : " + token + " , localizedPrice : " + e.purchasedProduct.metadata.localizedPriceString + " , isoCurrencyCode : " + e.purchasedProduct.metadata.isoCurrencyCode); + TKGNativeInterface.Instance.ClientIAPSuccess(mProductName, e.purchasedProduct.definition.id, orderId, token, e.purchasedProduct.metadata.isoCurrencyCode, e.purchasedProduct.metadata.localizedPrice.ToString(), mGameExtraParam); + + //if (orderId.StartsWith("GPA.")) + //{ + // TKGSDKManager.Instance.LogPurchasePrice(e.purchasedProduct.metadata.localizedPriceString, + // e.purchasedProduct.metadata.isoCurrencyCode); // todo delete android upload event + // OnPurchaseDone?.Invoke(e.purchasedProduct.definition.id, true, orderId, token); + //} + //else + //{ + // //OnPurchaseDone?.Invoke(e.purchasedProduct.definition.id, false, "", ""); + // TKGDebugger.LogDebug("productId : " + e.purchasedProduct.definition.id + " , transactionID : " + orderId + " , localizedPrice : " + e.purchasedProduct.metadata.localizedPriceString + " , isoCurrencyCode : " + e.purchasedProduct.metadata.isoCurrencyCode); + // TKGNativeInterface.Instance.ClientIAPFailed("", e.purchasedProduct.definition.id, orderId, token, e.purchasedProduct.metadata.localizedPriceString, e.purchasedProduct.metadata.isoCurrencyCode); + //} + } + else + { + //TKGSDKManager.Instance.LogPurchasePrice(e.purchasedProduct.metadata.localizedPriceString, + // e.purchasedProduct.metadata.isoCurrencyCode); // todo delete iOS upload event + //苹果验单直接传入 payload + token = ""; + orderId = (string)wrapper["TransactionID"]; + //OnPurchaseDone?.Invoke(e.purchasedProduct.definition.id, true, orderId, token); + + + TKGDebugger.LogDebug("ClientIAPSuccess productId : " + e.purchasedProduct.definition.id + " , transactionID : " + orderId + " , token : " + token + " , localizedPrice : " + e.purchasedProduct.metadata.localizedPriceString + " , isoCurrencyCode : " + e.purchasedProduct.metadata.isoCurrencyCode); + TKGNativeInterface.Instance.ClientIAPSuccess(mProductName, e.purchasedProduct.definition.id, orderId, token, e.purchasedProduct.metadata.isoCurrencyCode, e.purchasedProduct.metadata.localizedPrice.ToString(),mGameExtraParam); + + } + + return PurchaseProcessingResult.Complete; + } + + // 支付失败回掉函数; + public void OnPurchaseFailed(Product product, PurchaseFailureReason failureDescription) + { + TKGDebugger.LogDebug("Purchase OK: " + product.definition.id); + m_PurchaseInProgress = false; + //OnPurchaseDone?.Invoke(item.definition.id, false, "", ""); + + TKGDebugger.LogDebug("OnPurchaseFailed -> productId : " + product.definition.id + " , transactionID : " + product.transactionID + " , localizedPrice : " + product.metadata.localizedPriceString + " , isoCurrencyCode : " + product.metadata.isoCurrencyCode); + TKGNativeInterface.Instance.ClientIAPFailed(mProductName, product.definition.id, product.transactionID, "", product.metadata.isoCurrencyCode,product.metadata.localizedPrice.ToString(),mGameExtraParam, IAPClientFailReasonType.PurchaseFailed); + + } + + // 购买延迟提示(这个看自己项目情况是否处理); + // 在 Apple 平台上,我们需要处理由 Apple 的"购买前先询问"功能导致的延期购买。 + // 在非 Apple 平台上,这将不起作用;永远不会调用 OnDeferred。 + public void OnDeferred(Product product) + { + TKGDebugger.LogDebug("Purchase deferred: " + product.definition.id + " , maybe slow internet."); + //OnPurchaseDone?.Invoke(item.definition.id, false, "", ""); + + TKGNativeInterface.Instance.ClientIAPFailed(mProductName, product.definition.id, product.transactionID, "", product.metadata.isoCurrencyCode, product.metadata.localizedPrice.ToString(), mGameExtraParam, IAPClientFailReasonType.Deferred); + + } + + // 恢复购买功能执行回掉函数; + public void OnTransactionsRestored(bool success) + { + TKGDebugger.LogDebug("Transactions restored : " + success); + } - // 恢复购买功能执行回掉函数; - public void OnTransactionsRestored(bool success) - { - TKGDebugger.LogDebug("Transactions restored : " + success); - } #endregion #region custom functions - public string GetPriceByID(string pID) - { - if (m_StoreController == null && m_StoreExtensionProvider == null) - return ""; - Product[] tProducts = m_StoreController.products.all; - for (int i = 0; i < tProducts.Length; i++) - { - TKGDebugger.LogDebug(tProducts[i].metadata.localizedTitle + "|" + tProducts[i].metadata.localizedPriceString + "|" + tProducts[i].metadata.localizedDescription + "|" + tProducts[i].metadata.isoCurrencyCode); - Product tItem = tProducts[i]; - if (tItem.definition.id.Equals(pID)) - { + public string GetPriceByID(string pID) + { + if (m_StoreController == null && m_StoreExtensionProvider == null) + return ""; + + Product[] tProducts = m_StoreController.products.all; + for (int i = 0; i < tProducts.Length; i++) + { + Product tItem = tProducts[i]; + if (tItem.definition.id.Equals(pID)) + { #if UNITY_ANDROID - return tItem.metadata.GetGoogleProductMetadata().localizedPriceString; + return tItem.metadata.GetGoogleProductMetadata().localizedPriceString; #else return tItem.metadata.localizedPriceString; #endif - } - } + } + } - return ""; - } + return ""; + } + + public Product GetProductInfoByID(string pID) + { + if (m_StoreController == null && m_StoreExtensionProvider == null) + return null; + for (int i = 0; i < m_StoreController.products.all.Length; i++) + { + Product tItem = m_StoreController.products.all[i]; + if (tItem.definition.id.Equals(pID)) + { + return tItem; + } + } + + return null; + } + + public SubscriptionInfo GetSubscriptionInfo() + { + return mSubsInfo; + } - public SubscriptionInfo GetSubscriptionInfo() - { - return mSubsInfo; - } #endregion + } } #endif \ No newline at end of file diff --git a/Assets/TKGSDK/Common/internal/ITKGSDK.cs b/Assets/TKGSDK/Common/internal/ITKGSDK.cs index ee0b31a5..e0f7465c 100644 --- a/Assets/TKGSDK/Common/internal/ITKGSDK.cs +++ b/Assets/TKGSDK/Common/internal/ITKGSDK.cs @@ -66,7 +66,7 @@ namespace Touka /// Name of interstitial ad placement. /// Callback of interstitial ad close and show interstitial failed /// IVADType for distinguish interstitial ads frequency, default use iv1 - void ShowInterstitialAd(TKGIVAdPositionName _adPos, Action _callback = null, IVADType _IvType = IVADType.IV1); + void ShowInterstitialAd(string _adPos, Action _callback = null, IVADType _IvType = IVADType.IV1); /// /// Show Reward Ad @@ -74,7 +74,7 @@ namespace Touka /// Name of reward ad placement /// true:reward succ, false: reward failed /// Callback of reward ad show fail - void ShowRewardAd(TKGRVPositionName _adPos, Action _rewardCallback = null, Action _showFailedCallback = null); + void ShowRewardAd(string _adPos, Action _rewardCallback = null, Action _showFailedCallback = null); /// /// SetShowSDKToast @@ -265,6 +265,13 @@ namespace Touka /// void SetUserSourceListener(Action _userSourceActionWithCampaignName); + /// + /// 注册功能开关回调 + /// + /// 各功能名称 + /// 回调事件,回来每个功能名称及对应开关 + void SetFunctionSwitchListener(List _functionKeys, Action _functionSwitchCallback); + /// /// common callback /// @@ -283,6 +290,26 @@ namespace Touka /// void ShareTxt(string _shareTxt); + /// + /// show picture cross + /// + bool showPictureCross(); + + /// + /// remove picture cross + /// + void removePictureCross(); + + /// + /// show more game icon + /// + bool showMoreGameIcon(); + + /// + /// remove more game icon + /// + void removeMoreGameIcon(); + /// /// regist APNS /// @@ -312,7 +339,225 @@ namespace Touka /// notification identifier void RemoveNotification(string notiId); + /// + /// if is debug mode + /// + bool IsDebugMode(); + + /// + /// get user name and user id card + /// + string GetUserNameAndUserIDCard(); + + /// + /// set segment type to sdk + /// + /// segment type + void SetSegment(SegmentType type); + + /// + /// get a iap product list for sdk config file + /// + Dictionary GetIAPProductList(); + #endregion + + #region 数据中台 + void LogPurchasePrice(string price,string currency); + + void LogRobuxCashOut(); + + void LogNoviceGuideFinish(); + + #endregion + + #region GooglePlay评论引导 + /// + /// Pop up GooglePlay Rate guid + /// + bool GuidGpComment(); + #endregion + + #region 用户登录 + /// + /// User Login + /// 登录回调Action<登录状态码,登录类型,登录状态信息,userid,token,邮箱 , 显示名称 , 头像url> + /// + void Login(LoginType loginType, Action _loginResultCallback = null); + /// + /// Logout + /// + void Logout(Action _logoutCallback = null); + + /// + /// Obtain a list of login channels, + /// and the game displays the obtained login list for users to choose to log in. + /// + /// available login channels + List AvailableLoginChannelList(); + + /// + /// user actively deletes account. + /// + /// Return the deleted userId. If the game needs to record it, you can operate it in the action. + /// + /// Delete userId + void DeleteAccount(Action _deleteAccountCallback = null); + + void BindAccount(LoginType type, BindType isForce, string userId, + Action + bindAccountCallback); + + + + void AutoLogin( + Action loginResultCallback); + + LoginType GetAccountType(); + + bool IsCanAutoLogin(); + + #endregion + + #region IAP Event + + /// + /// Log IAP button show + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + void LogIAPBtnShow(string _productName,string _productID); + + /// + /// Log IAP button Click + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + void LogIAPBtnClick(string _productName, string _productID); + + /// + /// Log IAP First payment successful + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + /// The order id returned by the payment channel + /// Currency ex:USD + /// Price + void LogIAPFirstPurchase(string _iap, string _id,string _paymentChannelOrderid, string _currency, string _price); + + /// + /// Log IAP payment successful + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + /// The order id on the game side + /// The order id returned by the payment channel + /// Purchase token: When the purchase is successful on GP, ​​a purchase token will be generated as a unique identifier + /// Official payment channels: appstore, googleplay, other payment channels corresponding channel name + /// Currency ex:USD + /// Price + void LogIAPSuccess(string _iap, string _id, string _gameOrderid, string _paymentChannelOrderid, string _productToken, string _paymentMethod, string _currency, string _price); + + #endregion + + + #region 保存数据 + void SaveCloudArchiving(string content, Action callback); + + void DetailCloudArchiving(Action callback); + #endregion + } + + public enum LoginType + { + // 游客登录 + LOGIN_BY_GUESTER = 0, + + // 邮箱账号登录(暂不支持) + LOGIN_BY_EMAIL = 1, + + // Google登录 + LOGIN_BY_GOOGLE = 2, + + // Facebook登录 + LOGIN_BY_FACEBOOK = 3, + + LOGIN_BY_Apple = 4, + + LOGIN_BY_AUTO = 10, + } + + + public enum BindAccountStatus + { + // 绑定失败 + BIND_CODE_FAILED = -1, + // 绑定成功 + BIND_CODE_SUCC = 0, + // 取消绑定 + BIND_CODE_CANCEL = 1, + // 已经绑定账户,需要选择 + BIND_CODE_SELECT = 2, + } + + public enum BindType + { + NO_FORCE = 0, + FORCE = 1, + } + + public enum DeleteStatus + { + DELETE_ACCOUNT_SUCC = 0, + DELETE_ACCOUNT_CANCEL = 1, + DELETE_ACCOUNT_FAILED = -1 + } + + public enum LoginStatus + { + // 登录成功 + LOGIN_STATUS_SUCC = 0, + + // 登录被用户取消 + LOGIN_STATUS_CANCEL = 1, + + // 自动登陆没有缓存数据 + LOGIN_STATUS_NO_CACHE = 2, + + // 登录失败 + LOGIN_STATUS_FAILED = -1 + } + + public enum SegmentType + { + Purchase, + T0, + T1, + T2, + Other1, + Other2, + Other3, + Other4, + Other5, + Other6, + Other7, + Other8, + Other9 + } + + /// + /// 功能名称枚举 + /// + public enum FunctionType + { + Function_wangz, + Function_bing, + Function_IA, + Function_IP, + Function_name, + Function_other1, + Function_other2, + Function_other3 } /// @@ -371,6 +616,11 @@ namespace Touka { FirebaseOnlineParamGet_Succ = 990001, FirebaseOnlineParamGet_Failed = 990002, + + SaveCloudArchiving_Succ = 100, + SaveCloudArchiving_Fail = 101, + DetailCloudArchiving_Succ = 102, + DetailCloudArchiving_Fail = 103, } /// @@ -409,4 +659,28 @@ namespace Touka AndroidRoot = 10000 } + + public enum AdsType + { + None, + Banner, + IV, + RV, + Native, + Splash, + } + + public enum ThirdAccountType + { + None, + Paypal + } + + public enum IAPClientFailReasonType + { + None, + NotInit, + PurchaseFailed, + Deferred + } } diff --git a/Assets/TKGSDK/Common/internal/TKGSDKNative.cs b/Assets/TKGSDK/Common/internal/TKGSDKNative.cs index 55ff7ad4..62579483 100644 --- a/Assets/TKGSDK/Common/internal/TKGSDKNative.cs +++ b/Assets/TKGSDK/Common/internal/TKGSDKNative.cs @@ -13,8 +13,8 @@ namespace Touka /// public void InitSDK(Action _initCallback = null) { - TKGNativeInterface.Instance.Init(_initCallback); SetOnlineConfigInit(); + TKGNativeInterface.Instance.Init(_initCallback); } private void SetOnlineConfigInit() @@ -116,7 +116,7 @@ namespace Touka /// Name of interstitial ad placement. /// Callback of interstitial ad close and show interstitial failed /// IVADType for distinguish interstitial ads frequency, default use iv1 - public void ShowInterstitialAd(TKGIVAdPositionName _adPos, Action _callback = null, IVADType _IvType = IVADType.IV1) + public void ShowInterstitialAd(string _adPos, Action _callback = null, IVADType _IvType = IVADType.IV1) { #if UNITY_EDITOR TKGDebugger.LogDebug("[TKGSDKNative] Show Interstitial call, _adPos : " + _adPos); @@ -124,7 +124,7 @@ namespace Touka return; #endif TKGSDKCallback.mInterAdCallback = _callback; - TKGNativeInterface.Instance.showInterstitialAd(_adPos.ToString(), _IvType); + TKGNativeInterface.Instance.showInterstitialAd(_adPos, _IvType); } /// @@ -133,7 +133,7 @@ namespace Touka /// Name of reward ad placement /// true:reward succ, false: reward failed /// Callback of reward ad show fail - public void ShowRewardAd(TKGRVPositionName _adPos, Action _rewardCallback = null, Action _showFailedCallback = null) + public void ShowRewardAd(string _adPos, Action _rewardCallback = null, Action _showFailedCallback = null) { #if UNITY_EDITOR TKGDebugger.LogDebug("[TKGSDKNative] Show reward call, _adPos : " + _adPos); @@ -144,7 +144,7 @@ namespace Touka TKGSDKCallback.mRewardCallback = _rewardCallback; TKGSDKCallback.mRewardShowFailedCallback = _showFailedCallback; - TKGNativeInterface.Instance.showRewardAd(_adPos.ToString(), -1); + TKGNativeInterface.Instance.showRewardAd(_adPos, -1); } public void Toast(string text) { @@ -443,13 +443,7 @@ namespace Touka { TKGDebugger.LogDebug("[TKGSDKNative] Review"); #if UNITY_EDITOR -#if AppStore_GB TKGDebugger.LogDebug("[TKGSDKNative] Review cannot be opened in editor, please open it in real machine"); -#else - - TKGDebugger.LogDebug("[TKGSDKNative] 编辑器中无法打开评价页面,请在真机中打开"); - -#endif return; #endif TKGNativeInterface.Instance.Review(); @@ -462,13 +456,7 @@ namespace Touka { TKGDebugger.LogDebug("[TKGSDKNative] OpenPrivacyURL"); #if UNITY_EDITOR -#if AppStore_GB TKGDebugger.LogDebug("[TKGSDKNative] Web page cannot be opened in editor, please open it in real machine"); -#else - - TKGDebugger.LogDebug("[TKGSDKNative] 编辑器中无法打开网页,请在真机中打开"); - -#endif return; #endif TKGNativeInterface.Instance.OpenPrivacyURL(); @@ -481,13 +469,7 @@ namespace Touka { TKGDebugger.LogDebug("[TKGSDKNative] OpenUserTermURL"); #if UNITY_EDITOR -#if AppStore_GB TKGDebugger.LogDebug("[TKGSDKNative] Web page cannot be opened in editor, please open it in real machine"); -#else - - TKGDebugger.LogDebug("[TKGSDKNative] 编辑器中无法打开网页,请在真机中打开"); - -#endif return; #endif TKGNativeInterface.Instance.OpenUserTermURL(); @@ -500,13 +482,7 @@ namespace Touka { TKGDebugger.LogDebug("[TKGSDKNative] OpenPolicyPop"); #if UNITY_EDITOR -#if AppStore_GB TKGDebugger.LogDebug("[TKGSDKNative] Web page cannot be opened in editor, please open it in real machine"); -#else - - TKGDebugger.LogDebug("[TKGSDKNative] 编辑器中无法打开网页,请在真机中打开"); - -#endif return; #endif TKGNativeInterface.Instance.OpenPolicyPop(); @@ -519,13 +495,7 @@ namespace Touka { TKGDebugger.LogDebug("[TKGSDKNative] OpenMoreGame"); #if UNITY_EDITOR -#if AppStore_GB TKGDebugger.LogDebug("[TKGSDKNative] App Store cannot be opened in editor, please open it in real machine"); -#else - - TKGDebugger.LogDebug("[TKGSDKNative] 编辑器中无法打开App Store,请在真机中打开"); - -#endif return; #endif TKGNativeInterface.Instance.OpenMoreGame(); @@ -558,6 +528,35 @@ namespace Touka TKGNativeInterface.Instance.shake(_shakeType, _intensity); } + // + public bool IsDebugMode() + { + return TKGNativeInterface.Instance.IsDebugMode(); + } + + public string GetUserNameAndUserIDCard() + { + + return TKGNativeInterface.Instance.GetUserNameAndUserIDCard(); + } + + /// + /// set segment type to sdk + /// + /// segment type + public void SetSegment(SegmentType type) + { + TKGNativeInterface.Instance.SetSegment(type); + } + + /// + /// get a iap product list for sdk config file + /// + public Dictionary GetIAPProductList() + { + return TKGNativeInterface.Instance.GetIAPProductList(); + } + #endregion #region others(uncommon) @@ -588,6 +587,15 @@ namespace Touka TKGNativeInterface.Instance.SetUserSourceCallback(new AndroidTKGUserSourceCalllbackWithCampaignName()); } + public void SetFunctionSwitchListener(List _functionKeys, Action _functionSwitchCallback) + { +#if UNITY_EDITOR + return; +#endif + TKGSDKCallback.mFunctionSwitchCalllback = _functionSwitchCallback; + TKGNativeInterface.Instance.SetFunctionSwitchCalllback(_functionKeys,new AndroidFunctionSwitchCalllback()); + + } /// /// Set TKG Common callback /// @@ -623,6 +631,51 @@ namespace Touka } + /// + /// show picture cross + /// + public bool showPictureCross() + { +#if UNITY_EDITOR + return false; +#endif + return TKGNativeInterface.Instance.showPictureCross(); + + } + + /// + /// remove picture cross + /// + public void removePictureCross() + { +#if UNITY_EDITOR + return; +#endif + TKGNativeInterface.Instance.removePictureCross(); + } + + /// + /// show more game icon + /// + public bool showMoreGameIcon() + { +#if UNITY_EDITOR + return false; +#endif + return TKGNativeInterface.Instance.showMoreGameIcon(); + } + + /// + /// remove more game icon + /// + public void removeMoreGameIcon() + { +#if UNITY_EDITOR + return; +#endif + TKGNativeInterface.Instance.removeMoreGameIcon(); + } + /// /// regist APNS /// @@ -680,6 +733,111 @@ namespace Touka TKGNativeInterface.Instance.RemoveNotification(notiId); #endif } -#endregion + + #endregion + + #region 数据中台 + + public void LogPurchasePrice(string price,string currency) + { + TKGNativeInterface.Instance.LogPurchasePrice(price,currency); + } + + public void LogRobuxCashOut() + { + TKGNativeInterface.Instance.LogRobuxCashOut(); + } + + public void LogNoviceGuideFinish() + { + TKGNativeInterface.Instance.LogNoviceGuideFinish(); + } + + #endregion + + #region GooglePlay评论引导 + /// + /// Pop up GooglePlay Rate guid + /// + public bool GuidGpComment() + { + return TKGNativeInterface.Instance.GuidGpComment(); + } + + public void Login(LoginType loginType, Action _loginResultCallback = null) + { + TKGNativeInterface.Instance.Login(loginType, _loginResultCallback); + } + + public void Logout(Action _logoutCallback = null) + { + TKGNativeInterface.Instance.Logout(_logoutCallback); + } + + public List AvailableLoginChannelList() + { + return TKGNativeInterface.Instance.AvailableLoginChannelList(); + } + + public void DeleteAccount(Action deleteAccountCallback = null) + { + TKGNativeInterface.Instance.DeleteAccount(deleteAccountCallback); + } + + public void BindAccount(LoginType type,BindType isForce, string userId, Action bindAccountCallback) + { + TKGNativeInterface.Instance.BindAccount(type, isForce, userId, bindAccountCallback); + } + + public void AutoLogin(Action loginResultCallback) + { + TKGNativeInterface.Instance.AutoLogin(loginResultCallback); + } + + public LoginType GetAccountType() + { + return TKGNativeInterface.Instance.GetAccountType(); + } + + public bool IsCanAutoLogin() + { + return TKGNativeInterface.Instance.IsCanAutoLogin(); + } + + public void LogIAPBtnShow(string _productName, string _productID) + { + TKGNativeInterface.Instance.LogIAPBtnShow(_productName, _productID); + } + + public void LogIAPBtnClick(string _productName, string _productID) + { + TKGNativeInterface.Instance.LogIAPBtnClick(_productName, _productID); + } + + public void LogIAPFirstPurchase(string _iap, string _id, string _paymentChannelOrderid,string _currency, string _price) + { + TKGNativeInterface.Instance.LogIAPFirstPurchase(_iap, _id,_paymentChannelOrderid, _currency, _price); + } + + public void LogIAPSuccess(string _iap, string _id, string _gameOrderid, string _paymentChannelOrderid, string _productToken, string _paymentMethod, string _currency, string _price) + { + TKGNativeInterface.Instance.LogIAPSuccess(_iap,_id, _gameOrderid, _paymentChannelOrderid, _productToken, _paymentMethod, _currency, _price); + } + #endregion + + #region 保存数据 + + public void SaveCloudArchiving(string content, Action callback) + { + TKGNativeInterface.Instance.SaveCloudArchiving(content, callback); + } + + public void DetailCloudArchiving(Action callback) + { + TKGNativeInterface.Instance.DetailCloudArchiving(callback); + } + #endregion + + } } diff --git a/Assets/TKGSDK/Common/internal/iOS/TGiOSAdmanager.cs b/Assets/TKGSDK/Common/internal/iOS/TGiOSAdmanager.cs index 8cd5700a..f0927bfd 100644 --- a/Assets/TKGSDK/Common/internal/iOS/TGiOSAdmanager.cs +++ b/Assets/TKGSDK/Common/internal/iOS/TGiOSAdmanager.cs @@ -15,21 +15,84 @@ public class TGiOSAdManager : MonoBehaviour public Action onAntiSuccessHander; private System.Action m_userSourceCallback; - public static TGiOSAdManager Instance + public void LogPurchasePrice(string price,string currency) { - get + TKG_DataCenter_Purchase(price); + } + + public void LogRobuxCashOut() + { + TKG_DataCenter_RobuxCashOut(); + } + + public void LogNoviceGuideFinish() + { + TKG_DataCenter_Guide(); + } + + public void setUserIDAndThirdAccount(string _userID, string _thirdAccount, ThirdAccountType _thirdAccountType) + { + TKG_SetUserIDAndThirdAccount(_userID,_thirdAccount, _thirdAccountType); + + } + + + /// + /// get a iap product list for sdk config file + /// + public Dictionary getIAPProductList() + { + + return StringToDictionary(TKG_GetIAPProductList()); + } + + Dictionary StringToDictionary(string value) + { + if (value.Length < 1) { - if (s_instance == null) - { - GameObject TGGameObject = new GameObject - { - name = "AdObject" - }; - s_instance = TGGameObject.AddComponent(); - DontDestroyOnLoad(TGGameObject); - } - return s_instance; + return new Dictionary(); } + Dictionary dic = new Dictionary(); + + string[] dicStrs = value.Split(','); + foreach (string str in dicStrs) + { + string[] strs = str.Split('='); + dic.Add(strs[0], strs[1]); + } + return dic; + } + + /// + /// show picture cross + /// + public bool showPictureCross() + { + return TKG_ShowPictureCross(); + } + + /// + /// remove picture cross + /// + public void removePictureCross() + { + TKG_RemovePictureCross(); + } + + /// + /// show more game icon + /// + public bool showMoreGameIcon() + { + return TKG_ShowMoreGameIcon(); + } + + /// + /// remove more game icon + /// + public void removeMoreGameIcon() + { + TKG_RemoveMoreGameIcon(); } @@ -50,6 +113,11 @@ public class TGiOSAdManager : MonoBehaviour IntPtr us = Marshal.GetFunctionPointerForDelegate(usHandler); userSourceCallback(us); + // function Switch + TKG_FunctionSwitchDelegate funcHandler = new TKG_FunctionSwitchDelegate(functionSwitchHandle); + IntPtr func = Marshal.GetFunctionPointerForDelegate(funcHandler); + funcSwitchCallback(func); + // rv close rewardCloseDelegate rvCloseHandler = new rewardCloseDelegate(rewardAdCloseHandle); IntPtr rewardClose = Marshal.GetFunctionPointerForDelegate(rvCloseHandler); @@ -70,16 +138,32 @@ public class TGiOSAdManager : MonoBehaviour IntPtr rvClick = Marshal.GetFunctionPointerForDelegate(rvClickHandler); rewardAdClickCallback(rvClick); + revenueDelegate revenueHandler = new revenueDelegate(revenueHandle); + IntPtr revHandle = Marshal.GetFunctionPointerForDelegate(revenueHandler); + adsRevenreCallback(revHandle); + + TKG_InitSDK(); } + // 注册事件 + public void setFunctions(string funcs) + { + TKG_SetFuncs(funcs); + } + // 通知 public void registAPNS() { TKG_RegistAPNS(); } + public string getUserNameAndUserIDCard() + { + return TKG_GetUserNameAndUserIDCard(); + } + public void registNotification(string notiId, string body, string fireDate, int badge, string title, string subTitle) { TKG_RegistNotification(notiId,body,fireDate,badge,title,subTitle); @@ -100,11 +184,31 @@ public class TGiOSAdManager : MonoBehaviour TKG_Shake(mType,mIntensity); } + public bool isDebugMode() + { + return TKG_IsDebugMode(); + } + + /// + /// set segment type to sdk + /// + /// segment type + public void SetSegment(string type) + { + TKG_SetSegment(type); + } + public void share(string _shareText) { TKG_Share(_shareText); } + // 获取渠道 + public int getChannel() + { + return TKG_GetChannel(); + } + // ads public void RemoveAllAds() @@ -367,6 +471,18 @@ public class TGiOSAdManager : MonoBehaviour } } + // ad revenue callback + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void revenueDelegate(AdsType type,string price, string currency); + [AOT.MonoPInvokeCallback(typeof(revenueDelegate))] + static void revenueHandle(AdsType type, string price, string currency) + { + if (TKGSDKCallback.mAdsRevenueCallback != null) + { + TKGSDKCallback.mAdsRevenueCallback(type,price,currency); + } + } + // pause game [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void pauseGameDelegate(bool m_pause); @@ -408,13 +524,124 @@ public class TGiOSAdManager : MonoBehaviour } } + // set func + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void TKG_FunctionSwitchDelegate(string funcT, string funcS); + [AOT.MonoPInvokeCallback(typeof(TKG_FunctionSwitchDelegate))] + static void functionSwitchHandle(string funcType, string funcSwitch) + { + + Debug.Log("TKG GAME unity log 回调到unity里:"+funcType+"sw:"+funcSwitch); + if (TKGSDKCallback.mFunctionSwitchCalllback != null) + { + FunctionType enumType = (FunctionType)Enum.Parse(typeof(FunctionType), funcType); + + if (TKGSDKCallback.mFunctionSwitchCalllback != null) + { + bool res = funcSwitch == "1" ? true : false; + TKGSDKCallback.mFunctionSwitchCalllback.Invoke(enumType, res); + } + } + } + + // iap result callback + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void iapResultDelegate(string orderId, string productName,string productId,bool res,string gameExtre); + [AOT.MonoPInvokeCallback(typeof(iapResultDelegate))] + static void game_iapResultHandle(string orderId,string productName,string productId, bool reslut, string gameExtre) + { + if (TKGSDKCallback.mSecondPurchaseCallback != null) + { + TKGSDKCallback.mSecondPurchaseCallback(orderId,productName,productId, reslut, gameExtre); + } + } + + + // iap + /// + /// Client IAP Success + /// + public void IAP_ClientIAPSuccess(string _productName, string _productID, string _purchaseOrderID, string _purchaseToken, string _currency, string _price, string _gameExtra) + { + iapResultDelegate iapHandler = new iapResultDelegate(game_iapResultHandle); + IntPtr iapRes = Marshal.GetFunctionPointerForDelegate(iapHandler); + TKG_IapResultHandle(iapRes); + + Dictionary _productInfoDict = new Dictionary(); + _productInfoDict.Add("iap_name", _productName); + _productInfoDict.Add("product_id", _productID); + _productInfoDict.Add("game_order_id", _gameExtra); + _productInfoDict.Add("order_id", _purchaseOrderID); + _productInfoDict.Add("purchase_token", _purchaseToken); + _productInfoDict.Add("currency", _currency); + _productInfoDict.Add("price", _price); + TKG_ClientIAPSuccess(TKG_DictionaryToJson(_productInfoDict)); + } + + /// + /// Client IAP Failed + /// + public void IAP_ClientIAPFailed(string _productName, string _productID, string _purchaseOrderID, string _purchaseToken, string _currency, string _price, string _gameExtra, IAPClientFailReasonType _failType) + { + iapResultDelegate iapHandler = new iapResultDelegate(game_iapResultHandle); + IntPtr iapRes = Marshal.GetFunctionPointerForDelegate(iapHandler); + TKG_IapResultHandle(iapRes); + + Dictionary _productInfoDict = new Dictionary(); + _productInfoDict.Add("iap_name", _productName); + _productInfoDict.Add("product_id", _productID); + _productInfoDict.Add("game_order_id", _gameExtra); + _productInfoDict.Add("order_id", _purchaseOrderID); + _productInfoDict.Add("purchase_token", _purchaseToken); + _productInfoDict.Add("currency", _currency); + _productInfoDict.Add("price", _price); + TKG_ClientIAPFailed(TKG_DictionaryToJson(_productInfoDict)); + } + + // dll + [DllImport("__Internal")] + private static extern void TKG_DataCenter_RobuxCashOut(); + + [DllImport("__Internal")] + private static extern void TKG_DataCenter_Guide(); + + [DllImport("__Internal")] + private static extern void TKG_DataCenter_Purchase(string price); + + [DllImport("__Internal")] + private static extern void TKG_SetSegment(string name); + + [DllImport("__Internal")] + private static extern string TKG_GetIAPProductList(); + + [DllImport("__Internal")] + private static extern bool TKG_ShowPictureCross(); + + [DllImport("__Internal")] + private static extern void TKG_RemovePictureCross(); + + [DllImport("__Internal")] + private static extern bool TKG_ShowMoreGameIcon(); + + [DllImport("__Internal")] + private static extern void TKG_RemoveMoreGameIcon(); + + [DllImport("__Internal")] + private static extern void TKG_SetFuncs(string funcs); + [DllImport("__Internal")] private static extern void TKG_Shake(int mType, float mIntensity); + [DllImport("__Internal")] + private static extern bool TKG_IsDebugMode(); + [DllImport("__Internal")] private static extern void TKG_Share(string text); + [DllImport("__Internal")] + private static extern int TKG_GetChannel(); + [DllImport("__Internal")] private static extern void TKG_InitSDK(); @@ -476,6 +703,9 @@ public class TGiOSAdManager : MonoBehaviour [DllImport("__Internal")] private static extern void TKG_LoadIntersititial(); + [DllImport("__Internal")] + private static extern string TKG_GetUserNameAndUserIDCard(); + [DllImport("__Internal")] private static extern bool TKG_IsReadyIntersititial(); @@ -547,6 +777,11 @@ public class TGiOSAdManager : MonoBehaviour IntPtr rewardShowFail ); + [DllImport("__Internal")] + public static extern void adsRevenreCallback( + IntPtr adRevenue + ); + // pause game [DllImport("__Internal")] public static extern void pauseGameCallback( @@ -565,6 +800,13 @@ public class TGiOSAdManager : MonoBehaviour IntPtr userSource ); + // func callback + [DllImport("__Internal")] + public static extern void funcSwitchCallback( + IntPtr funcSwitch + ); + + // 设置unity版本 [DllImport("__Internal")] private static extern void TKG_SetUnityVersion(string version); @@ -582,6 +824,22 @@ public class TGiOSAdManager : MonoBehaviour [DllImport("__Internal")] private static extern void TKG_RegistNotification(string notiId, string body, string fireDate, int badge, string title, string subTitle); + // iap + [DllImport("__Internal")] + private static extern void TKG_ClientIAPSuccess(string productInfo); + + [DllImport("__Internal")] + private static extern void TKG_ClientIAPFailed(string productInfo); + + [DllImport("__Internal")] + public static extern void TKG_IapResultHandle( + IntPtr iapResult + ); + + [DllImport("__Internal")] + private static extern void TKG_SetUserIDAndThirdAccount(string _userID, string _thirdAccount, ThirdAccountType _thirdAccountType); + + // ============================ old sdk todo ======================== //设置log开关 @@ -594,6 +852,23 @@ public class TGiOSAdManager : MonoBehaviour { TKG_SetUnityVersion(version); } + + public static TGiOSAdManager Instance + { + get + { + if (s_instance == null) + { + GameObject TGGameObject = new GameObject + { + name = "AdObject" + }; + s_instance = TGGameObject.AddComponent(); + DontDestroyOnLoad(TGGameObject); + } + return s_instance; + } + } } #endif diff --git a/Assets/TKGSDK/Common/internal/iOS/TKGiOSLoginManager.cs b/Assets/TKGSDK/Common/internal/iOS/TKGiOSLoginManager.cs new file mode 100644 index 00000000..1cde9f09 --- /dev/null +++ b/Assets/TKGSDK/Common/internal/iOS/TKGiOSLoginManager.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using Touka; +using UnityEngine; + +public class TKGiOSLoginManager : MonoBehaviour +{ +#if UNITY_IOS + // login result callback + [DllImport("__Internal")] + public static extern void TKG_LoginResultCallback( + IntPtr loginResult + ); + + // login out callback + [DllImport("__Internal")] + public static extern void TKG_LogoutCallback( + IntPtr loginOut + ); + + // delete account callback + [DllImport("__Internal")] + public static extern void TKG_DeleteAccountCallback( + IntPtr deleteAccount + ); + + // login out + [DllImport("__Internal")] + private static extern void TKG_Logout(); + + // availablechannel + [DllImport("__Internal")] + private static extern string TKG_AvailableLoginChannelList(); + + // login + [DllImport("__Internal")] + private static extern void TKG_Login(LoginType type); + + // delete account + [DllImport("__Internal")] + private static extern void TKG_DeleteAccount(); + + + // bind account + [DllImport("__Internal")] + private static extern void TKG_BindAccount(LoginType loginType,BindType bindType,string thirdUid); + + // bind account callback + [DllImport("__Internal")] + public static extern void TKG_BindAccountCallback( + IntPtr bindAccount + ); + + // auto login + [DllImport("__Internal")] + private static extern bool TKG_IsCanAutoLogin(); + + [DllImport("__Internal")] + private static extern void TKG_AutoLogin(); +#endif + + + public bool IsCanAutoLogin() + { +#if UNITY_IOS + return TKG_IsCanAutoLogin(); +#else + return false; +#endif + } + + public void AutoLogin() + { +#if UNITY_IOS + // login callback + loginResultDelegate loginResultHandler = new loginResultDelegate(loginResultHandle); + IntPtr result = Marshal.GetFunctionPointerForDelegate(loginResultHandler); + TKG_LoginResultCallback(result); + TKG_AutoLogin(); +#endif + } + + public void DeleteAccount() + { + +#if UNITY_IOS + // delete account callback + deleteAccountDelegate deleteAccountHandler = new deleteAccountDelegate(deleteAccountHandle); + IntPtr result = Marshal.GetFunctionPointerForDelegate(deleteAccountHandler); + TKG_DeleteAccountCallback(result); + + TKG_DeleteAccount(); +#endif + } + + + public void Login(LoginType _type) + { +#if UNITY_IOS + // login callback + loginResultDelegate loginResultHandler = new loginResultDelegate(loginResultHandle) ; + IntPtr result = Marshal.GetFunctionPointerForDelegate(loginResultHandler); + TKG_LoginResultCallback(result); + + TKG_Login(_type); +#endif + + } + + public void Logout() + { +#if UNITY_IOS + // logout callback + logoutDelegate logoutHandler = new logoutDelegate(logoutHandle); + IntPtr result = Marshal.GetFunctionPointerForDelegate(logoutHandler); + TKG_LogoutCallback(result); + + TKG_Logout(); +#endif + } + + public List AvailableLoginChannelList() + { + +#if UNITY_EDITOR + string temp = "0,4"; +#elif UNITY_IOS + string temp = TKG_AvailableLoginChannelList(); + + + string[] arr = temp.Split(','); + List list = new List(); + for (int i = 0; i < arr.Length; i++) + { + list.Add((LoginType)Enum.Parse(typeof(LoginType), arr[i])); + } + return list; +#endif + return null; + } + + public void BindAccount(LoginType loginType, BindType bindType, string thirdUid) + { +#if UNITY_IOS + // logout callback + bindAccountDelegate bindHandler = new bindAccountDelegate(bindAccountHandle); + IntPtr result = Marshal.GetFunctionPointerForDelegate(bindHandler); + TKG_BindAccountCallback(result); + TKG_BindAccount(loginType,bindType,thirdUid); +#endif + } + +#if UNITY_IOS + // bind account callback + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void bindAccountDelegate(BindAccountStatus status, LoginType type, string msg, string userId, string token, string email, string nickName, string iconUrl,string thirdUids); + [AOT.MonoPInvokeCallback(typeof(bindAccountDelegate))] + static void bindAccountHandle(BindAccountStatus status, LoginType type, string msg, string userId, string token, string email, string nickName, string iconUrl, string thirdUids) + { + + if (TKGSDKCallback.mBindAccountCallback != null) + { + string[] Strs = thirdUids.Split(','); + TKGSDKCallback.mBindAccountCallback.Invoke(status, type, msg, userId, token, email, nickName, iconUrl, Strs); + TKGSDKCallback.mBindAccountCallback = null; + } + } + + + // delete account callback + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void deleteAccountDelegate(DeleteStatus status,string userId); + [AOT.MonoPInvokeCallback(typeof(deleteAccountDelegate))] + static void deleteAccountHandle(DeleteStatus status, string userId) + { + + if (TKGSDKCallback.mDeleteAccountCallback != null) + { + TKGSDKCallback.mDeleteAccountCallback.Invoke(status, userId); + TKGSDKCallback.mDeleteAccountCallback = null; + } + } + + // login out callback + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void logoutDelegate(); + [AOT.MonoPInvokeCallback(typeof(logoutDelegate))] + static void logoutHandle() + { + + if (TKGSDKCallback.mLogoutCallback != null) + { + TKGSDKCallback.mLogoutCallback.Invoke(); + TKGSDKCallback.mLogoutCallback = null; + } + } + + // login callback + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void loginResultDelegate(LoginStatus status, LoginType type, string msg, string userId, string token, string email, string nickName, string iconUrl); + [AOT.MonoPInvokeCallback(typeof(loginResultDelegate))] + static void loginResultHandle(LoginStatus status, LoginType type, string msg, string userId, string token, string email, string nickName, string iconUrl) + { + + if (TKGSDKCallback.mLoginCallback != null) + { + TKGSDKCallback.mLoginCallback.Invoke(status,type,msg,userId,token,email,nickName,iconUrl); + TKGSDKCallback.mLoginCallback = null; + } + } + +#endif + + private static TKGiOSLoginManager s_instance; + + public static TKGiOSLoginManager Instance + { + get + { + if (s_instance == null) + { + GameObject TGGameObject = new GameObject + { + name = "TKGLoginObject" + }; + s_instance = TGGameObject.AddComponent(); + DontDestroyOnLoad(TGGameObject); + } + return s_instance; + } + } +} diff --git a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallbackIOS.cs.meta b/Assets/TKGSDK/Common/internal/iOS/TKGiOSLoginManager.cs.meta similarity index 83% rename from Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallbackIOS.cs.meta rename to Assets/TKGSDK/Common/internal/iOS/TKGiOSLoginManager.cs.meta index 4260592e..7a4ac762 100644 --- a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallbackIOS.cs.meta +++ b/Assets/TKGSDK/Common/internal/iOS/TKGiOSLoginManager.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 4f7da094c07e543bcb390b93b01aba44 +guid: 5590242be350743f5af1a744a9e067ab MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/TKGSDK/Config/Scripts/IAPProducts.cs b/Assets/TKGSDK/Config/Scripts/IAPProducts.cs index dafba808..f98b9dc3 100644 --- a/Assets/TKGSDK/Config/Scripts/IAPProducts.cs +++ b/Assets/TKGSDK/Config/Scripts/IAPProducts.cs @@ -1,16 +1,17 @@ #if USE_IAP -using System.Collections; using System.Collections.Generic; -using UnityEngine; using UnityEngine.Purchasing; -public static class IAPProducts//商品ID统一小写 +public static class IAPProducts { - public const string NoAds = "com.hotpotgames.lovepuzzle.global.noads";//去广告商品ID + /// + /// 去广告商品ID(商品ID统一小写) + /// + public const string NoAds = "mergegangster_noads"; - public static readonly Dictionary ProductDic = new Dictionary() + public readonly static Dictionary ProductDic = new Dictionary() { - { NoAds, ProductType.NonConsumable} + { NoAds, ProductType.NonConsumable}, }; } #endif \ No newline at end of file diff --git a/Assets/TKGSDK/Config/Scripts/TKGAdPositionName.cs b/Assets/TKGSDK/Config/Scripts/TKGAdPositionName.cs index 8211b630..8f0e983b 100644 --- a/Assets/TKGSDK/Config/Scripts/TKGAdPositionName.cs +++ b/Assets/TKGSDK/Config/Scripts/TKGAdPositionName.cs @@ -15,6 +15,8 @@ public enum TKGIVAdPositionName IV_Retry, IV_NextLevel, IV_Back, + IV_Spin + } public enum TKGNativePositionName @@ -38,5 +40,6 @@ public enum TKGRVPositionName Get_Human, Get_Monster, Get_Coin, - Get_AutoMerge, + Get_AutoMerge + } \ No newline at end of file diff --git a/Assets/TKGSDK/Config/Scripts/TKGParams.cs b/Assets/TKGSDK/Config/Scripts/TKGParams.cs index b0dba034..18a25f49 100644 --- a/Assets/TKGSDK/Config/Scripts/TKGParams.cs +++ b/Assets/TKGSDK/Config/Scripts/TKGParams.cs @@ -15,7 +15,7 @@ public static class TKGParams { TKGParamKey.RemoveAdsShowCount.ToString(), 4 }, // int value // { TKGParamKey.LevelList.ToString(), "1,78,72,70,64,65,4,66" }, // string value { TKGParamKey.HasBlock.ToString(), 0 }, // bool value // 1:true 0:false - { TKGParamKey.UserGroup.ToString(), "Default" }, + { TKGParamKey.UserGroup.ToString(), "Default" }, { TKGParamKey.RemoveAdsShow.ToString(), 2 }, { TKGParamKey.RemoveAds.ToString(), 4 }, { TKGParamKey.LevelInterSwitch.ToString(), 3 }, diff --git a/Assets/TKGSDK/Config/TKGLoadConfig.cs b/Assets/TKGSDK/Config/TKGLoadConfig.cs index 469361a1..2ca0a5ad 100644 --- a/Assets/TKGSDK/Config/TKGLoadConfig.cs +++ b/Assets/TKGSDK/Config/TKGLoadConfig.cs @@ -57,13 +57,22 @@ namespace Touka /// private static PlayerPrefPair[] ParseiOSConfigInner() { + + #if AppStore_GB - PlayerPrefPair[] configs = TKGLoadPlistConfig.GetToukaConfig(toukaconfigFile,toukaconfigPathGB); + PlayerPrefPair[] configs = TKGLoadPlistConfig.GetToukaConfig(toukaconfigFile, toukaconfigPathGB); + ParseConfigsInner(configs); + return configs; +#elif AppStore_CN + PlayerPrefPair[] configs = TKGLoadPlistConfig.GetToukaConfig(toukaconfigFile, toukaconfigPathCN); + ParseConfigsInner(configs); + return configs; #else - PlayerPrefPair[] configs = TKGLoadPlistConfig.GetToukaConfig(toukaconfigFile, toukaconfigPathCN); + + return null; #endif - ParseConfigsInner(configs); - return configs; + + } /// diff --git a/Assets/TKGSDK/Demo/ToukaAccountSDKDemo.cs b/Assets/TKGSDK/Demo/ToukaAccountSDKDemo.cs new file mode 100644 index 00000000..4da8bf6c --- /dev/null +++ b/Assets/TKGSDK/Demo/ToukaAccountSDKDemo.cs @@ -0,0 +1,382 @@ +using System; +using System.Linq; +using System.Threading; +using Touka; +using UnityEngine; +using UnityEngine.SceneManagement; +using UnityEngine.UI; + +public class ToukaAccountSDKDemo : MonoBehaviour +{ + public Transform loading; + + public Transform loginView; + + public Transform userCenter; + + public Transform loginView_LoginChannelPanelRoot; + + public Transform userCenter_loginType; + public Transform userCenter_userId; + public Transform userCenter_token; + public Transform userCenter_userType; + + public Transform btnBinded; + public Transform btnBindGoogle; + public Transform btnBindFacebook; + + public Transform PanelUserCenter_BindSelect; + + private string _userId; + private string _token; + private LoginType _userType; + private LoginType _loginType; + + private Action _loginAction; + + private Action + _bindAccountCallback; + + // Start is called before the first frame update + void Start() + { + Loom.QueueOnMainThread((o => { }), ""); + TKGSDKManager.Instance.InitSDK(() => { }); + _loginAction = (status, type, msg, userid, token, email, displayName, photoUrl) => + { + Debug.Log($"登陆回调 {status} type:{type} msg:{msg} userId:{userid} token:{token}"); + if (status == LoginStatus.LOGIN_STATUS_SUCC) + { + _userId = userid; + _userType = type; + _token = token; + ShowUserCenter(); + ToukaToast.ShowToast("登陆成功"); + } + else + { + _userId = ""; + _userType = LoginType.LOGIN_BY_GUESTER; + _token = ""; + ToukaToast.ShowToast($"登陆失败:{msg}"); + ShowLoginView(); + } + }; + + _bindAccountCallback = (status, loginTYpe, msg, userId, token, email, displayName, photoUrl, userIdList) => + { + Debug.Log( + $"绑定回调 {status} type:{loginTYpe} msg:{msg} userId:{userId} token:{token} userIdList:{userIdList}"); + if (status == BindAccountStatus.BIND_CODE_SELECT) + { + Debug.Log("绑定回调 - 选择界面"); + InitBindSelectView(userIdList); + return; + } + + if (status == BindAccountStatus.BIND_CODE_SUCC) + { + Debug.Log("绑定回调 - 绑定成功"); + if (!userId.Equals(_userId)) + { + Debug.Log($"绑定回调 - 绑定成功 - 重新登陆 userId:{userId} _userId:{_userId}"); + CloseBindSelectView(); + // 重新登陆了 + ShowLoading(); + return; + } + + ToukaToast.ShowToast("绑定成功"); + ShowUserCenter(); + return; + } + + ToukaToast.ShowToast($"绑定失败 {msg}"); + }; + ShowLoading(); + } + + + private static void CreateButton(Transform rootViewTransform, string content, out Button myButton) + { + var rootVector2 = rootViewTransform.GetComponent().sizeDelta; + + // 创建一个Button对象 + var buttonGo = new GameObject("MyButton"); + myButton = buttonGo.AddComponent public abstract void OpenMoreGame(); + + /// + /// if is debug mode + /// + public abstract bool IsDebugMode(); + + + /// + /// get user name and user id card + /// + public abstract string GetUserNameAndUserIDCard(); + + /// + /// set segment type to sdk + /// + /// segment type + public abstract void SetSegment(SegmentType type); + + /// + /// get a iap product list for sdk config file + /// + public abstract Dictionary GetIAPProductList(); #endregion #region Others (Uncommon) @@ -407,6 +429,26 @@ namespace Touka /// public abstract void RegistAPNS(); + /// + /// show picture cross + /// + public abstract bool showPictureCross(); + + /// + /// remove picture cross + /// + public abstract void removePictureCross(); + + /// + /// show more game icon + /// + public abstract bool showMoreGameIcon(); + + /// + /// remove more game icon + /// + public abstract void removeMoreGameIcon(); + /// /// shake /// @@ -447,6 +489,131 @@ namespace Touka /// public abstract void SetUserSourceCallback(AndroidTKGUserSourceCalllbackWithCampaignName _userSourceCallback); + /// + /// Set Function Switch Calllback + /// + public abstract void SetFunctionSwitchCalllback(List _functionKeys ,AndroidFunctionSwitchCalllback _functionSwitchCalllback); + #endregion + + #region 数据中台 + + public abstract void LogPurchasePrice(string price,string currency); + + public abstract void LogRobuxCashOut(); + + public abstract void LogNoviceGuideFinish(); + + #endregion + + #region GooglePlay评论引导 + /// + /// Pop up GooglePlay Rate guid + /// + public abstract bool GuidGpComment(); + #endregion + + + #region 用户登录 + /// + /// User Login + /// + public abstract void Login(LoginType loginType, Action _loginResultCallback = null); + /// + /// Logout + /// + public abstract void Logout(Action _logoutCallback = null); + + public abstract List AvailableLoginChannelList(); + + public abstract void DeleteAccount(Action _deleteAccountCallback = null); + + public abstract void BindAccount(LoginType type,BindType isForce, string userId, + Action + bindAccountCallback); + + public abstract void AutoLogin( + Action loginResultCallback); + + public abstract LoginType GetAccountType(); + + public abstract bool IsCanAutoLogin(); + + #endregion + + #region IAP Event + + /// + /// Log IAP button show + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + public abstract void LogIAPBtnShow(string _productName, string _productID); + + /// + /// Log IAP button Click + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + public abstract void LogIAPBtnClick(string _productName, string _productID); + + /// + /// Log IAP First payment successful + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + /// The order id returned by the payment channel + /// Currency ex:USD + /// Price + public abstract void LogIAPFirstPurchase(string _iap, string _id, string _paymentChannelOrderid, string _currency, string _price); + + /// + /// Log IAP payment successful + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + /// The order id on the game side + /// The order id returned by the payment channel + /// Purchase token: When the purchase is successful on GP, ​​a purchase token will be generated as a unique identifier + /// Official payment channels: appstore, googleplay, other payment channels corresponding channel name + /// Currency ex:USD + /// Price + public abstract void LogIAPSuccess(string _iap, string _id, string _gameOrderid, string _paymentChannelOrderid, string _productToken, string _paymentMethod, string _currency, string _price); + + #endregion + + #region MyRegion + + public abstract void SaveCloudArchiving(string content, Action callback); + + public abstract void DetailCloudArchiving(Action callback); + + #endregion + + #region serve for wz + + /// + /// Set userid and third account + /// + /// userID (Unique user id) + /// third account + /// third account type + public abstract void SetUserIDAndThirdAccount(string _userID, string _thirdAccount, ThirdAccountType _thirdAccountType); + + #endregion + + #region client iap pay result + /// + /// Client IAP Success + /// + public abstract void ClientIAPSuccess(string _productName, string _productID, string _purchaseOrderID, string _purchaseToken, string _currency, string _price, string _gameExtra); + + /// + /// Client IAP Failed + /// + public abstract void ClientIAPFailed(string _productName, string _productID, string _purchaseOrderID, string _purchaseToken, string _currency, string _price, string _gameExtra, IAPClientFailReasonType _failType); + + #endregion + } } \ No newline at end of file diff --git a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceAndroid.cs b/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceAndroid.cs index f14ced62..3926b389 100644 --- a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceAndroid.cs +++ b/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceAndroid.cs @@ -3,6 +3,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using UnityEngine; namespace Touka @@ -12,7 +13,6 @@ namespace Touka /// public class TKGNativeInterfaceAndroid : TKGNativeInterface { - private AndroidJavaObject jo; public TKGNativeInterfaceAndroid() @@ -34,6 +34,7 @@ namespace Touka { Debug.LogError(e); } + return default(T); } @@ -49,7 +50,7 @@ namespace Touka } } -#region init + #region init /// /// init @@ -68,12 +69,24 @@ namespace Touka TKGDebugger.LogDebug("init ----- 01 ------- c"); SetSDKCommonCallback(new AndroidTKGCommonCalllback()); TKGDebugger.LogDebug("init ----- 01 ------- d"); - + SetSecondPurchaseCallback(); + SetAdsRevenueCallback(); SDKCall("init", new AndroidProxyCallback()); TKGDebugger.LogDebug("init ----- 02"); } -#endregion + private void SetSecondPurchaseCallback() + { +#if USE_IAP + SDKCall("setSecondPurchaseCallback", new SecondPurchaseCallback()); +#endif + } + private void SetAdsRevenueCallback() + { + SDKCall("setAdsRevenueCallback", new AdsRevenueCallback()); + } + + #endregion /// /// Get Channel @@ -87,7 +100,7 @@ namespace Touka return "AndroidRoot"; } -#region Ads + #region Ads public override void PurchasedRemoveAds() { @@ -98,28 +111,25 @@ namespace Touka public override void SetUnitySDKVersion(string sdkVersion) { - #if UNITY_ANDROID - SDKCall("setUnitySDKVersion","UnitySDK",sdkVersion); + SDKCall("setUnitySDKVersion", "UnitySDK", sdkVersion); #endif - } -#region Ads Show + #region Ads Show /// /// Show banner Ad /// /// bannerAlign - public override void showBannerAd(TKGBannerAlign _pos) + public override void showBannerAd(TKGBannerAlign _pos) { int _posIndex = 2; - if(_pos == TKGBannerAlign.BannerCenterTopAlign) + if (_pos == TKGBannerAlign.BannerCenterTopAlign) { _posIndex = 1; - } - else if(_pos == TKGBannerAlign.BannerCenterBottomAlign) + else if (_pos == TKGBannerAlign.BannerCenterBottomAlign) { _posIndex = 2; } @@ -161,7 +171,6 @@ namespace Touka /// public override void showInterstitialAd(string _adPos, IVADType _IvType = IVADType.IV1) { - #if UNITY_ANDROID SDKCall("showInterstitialAd", _adPos, (int)_IvType); #endif @@ -174,7 +183,6 @@ namespace Touka /// public override void showRewardAd(string _adPos, int _itemCount = -1) { - #if UNITY_ANDROID SDKCall("showRewardAd", _adPos, _itemCount); #endif @@ -208,8 +216,8 @@ namespace Touka public override void SetShowSDKToast(bool _useSDKToast) { #if UNITY_ANDROID + SDKCall("setShowSDKRewardTips", _useSDKToast); #endif - } public override void ShowNativeAd(RectTransform pRect, Camera pCam = null, string pAdPos = "") @@ -224,14 +232,14 @@ namespace Touka float tHeight = Mathf.Abs(tBottomRight.y - tTopLeft.y); // x , y , width , height // ((tTopLeft.x, Screen.height - tTopLeft.y, tWidth, tHeight) - SDKCall("showNative", pAdPos, tTopLeft.x, Screen.height - tTopLeft.y, tWidth, tHeight, pAdPos); + SDKCall("showNative", pAdPos, tTopLeft.x, Screen.height - tTopLeft.y, tWidth, tHeight); #endif - } -#endregion + + #endregion -#region Ads isready + #region Ads isready /// /// banner isReady @@ -239,7 +247,6 @@ namespace Touka /// public override bool isBannerAdReady() { - #if UNITY_ANDROID bool isReady = SDKCall("isBannerAdReady"); return isReady; @@ -268,7 +275,6 @@ namespace Touka /// public override bool isRewardAdReady() { - #if UNITY_ANDROID bool isReady = SDKCall("isRewardAdReady"); return isReady; @@ -301,9 +307,9 @@ namespace Touka #endif } -#endregion + #endregion -#region Set ads callback + #region Set ads callback /// /// Set Banner Ad Callback @@ -345,15 +351,14 @@ namespace Touka /// public override void setVideoAdCallback(AndroidInterADTKGAdCallback _videoCallback) { - #if UNITY_ANDROID SDKCall("setVideoAdCallback", _videoCallback); #endif } -#endregion + #endregion -#region load ads + #region load ads /// /// load interstitial ad @@ -388,14 +393,14 @@ namespace Touka #endif } -#endregion + #endregion -#endregion + #endregion -#region Log Event + #region Log Event -#region Normal + #region Normal /// /// onEvent @@ -451,9 +456,9 @@ namespace Touka #endif } -#endregion + #endregion -#region Level Event + #region Level Event /// /// Level Start @@ -478,9 +483,9 @@ namespace Touka #endif } -#endregion + #endregion -#region Tracking Event + #region Tracking Event /// /// Log Tracking Event @@ -493,11 +498,11 @@ namespace Touka #endif } -#endregion + #endregion -#endregion + #endregion -#region Online Config + #region Online Config /// /// get config - int @@ -535,10 +540,9 @@ namespace Touka return newValue; } + #endregion -#endregion - -#region Others (Common) + #region Others (Common) /// /// review @@ -588,9 +592,42 @@ namespace Touka { SDKCall("setEnableLog", _enable); } -#endregion -#region Others (Uncommon) + /// + /// get a iap product list for sdk config file + /// + public override Dictionary GetIAPProductList() + { + Dictionary dic = new Dictionary(); + return dic; + } + + public override bool IsDebugMode() + { + return SDKCall("isDebugMode"); + } + + + /// + /// get user name and user id card + /// + public override string GetUserNameAndUserIDCard() + { + return "0_0"; + } + + /// + /// set segment type to sdk + /// + /// segment type + public override void SetSegment(SegmentType type) + { + SDKCall("setSegment", type.ToString()); + } + + #endregion + + #region Others (Uncommon) /// /// shake(no repeat) @@ -657,7 +694,7 @@ namespace Touka /// public override void toast(string _content) { - SDKCall("toast"); + SDKCall("dialogTips", _content); } /// @@ -679,27 +716,79 @@ namespace Touka public override void RegistAPNS() { - } - public override void RegistNotification(string notiId, string body, string fireDate, int badge, string title, string subTitle) + /// + /// show picture cross + /// + public override bool showPictureCross() { - + return SDKCall("showPictureCross"); + } + + /// + /// remove picture cross + /// + public override void removePictureCross() + { + SDKCall("removePictureCross"); + } + + /// + /// show more game icon + /// + public override bool showMoreGameIcon() + { + return SDKCall("showMoreGameIcon"); + } + + /// + /// remove more game icon + /// + public override void removeMoreGameIcon() + { + SDKCall("removeMoreGameIcon"); + } + + + public override void RegistNotification(string notiId, string body, string fireDate, int badge, string title, + string subTitle) + { + SDKCall("registNotification", notiId, body, fireDate, badge, title, subTitle); } public override void RemoveNotification(string notiId) { - + SDKCall("removeNotification", notiId); } public override void RemoveAllNotifications() { - + SDKCall("removeAllNotifications"); } -#endregion + #endregion -#region common callback + #region 数据中台 + + public override void LogPurchasePrice(string price, string currency) + { + SDKCall("logPurchasePrice", price, currency); + } + + public override void LogRobuxCashOut() + { + SDKCall("logRobuxCashOut"); + } + + public override void LogNoviceGuideFinish() + { + SDKCall("logNoviceGuideFinish"); + } + + #endregion + + #region common callback public override void SetSDKCommonCallback(AndroidTKGCommonCalllback _commonCallback) { @@ -717,8 +806,227 @@ namespace Touka SDKCall("getUserSource", _userSourceCallback); } -#endregion + public override void SetFunctionSwitchCalllback(List _functionKeys, + AndroidFunctionSwitchCalllback _functionSwitchCalllback) + { + string keys = ""; + for (int i = 0; i < _functionKeys.Count; i++) + { + FunctionType enumType = _functionKeys[i]; + string enumTypeString = enumType.ToString(); + if (keys != "") + { + keys = keys + "@"; + } + + keys = keys + enumTypeString; + } + + SDKCall("setGameSwitchListener", keys, _functionSwitchCalllback); + } + + public override bool GuidGpComment() + { + return SDKCall("guidGpComment"); + } + + #endregion + + #region 用户登录 + + public override void Login(LoginType loginType, + Action _loginResultCallback = null) + { + TKGSDKCallback.mLoginCallback = _loginResultCallback; + SDKCall("login", (int)loginType, new AndroidLoginCalllback()); + } + + public override void Logout(Action _logoutCallback = null) + { + TKGSDKCallback.mLogoutCallback = _logoutCallback; + SDKCall("logout", new AndroidLoginCalllback()); + } + + public override List AvailableLoginChannelList() + { + var availableLoginChannelList = SDKCall("availableLoginChannelList"); + return availableLoginChannelList.Select(channel => (LoginType)Enum.ToObject(typeof(LoginType), channel)) + .ToList(); + } + + public override void DeleteAccount(Action deleteAccountCallback = null) + { + TKGSDKCallback.mDeleteAccountCallback = deleteAccountCallback; + SDKCall("deleteAccount", new AndroidLoginCalllback()); + } + + public override void BindAccount(LoginType type, BindType isForce, string userId, + Action + bindAccountCallback) + { + TKGSDKCallback.mBindAccountCallback = bindAccountCallback; + SDKCall("bindAccount", (int)type, (int)isForce, userId, new AndroidLoginCalllback()); + } + + public override void AutoLogin( + Action loginResultCallback) + { + TKGSDKCallback.mAutoLoginCallback = loginResultCallback; + SDKCall("autoLogin", new AndroidLoginCalllback(isAutoLogin: true)); + } + + public override LoginType GetAccountType() + { + var userType = SDKCall("getUserType"); + return (LoginType)Enum.ToObject(typeof(LoginType), userType); + } + + public override bool IsCanAutoLogin() + { + return SDKCall("isCanAutoLogin"); + } + + #endregion + + #region IAP Event + + /// + /// Log IAP button show + /// + public override void LogIAPBtnShow(string _productName, string _productID) + { + Dictionary _keyValues = new Dictionary(); + _keyValues.Add("IAP", _productName); + _keyValues.Add("ID", _productID); + //_keyValues.Add("Currency", _currency); + //_keyValues.Add("Price", _price); + onEvent("IAP_Button_Show", _keyValues); + } + + /// + /// Log IAP button Click + /// + public override void LogIAPBtnClick(string _productName, string _productID) + { + Dictionary _keyValues = new Dictionary(); + _keyValues.Add("IAP", _productName); + _keyValues.Add("ID", _productID); + //_keyValues.Add("Currency", _currency); + //_keyValues.Add("Price", _price); + onEvent("IAP_Button_Click", _keyValues); + } + + /// + /// Log IAP First payment successful + /// + public override void LogIAPFirstPurchase(string _iap, string _id, string _paymentChannelOrderid, + string _currency, string _price) + { + // 放到native层实现了 + //Dictionary _keyValues = new Dictionary(); + //_keyValues.Add("IAP", _iap); + //_keyValues.Add("ID", _id); + //_keyValues.Add("Currency", _currency); + //_keyValues.Add("Price", _price); + //_keyValues.Add("order_id", _paymentChannelOrderid); + //onEvent("First_purchase", _keyValues); + } + + /// + /// Log IAP payment successful + /// + public override void LogIAPSuccess(string _iap, string _id, string _gameOrderid, string _paymentChannelOrderid, + string _productToken, string _paymentMethod, string _currency, string _price) + { + // 放到native层实现了 + //Dictionary _keyValues = new Dictionary(); + //_keyValues.Add("IAP", _iap); + //_keyValues.Add("ID", _id); + //_keyValues.Add("Currency", _currency); + //_keyValues.Add("Price", _price); + //_keyValues.Add("order_id", _paymentChannelOrderid); + //onEvent("IAP_Success", _keyValues); + //SDKCall("logIAPSuccess", _price, _id, _gameOrderid, _paymentChannelOrderid, _productToken, _currency, _paymentMethod, _iap); + } + + public override void SaveCloudArchiving(string content, Action callback) + { + void Action(CommonCallbackCode code, string s) + { + if (code == CommonCallbackCode.SaveCloudArchiving_Succ || + code == CommonCallbackCode.SaveCloudArchiving_Fail) + { + callback.Invoke(code == CommonCallbackCode.SaveCloudArchiving_Succ ? 0 : -1, s); + TKGSDKCallback.RemoveTKGCommonCallback(Action); + } + } + + TKGSDKCallback.SetTKGCommonCallback(Action); + SDKCall("saveCloudArchiving", content); + } + + public override void DetailCloudArchiving(Action callback) + { + void Action(CommonCallbackCode code, string s) + { + if (code == CommonCallbackCode.DetailCloudArchiving_Succ || + code == CommonCallbackCode.DetailCloudArchiving_Fail) + { + callback.Invoke(code == CommonCallbackCode.DetailCloudArchiving_Succ ? 0 : -1, s); + TKGSDKCallback.RemoveTKGCommonCallback(Action); + } + } + + TKGSDKCallback.SetTKGCommonCallback(Action); + SDKCall("detailCloudArchiving"); + } + + #endregion + + + #region serve for wz + + /// + /// Set userid and third account + /// + /// userID (Unique user id) + /// third account + /// third account type + public override void SetUserIDAndThirdAccount(string _userID, string _thirdAccount, + ThirdAccountType _thirdAccountType) + { + Debug.Log("【TKGNativeInterfaceAndroid】 SetUserIDAndThirdAccount _userID : " + _userID + + " , _thirdAccount : " + _thirdAccount + " , _thirdAccountType : " + _thirdAccountType); + SDKCall("setUserIDAndThirdAccount", _userID, _thirdAccount, _thirdAccountType.ToString()); + } + + #endregion + + #region client iap pay result + + /// + /// Client IAP Success + /// + public override void ClientIAPSuccess(string _productName, string _productID, string _purchaseOrderID, + string _purchaseToken, string _currency, string _price, string _gameExtra) + { + SDKCall("ClientIAPSuccess", _productName, _productID, _purchaseOrderID, _purchaseToken, _currency, _price, + _gameExtra); + } + + /// + /// Client IAP Failed + /// + public override void ClientIAPFailed(string _productName, string _productID, string _purchaseOrderID, + string _purchaseToken, string _currency, string _price, string _gameExtra, + IAPClientFailReasonType _failType) + { + SDKCall("ClientIAPFailed", _productName, _productID, _purchaseOrderID, _purchaseToken, _currency, _price, + _gameExtra, _failType.ToString()); + } + + #endregion } } diff --git a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceDefault.cs b/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceDefault.cs index 0faea728..46eb3b5e 100644 --- a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceDefault.cs +++ b/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceDefault.cs @@ -1,6 +1,7 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using UnityEngine; namespace Touka @@ -17,7 +18,6 @@ namespace Touka public override void SetUnitySDKVersion(string sdkVersion) { - } /// @@ -35,14 +35,12 @@ namespace Touka /// public override void SetLogEnable(bool _enable) { - } #region Ads public override void PurchasedRemoveAds() { - } #region Ads Show @@ -53,7 +51,6 @@ namespace Touka /// bannerAlign public override void showBannerAd(TKGBannerAlign _pos) { - } /// @@ -61,7 +58,6 @@ namespace Touka /// public override void hideBannerAd() { - } /// @@ -69,7 +65,6 @@ namespace Touka /// public override void showInterstitialAd() { - } /// @@ -77,7 +72,6 @@ namespace Touka /// public override void showInterstitialAd(string _adPos, IVADType _IvType = IVADType.IV1) { - } /// @@ -85,7 +79,6 @@ namespace Touka /// public override void showRewardAd(string _adPos, int _itemCount = -1) { - } /// @@ -96,7 +89,6 @@ namespace Touka /// public override void showRewardAd(string _adPos, int _itemCount, Dictionary _extraEvent) { - } /// @@ -104,7 +96,6 @@ namespace Touka /// public override void showVideoAd(string _adPos, int _itemCount = -1) { - } #endregion @@ -158,7 +149,6 @@ namespace Touka /// public override void SetBannerAdCallback(AndroidBannerADTKGAdCallback _bannerCallback) { - } /// @@ -167,7 +157,6 @@ namespace Touka /// public override void SetRewardClickListener(Action _rewardClickAction) { - } /// @@ -176,7 +165,6 @@ namespace Touka /// public override void SetGameFocusListener(Action _gameFocusAction) { - } /// @@ -185,7 +173,6 @@ namespace Touka /// public override void setInterstitalAdCallback(AndroidInterADTKGAdCallback _interCallback) { - } /// @@ -194,7 +181,6 @@ namespace Touka /// public override void SetRewardAdCallback(AndroidRewardADTKGAdCallback _rewardCallback) { - } /// @@ -203,7 +189,6 @@ namespace Touka /// public override void setVideoAdCallback(AndroidInterADTKGAdCallback _videoCallback) { - } #endregion @@ -216,7 +201,6 @@ namespace Touka /// public override void loadInterstitialAD() { - } /// @@ -225,7 +209,6 @@ namespace Touka /// public override void loadRewardAD() { - } /// @@ -234,10 +217,8 @@ namespace Touka /// public override void loadVideoAD() { - } - #endregion #endregion @@ -252,7 +233,6 @@ namespace Touka /// public override void onEvent(string _eventName) { - } /// @@ -264,7 +244,6 @@ namespace Touka /// public override void onEvent(string _eventName, string _key01, string _value01) { - } /// @@ -278,7 +257,6 @@ namespace Touka /// public override void onEvent(string _eventName, string _key01, string _value01, string _key02, string _value02) { - } /// @@ -288,7 +266,6 @@ namespace Touka /// public override void onEvent(string _eventName, Dictionary _keyValues) { - } #region Level Event @@ -299,7 +276,6 @@ namespace Touka /// public override void LevelStart(string _levelId) { - } /// @@ -309,7 +285,6 @@ namespace Touka /// public override void LevelEnd(string _levelId, StageResult _stageResult) { - } #endregion @@ -322,12 +297,10 @@ namespace Touka /// public override void LogTrackingEvent(TrackingEventType _eventType) { - } #endregion - #endregion #region Online Config @@ -371,7 +344,6 @@ namespace Touka /// public override void Review() { - } /// @@ -379,7 +351,6 @@ namespace Touka /// public override void OpenPrivacyURL() { - } /// @@ -387,7 +358,6 @@ namespace Touka /// public override void OpenUserTermURL() { - } /// @@ -395,7 +365,6 @@ namespace Touka /// public override void OpenPolicyPop() { - } /// @@ -403,7 +372,6 @@ namespace Touka /// public override void OpenMoreGame() { - } #endregion @@ -416,7 +384,36 @@ namespace Touka /// shake time public override void shake(int _shakeType, float _intensity = 1) { + } + /// + /// show picture cross + /// + public override bool showPictureCross() + { + return false; + } + + /// + /// remove picture cross + /// + public override void removePictureCross() + { + } + + /// + /// show more game icon + /// + public override bool showMoreGameIcon() + { + return false; + } + + /// + /// remove more game icon + /// + public override void removeMoreGameIcon() + { } /// @@ -434,7 +431,6 @@ namespace Touka /// public override void cancelShake() { - } /// @@ -447,7 +443,6 @@ namespace Touka /// content public override void dialogTips(string _titleStr, string _contentStr) { - } /// @@ -456,7 +451,6 @@ namespace Touka /// public override void openUrlBrowser(string _url) { - } /// @@ -465,7 +459,6 @@ namespace Touka /// public override void openWebUrl(string _url) { - } /// @@ -474,7 +467,6 @@ namespace Touka /// public override void toast(string _content) { - } /// @@ -482,7 +474,6 @@ namespace Touka /// public override void pushMsg() { - } #endregion @@ -491,23 +482,50 @@ namespace Touka public override void SetSDKCommonCallback(AndroidTKGCommonCalllback _commonCallback) { - } public override void SetUserSourceCallback(AndroidTKGUserSourceCalllback _userSourceCallback) { - } public override void SetUserSourceCallback(AndroidTKGUserSourceCalllbackWithCampaignName _userSourceCallback) { + } + /// + /// get a iap product list for sdk config file + /// + public override Dictionary GetIAPProductList() + { + return new Dictionary(); } public override void RemoveNativeAd() { } + + /// + /// set segment type to sdk + /// + /// segment type + public override void SetSegment(SegmentType type) + { + } + + public override bool IsDebugMode() + { + return false; + } + + /// + /// get user name and user id card + /// + public override string GetUserNameAndUserIDCard() + { + return "0_0"; + } + public override bool IsReadyNativeAd() { return false; @@ -515,41 +533,265 @@ namespace Touka public override void ShowNativeAd(RectTransform pRect, Camera pCam = null, string pAdPos = "") { - } public override void ShareTxt(string _shareTxt) { - } public override void RegistAPNS() { - } - public override void RegistNotification(string notiId, string body, string fireDate, int badge, string title, string subTitle) + public override void RegistNotification(string notiId, string body, string fireDate, int badge, string title, + string subTitle) { - } public override void RemoveNotification(string notiId) { - } public override void RemoveAllNotifications() { - } public override void SetShowSDKToast(bool _useSDKToast) { + } + public override void SetFunctionSwitchCalllback(List _functionKeys, + AndroidFunctionSwitchCalllback _functionSwitchCalllback) + { } #endregion + #region 数据中台 + + public override void LogPurchasePrice(string price,string currency) + { + } + + public override void LogRobuxCashOut() + { + } + + public override void LogNoviceGuideFinish() + { + } + + public override bool GuidGpComment() + { + return true; + } + + #endregion + + #region 用户登录 + + public override void Login(LoginType loginType, + Action loginResultCallback = null) + { + Server.Instance.Login(loginType, (status, msg, loginInfo) => + { + PlayerPrefs.SetInt("last_login_type", (int)loginType); + var loginStatus = status == 0 ? LoginStatus.LOGIN_STATUS_SUCC : LoginStatus.LOGIN_STATUS_FAILED; + var loginTypeEnum = (LoginType)Enum.ToObject(typeof(LoginType), loginInfo.user_type); + PlayerPrefs.SetString("user_id", loginInfo.user_id); + PlayerPrefs.SetString("token", loginInfo.token); + PlayerPrefs.SetInt("user_type", loginInfo.user_type); + loginResultCallback?.Invoke(loginStatus, loginTypeEnum, msg, loginInfo.user_id, loginInfo.token, "", "", + ""); + }); + } + + public override void Logout(Action _logoutCallback = null) + { + PlayerPrefs.DeleteKey("last_login_type"); + PlayerPrefs.DeleteKey("user_id"); + PlayerPrefs.DeleteKey("user_type"); + PlayerPrefs.DeleteKey("token"); + _logoutCallback?.Invoke(); + } + + public override List AvailableLoginChannelList() + { + var loginChannels = PlayerPrefs.GetString("loginChannels", "" + (int)LoginType.LOGIN_BY_GUESTER); + return loginChannels.Split(',') + .Select(channel => (LoginType)Enum.ToObject(typeof(LoginType), int.Parse(channel))).ToList(); + } + + public override void DeleteAccount(Action deleteAccountCallback = null) + { + Server.Instance.DeleteAccount(PlayerPrefs.GetString("user_id"), (code, msg) => + { + // 退出账号 + Logout(); + deleteAccountCallback?.Invoke( + code == 0 ? DeleteStatus.DELETE_ACCOUNT_SUCC : DeleteStatus.DELETE_ACCOUNT_FAILED, msg); + }); + } + + public override void BindAccount(LoginType type, BindType isForce, string userId, + Action + bindAccountCallback) + { + var thirdUserId = ""; + + switch (type) + { + case LoginType.LOGIN_BY_GOOGLE: + thirdUserId = PlayerPrefs.GetString("google_user_id"); + break; + case LoginType.LOGIN_BY_FACEBOOK: + thirdUserId = PlayerPrefs.GetString("facebook_user_id"); + break; + } + + if (isForce == BindType.NO_FORCE) + { + userId = PlayerPrefs.GetString("user_id"); + } + + Server.Instance.Bind(type, isForce, thirdUserId, userId, (status, msg, data) => + { + if (status != 0) + { + bindAccountCallback.Invoke(BindAccountStatus.BIND_CODE_FAILED, type, msg, data.user_id, data.token, + "", "", "", data.user_ids); + return; + } + + if (data.user_ids != null && data.user_ids.Length == 2) + { + // (status, loginTYpe, msg, userId, token, email, displayName, photoUrl, userIdList) + bindAccountCallback.Invoke(BindAccountStatus.BIND_CODE_SELECT, type, msg, data.user_id, data.token, + "", "", "", data.user_ids); + } + else + { + PlayerPrefs.SetString("user_id", data.user_id); + PlayerPrefs.SetString("token", data.token); + PlayerPrefs.SetInt("user_type", (int)type); + + bindAccountCallback.Invoke(BindAccountStatus.BIND_CODE_SUCC, type, msg, data.user_id, data.token, + "", "", "", data.user_ids); + } + }); + } + + public override void AutoLogin( + Action loginResultCallback) + { + if (!IsCanAutoLogin()) + { + loginResultCallback?.Invoke(LoginStatus.LOGIN_STATUS_NO_CACHE, LoginType.LOGIN_BY_AUTO, + "not cache login", "", "", "", "", ""); + } + else + { + var lastLoginType = PlayerPrefs.GetInt("last_login_type"); + Login((LoginType)Enum.ToObject(typeof(LoginType), lastLoginType), loginResultCallback); + } + } + + public override LoginType GetAccountType() + { + var userType = PlayerPrefs.GetInt("user_type"); + return (LoginType)Enum.ToObject(typeof(LoginType), userType); + } + + public override bool IsCanAutoLogin() + { + return PlayerPrefs.HasKey("last_login_type"); + } + + #endregion + + #region IAP Event + + /// + /// Log IAP button show + /// + public override void LogIAPBtnShow(string _productName, string _productID) + { + } + + /// + /// Log IAP button Click + /// + public override void LogIAPBtnClick(string _productName, string _productID) + { + } + + /// + /// Log IAP First payment successful + /// + public override void LogIAPFirstPurchase(string _iap, string _id, string _paymentChannelOrderid, string _currency, string _price) + { + } + + /// + /// Log IAP payment successful + /// + public override void LogIAPSuccess(string _iap, string _id, string _gameOrderid, string _paymentChannelOrderid, + string _productToken, string _paymentMethod, string _currency, string _price) + { + } + + public override void SaveCloudArchiving(string content, Action callback) + { + var userId = PlayerPrefs.GetString("user_id"); + var token = PlayerPrefs.GetString("token"); + Server.Instance.SaveCloudArchiving(userId, token, content, callback); + } + + public override void DetailCloudArchiving(Action callback) + { + var userId = PlayerPrefs.GetString("user_id"); + var token = PlayerPrefs.GetString("token"); + Server.Instance.DetailCloudArchiving(userId, token, + (code, msg, content) => { callback.Invoke(code, code == 0 ? content : msg); }); + } + + #endregion + + + #region + + /// + /// Set userid and third account + /// + /// userID (Unique user id) + /// third account + /// third account type + public override void SetUserIDAndThirdAccount(string _userID, string _thirdAccount, ThirdAccountType _thirdAccountType) + { + Debug.Log("【TKGNativeInterfaceDefault】 SetUserIDAndThirdAccount _userID : " + _userID + " , _thirdAccount : " + _thirdAccount + " , _thirdAccountType : " + _thirdAccountType); + } + + #endregion + + #region client iap pay result + /// + /// Client IAP Success + /// + public override void ClientIAPSuccess(string _productName, string _productID, string _purchaseOrderID, string _purchaseToken, string _currency, string _price, string _gameExtra) + { + // todo 直接回调支付成功 + TKGSDKCallback.mSecondPurchaseCallback?.Invoke(_purchaseOrderID,_productName, _productID, true, _gameExtra); + } + + /// + /// Client IAP Failed + /// + public override void ClientIAPFailed(string _productName, string _productID, string _purchaseOrderID, string _purchaseToken, string _currency, string _price, string _gameExtra, IAPClientFailReasonType _failType) + { + // todo 直接回调支付失败 + TKGSDKCallback.mSecondPurchaseCallback?.Invoke(_purchaseOrderID, _productName, _productID, false, _gameExtra); + } + #endregion } } \ No newline at end of file diff --git a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceIOS.cs b/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceIOS.cs index f3b58d5e..5ab87ae5 100644 --- a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceIOS.cs +++ b/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGNativeInterfaceIOS.cs @@ -26,11 +26,7 @@ namespace Touka /// public override string GetChannel() { -#if !AppStore_GB - return "AppStore_CN"; -#else - return "AppStore_GB"; -#endif + return TGiOSAdManager.Instance.getChannel().ToString(); } /// @@ -61,6 +57,7 @@ namespace Touka } + public override void RemoveNativeAd() { #if !UNITY_EDITOR @@ -511,6 +508,55 @@ namespace Touka TGiOSAdManager.Instance.share(_shareTxt); } + /// + /// show picture cross + /// + public override bool showPictureCross() + { + +#if UNITY_EDITOR + return false; +#else + return TGiOSAdManager.Instance.showPictureCross(); +#endif + } + + /// + /// remove picture cross + /// + public override void removePictureCross() + { + +#if !UNITY_EDITOR + TGiOSAdManager.Instance.removePictureCross(); +#endif + } + + /// + /// show more game icon + /// + public override bool showMoreGameIcon() + { + +#if UNITY_EDITOR + return false; +#else + return TGiOSAdManager.Instance.showMoreGameIcon(); +#endif + } + + /// + /// remove more game icon + /// + public override void removeMoreGameIcon() + { + +#if !UNITY_EDITOR + TGiOSAdManager.Instance.removeMoreGameIcon(); +#endif + } + + public override void RegistAPNS() { #if !UNITY_EDITOR @@ -551,6 +597,35 @@ namespace Touka TGiOSAdManager.Instance.shake(_shakeType,_intensity); } + /// + /// get a iap product list for sdk config file + /// + public override Dictionary GetIAPProductList() + { + return TGiOSAdManager.Instance.getIAPProductList() ; + } + + /// + /// set segment type to sdk + /// + /// segment type + public override void SetSegment(SegmentType type) + { + TGiOSAdManager.Instance.SetSegment(type.ToString()); + } + + public override bool IsDebugMode() + { + return TGiOSAdManager.Instance.isDebugMode(); + } + + /// + /// get user name and user id card + /// + public override string GetUserNameAndUserIDCard() + { + return TGiOSAdManager.Instance.getUserNameAndUserIDCard(); + } /// /// shake(can repeat) /// @@ -621,6 +696,32 @@ namespace Touka #endregion +#region 数据中台 + + public override void LogPurchasePrice(string price,string currency) + { + +#if !UNITY_EDITOR + TGiOSAdManager.Instance.LogPurchasePrice(price,currency); +#endif + } + + public override void LogRobuxCashOut() + { +#if !UNITY_EDITOR + TGiOSAdManager.Instance.LogRobuxCashOut(); +#endif + } + + public override void LogNoviceGuideFinish() + { +#if !UNITY_EDITOR + TGiOSAdManager.Instance.LogNoviceGuideFinish(); +#endif + } + +#endregion + #region common callback public override void SetSDKCommonCallback(AndroidTKGCommonCalllback _commonCallback) @@ -638,10 +739,227 @@ namespace Touka } + public override void SetFunctionSwitchCalllback(List _functionKeys, AndroidFunctionSwitchCalllback _functionSwitchCalllback) + { + string temp = ""; + if (_functionKeys.Count != 0) + { + for (int index = 0; index < _functionKeys.Count; index++) + { + + if (index == _functionKeys.Count - 1) + { + temp += _functionKeys[index]; + } + else + { + temp = temp + _functionKeys[index] + ","; + } + } + } + + TGiOSAdManager.Instance.setFunctions(temp); + } + + public override bool GuidGpComment() + { + return false; + } #endregion +#region 用户登录 + public override void Login(LoginType loginType, Action _loginResultCallback = null) + { + TKGSDKCallback.mLoginCallback = _loginResultCallback; + TKGiOSLoginManager.Instance.Login(loginType); + } + + public override void Logout(Action _logoutCallback = null) + { + TKGSDKCallback.mLogoutCallback = _logoutCallback; + TKGiOSLoginManager.Instance.Logout(); + } + + public override List AvailableLoginChannelList() + { + return TKGiOSLoginManager.Instance.AvailableLoginChannelList(); + } + + public override void DeleteAccount(Action _deleteAccountCallback = null) + { + TKGSDKCallback.mDeleteAccountCallback = _deleteAccountCallback; + TKGiOSLoginManager.Instance.DeleteAccount(); + } + + public override void BindAccount(LoginType type, BindType isForce, string userId, Action bindAccountCallback) + { + TKGSDKCallback.mBindAccountCallback = bindAccountCallback; + TKGiOSLoginManager.Instance.BindAccount(type,isForce,userId); + } + +#endregion + +#region IAP Event + + /// + /// Log IAP button show + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + /// Currency ex:USD + /// Price + public override void LogIAPBtnShow(string _productName, string _productID) + { + Dictionary _keyValues = new Dictionary(); + _keyValues.Add("IAP", _productName); + _keyValues.Add("ID", _productID); + //_keyValues.Add("Currency", _currency); + //_keyValues.Add("Price", _price); + onEvent("IAP_Button_Show", _keyValues); + } + + /// + /// Log IAP button Click + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + /// Currency ex:USD + /// Price + public override void LogIAPBtnClick(string _productName, string _productID) + { + Dictionary _keyValues = new Dictionary(); + _keyValues.Add("IAP", _productName); + _keyValues.Add("ID", _productID); + //_keyValues.Add("Currency", _currency); + //_keyValues.Add("Price", _price); + onEvent("IAP_Button_Click", _keyValues); + + } + + /// + /// Log IAP First payment successful + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + /// Currency ex:USD + /// Price + public override void LogIAPFirstPurchase(string _iap, string _id, string _paymentChannelOrderid, string _currency, string _price) + { + // native 层实现 + //Dictionary _keyValues = new Dictionary(); + //_keyValues.Add("IAP", _iap); + //_keyValues.Add("ID", _id); + //_keyValues.Add("Currency", _currency); + //_keyValues.Add("Price", _price); + //_keyValues.Add("order_id", _paymentChannelOrderid); + //onEvent("First_purchase", _keyValues); + + } + + /// + /// Log IAP payment successful + /// + /// Product name (customized on the game side) English name of the product cannot contain special characters ex: Gem100 + /// Product ID: The ID of a specific product type + /// The order id on the game side + /// The order id returned by the payment channel + /// Purchase token: When the purchase is successful on GP, ​​a purchase token will be generated as a unique identifier + /// Official payment channels: appstore, googleplay, other payment channels corresponding channel name + /// Currency ex:USD + /// Price + public override void LogIAPSuccess(string _iap, string _id, string _gameOrderid, string _paymentChannelOrderid, string _productToken, string _paymentMethod, string _currency, string _price) + { + //Dictionary _keyValues = new Dictionary(); + //_keyValues.Add("IAP", _iap); + //_keyValues.Add("ID", _id); + //_keyValues.Add("Currency", _currency); + //_keyValues.Add("Price", _price); + //_keyValues.Add("order_id", _paymentChannelOrderid); + //onEvent("IAP_Success", _keyValues); + + //Dictionary _dataCenterDict = new Dictionary(); + //_dataCenterDict.Add("iap_name", _iap); + //_dataCenterDict.Add("product_id",_id); + //_dataCenterDict.Add("game_order_id",_gameOrderid); + //_dataCenterDict.Add("order_id",_paymentChannelOrderid); + //_dataCenterDict.Add("purchase_token", _productToken); + //_dataCenterDict.Add("payment_method", _paymentMethod); + //_dataCenterDict.Add("currency", _currency); + //_dataCenterDict.Add("price", _price); + //onEvent("IAP_DataCenter",_dataCenterDict); + + } + + public override void AutoLogin(Action loginResultCallback) + { + TKGSDKCallback.mLoginCallback = loginResultCallback; + TKGiOSLoginManager.Instance.AutoLogin(); + } + + public override LoginType GetAccountType() + { + var userType = PlayerPrefs.GetInt("user_type"); + return (LoginType)Enum.ToObject(typeof(LoginType), userType); + } + + public override void SaveCloudArchiving(string content, Action callback) + { + + } + + public override void DetailCloudArchiving(Action callback) + { + + } + + public override bool IsCanAutoLogin() + { + + return TKGiOSLoginManager.Instance.IsCanAutoLogin(); + } + +#endregion + +#region serve for wz + + /// + /// Set userid and third account + /// + /// userID (Unique user id) + /// third account + /// third account type + public override void SetUserIDAndThirdAccount(string _userID, string _thirdAccount, ThirdAccountType _thirdAccountType) + { + Debug.Log("【TKGNativeInterfaceiOS】 SetUserIDAndThirdAccount _userID : " + _userID + " , _thirdAccount : " + _thirdAccount + " , _thirdAccountType : " + _thirdAccountType); +#if !UNITY_EDITOR + TGiOSAdManager.Instance.setUserIDAndThirdAccount(_userID, _thirdAccount, _thirdAccountType); +#endif + } + #endregion + #region client iap pay result + /// + /// Client IAP Success + /// + public override void ClientIAPSuccess(string _productName, string _productID, string _purchaseOrderID, string _purchaseToken, string _currency, string _price, string _gameExtra) + { +#if !UNITY_EDITOR + TGiOSAdManager.Instance.IAP_ClientIAPSuccess(_productName, _productID, _purchaseOrderID, _purchaseToken, _currency, _price, _gameExtra); +#endif + } + + /// + /// Client IAP Failed + /// + public override void ClientIAPFailed(string _productName, string _productID, string _purchaseOrderID, string _purchaseToken, string _currency, string _price, string _gameExtra, IAPClientFailReasonType _failType) + { +#if !UNITY_EDITOR + TGiOSAdManager.Instance.IAP_ClientIAPFailed(_productName, _productID, _purchaseOrderID, _purchaseToken, _currency, _price, _gameExtra, _failType); +#endif + } + +#endregion } } diff --git a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallback.cs b/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallback.cs index 084d9d7b..45487fb3 100644 --- a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallback.cs +++ b/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallback.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -21,12 +21,31 @@ namespace Touka // tkg user source public static Action mTKGUserSourceCallbackWithCampaignName = null; + //FunctionSwitchCalllback + public static Action mFunctionSwitchCalllback = null; + // tkg common callback public static Action mTKGCommonCallback = null; // tkg reward click callback public static Action mRewardClickCallback = null; - + + // tkg ads revenue callback + // adsType, price, currency + public static Action mAdsRevenueCallback = null; + + // Login result callback + public static Action mLoginCallback = null; + + // Logout callback + public static Action mLogoutCallback = null; + + public static Action mDeleteAccountCallback = null; + + public static Action mBindAccountCallback; + + // auto Login result callback + public static Action mAutoLoginCallback = null; #region 插屏广告 @@ -52,6 +71,16 @@ namespace Touka #endregion + #region iap + + /// + /// SecondPurchaseCallback + /// orderID, productName, productID, purchase result, game extra param + /// + public static Action mSecondPurchaseCallback = null; + + #endregion + /// /// set init callback @@ -77,7 +106,16 @@ namespace Touka /// public static void SetTKGCommonCallback(Action _commonCallbackAction) { - mTKGCommonCallback = _commonCallbackAction; + mTKGCommonCallback += _commonCallbackAction; + } + + /// + /// set common callback + /// + /// + public static void RemoveTKGCommonCallback(Action _commonCallbackAction) + { + mTKGCommonCallback -= _commonCallbackAction; } /// @@ -99,9 +137,52 @@ namespace Touka mTKGUserSourceCallbackWithCampaignName = _userSourceCallbackWithCampaignNameAction; } + + /// + /// Set Function Switch Calllback + /// + /// + public static void SetFunctionSwitchCalllback(Action _functionSwitchCalllback) + { + mFunctionSwitchCalllback = _functionSwitchCalllback; + } + + #region for wz + + /// + /// Set Reward Click Callback + /// + /// public static void SetRewardClickCallback(Action _rewardClickAction) { mRewardClickCallback = _rewardClickAction; } + + + /// + /// ads revenue callback + /// + /// adsType, price, currency + /// + public static void SetAdsRevenueCallback(Action _adsRevenueCallback) + { + mAdsRevenueCallback = _adsRevenueCallback; + } + + #endregion + + #region IAP Second purchase + + /// + /// set game pause/resume callback + /// orderID, productName, productID, purchase result, game extra param + /// + /// + public static void SetSecondPurchaseCallback(Action _nativePurchaseAction) + { + mSecondPurchaseCallback = _nativePurchaseAction; + } + + #endregion } } \ No newline at end of file diff --git a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallbackAndroid.cs b/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallbackAndroid.cs index e927178f..98c2352a 100644 --- a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallbackAndroid.cs +++ b/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallbackAndroid.cs @@ -1,4 +1,5 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -6,17 +7,17 @@ namespace Touka { public class TKGSDKCallbackAndroid { - } - /// /// TGK framework level callback /// public class AndroidProxyCallback : AndroidJavaProxy { - public AndroidProxyCallback() : base("com.touka.tkg.idal.ITKGProxyCallback") { } + public AndroidProxyCallback() : base("com.touka.tkg.idal.ITKGProxyCallback") + { + } // init succ callback public void onInitSuccess() @@ -87,7 +88,6 @@ namespace Touka { TKGSDKCallback.mGameFocusCallback.Invoke(false); } - }, ""); } @@ -104,7 +104,6 @@ namespace Touka } }, ""); } - } /// @@ -112,7 +111,9 @@ namespace Touka /// public class AndroidInterADTKGAdCallback : AndroidJavaProxy { - public AndroidInterADTKGAdCallback() : base("com.touka.tkg.idal.ITKGAdCallback") { } + public AndroidInterADTKGAdCallback() : base("com.touka.tkg.idal.ITKGAdCallback") + { + } public void onClosed() { @@ -125,8 +126,8 @@ namespace Touka TKGSDKCallback.mInterAdCallback = null; } }, ""); - } + public void onClicked() { TKGDebugger.LogDebug("onClicked"); @@ -137,18 +138,22 @@ namespace Touka { TKGDebugger.LogDebug("onSkip"); } + public void onLoaded() { TKGDebugger.LogDebug("onLoaded"); } + public void onLoadFail(int code, string msg) { TKGDebugger.LogDebug("onLoadFail"); } + public void onShow() { TKGDebugger.LogDebug("onShow"); } + public void onShowFail(int code, string msg) { TKGDebugger.LogDebug("onShowFail"); @@ -156,7 +161,8 @@ namespace Touka if (code == (int)AdShowFailCodeType.AdIsNotReady) { TKGDebugger.LogDebug("iv show failed - AdIsNotReady"); - }else if(code == (int)AdShowFailCodeType.AdIsReadyCannotShow) + } + else if (code == (int)AdShowFailCodeType.AdIsReadyCannotShow) { TKGDebugger.LogDebug("iv show failed - AdIsReadyCannotShow"); } @@ -181,12 +187,15 @@ namespace Touka /// public class AndroidRewardADTKGAdCallback : AndroidJavaProxy { - public AndroidRewardADTKGAdCallback() : base("com.touka.tkg.idal.ITKGRewardADCallback") { } + public AndroidRewardADTKGAdCallback() : base("com.touka.tkg.idal.ITKGRewardADCallback") + { + } public void onClosed() { TKGDebugger.LogDebug("AndroidRewardADTKGAdCallback onClosed"); } + public void onClicked() { TKGDebugger.LogDebug("AndroidRewardADTKGAdCallback onClicked"); @@ -204,14 +213,17 @@ namespace Touka { TKGDebugger.LogDebug("AndroidRewardADTKGAdCallback onSkip"); } + public void onLoaded() { TKGDebugger.LogDebug("AndroidRewardADTKGAdCallback onLoaded"); } + public void onLoadFail(int code, string msg) { TKGDebugger.LogDebug("AndroidRewardADTKGAdCallback onLoadFail, code : " + code + " , msg : " + msg); } + public void onShow() { TKGDebugger.LogDebug("AndroidRewardADTKGAdCallback onShow"); @@ -268,32 +280,40 @@ namespace Touka /// public class AndroidBannerADTKGAdCallback : AndroidJavaProxy { - public AndroidBannerADTKGAdCallback() : base("com.touka.tkg.idal.ITKGAdCallback") { } + public AndroidBannerADTKGAdCallback() : base("com.touka.tkg.idal.ITKGAdCallback") + { + } public void onClosed() { TKGDebugger.LogDebug("onClosed"); } + public void onClicked() { TKGDebugger.LogDebug("onClicked"); } + public void onSkip() { TKGDebugger.LogDebug("onSkip"); } + public void onLoaded() { TKGDebugger.LogDebug("onLoaded"); } + public void onLoadFail(int code, string msg) { TKGDebugger.LogDebug("onLoadFail, code : " + code + " , msg : " + msg); } + public void onShow() { TKGDebugger.LogDebug("onShow"); } + public void onShowFail(int code, string msg) { TKGDebugger.LogDebug("onShowFail, code : " + code + " , msg : " + msg); @@ -305,16 +325,20 @@ namespace Touka /// public class AndroidTKGCommonCalllback : AndroidJavaProxy { - public AndroidTKGCommonCalllback() : base("com.touka.tkg.idal.TKGCalllback") { } + public AndroidTKGCommonCalllback() : base("com.touka.tkg.idal.TKGCalllback") + { + } public void onCall(int _code, string _msg) { TKGDebugger.LogDebug("TKGCallback onCall, code : " + _code + " , msg : " + _msg); - if(TKGSDKCallback.mTKGCommonCallback != null) + + Loom.QueueOnMainThread(pObj => { + if (TKGSDKCallback.mTKGCommonCallback == null) return; TKGSDKCallback.mTKGCommonCallback.Invoke((CommonCallbackCode)_code, _msg); TKGSDKCallback.mTKGCommonCallback = null; - } + }, ""); } } @@ -323,16 +347,21 @@ namespace Touka /// public class AndroidTKGUserSourceCalllback : AndroidJavaProxy { - public AndroidTKGUserSourceCalllback() : base("com.touka.tkg.idal.UserSourceCallback") { } + public AndroidTKGUserSourceCalllback() : base("com.touka.tkg.idal.UserSourceCallback") + { + } public void onResult(bool _isOrganic, string _userSource) { TKGDebugger.LogDebug("TKGCallback onCall, isOrganic : " + _isOrganic + " , userSource : " + _userSource); - if(TKGSDKCallback.mTKGUserSourceCallback != null) + Loom.QueueOnMainThread((pObj) => { - TKGSDKCallback.mTKGUserSourceCallback.Invoke(_isOrganic, _userSource); - TKGSDKCallback.mTKGUserSourceCallback = null; - } + if (TKGSDKCallback.mTKGUserSourceCallback != null) + { + TKGSDKCallback.mTKGUserSourceCallback.Invoke(_isOrganic, _userSource); + TKGSDKCallback.mTKGUserSourceCallback = null; + } + }, ""); } } @@ -342,15 +371,191 @@ namespace Touka /// public class AndroidTKGUserSourceCalllbackWithCampaignName : AndroidJavaProxy { - public AndroidTKGUserSourceCalllbackWithCampaignName() : base("com.touka.tkg.idal.UserSourceCallbackWithType") { } - - public void onResult(bool _isOrganic, string _userSource,string campaignName) + public AndroidTKGUserSourceCalllbackWithCampaignName() : base("com.touka.tkg.idal.UserSourceCallbackWithType") { - TKGDebugger.LogDebug("TKGCallback onCall, isOrganic : " + _isOrganic + " , userSource : " + _userSource + " , campaignName : " + campaignName); - if(TKGSDKCallback.mTKGUserSourceCallbackWithCampaignName != null) + } + + public void onResult(bool _isOrganic, string _userSource, string campaignName) + { + TKGDebugger.LogDebug("TKGCallback onCall, isOrganic : " + _isOrganic + " , userSource : " + _userSource + + " , campaignName : " + campaignName); + + Loom.QueueOnMainThread(_ => { - TKGSDKCallback.mTKGUserSourceCallbackWithCampaignName.Invoke(_isOrganic, _userSource,campaignName); + if (TKGSDKCallback.mTKGUserSourceCallbackWithCampaignName == null) return; + TKGSDKCallback.mTKGUserSourceCallbackWithCampaignName.Invoke(_isOrganic, _userSource, campaignName); TKGSDKCallback.mTKGUserSourceCallbackWithCampaignName = null; + }, ""); + } + } + + /// + /// FunctionSwitchCalllback + /// + public class AndroidFunctionSwitchCalllback : AndroidJavaProxy + { + public AndroidFunctionSwitchCalllback() : base("com.touka.tkg.idal.GameFunctionSwitchCallback") + { + } + + public void onFunctionSwitchResult(string _functionKey, bool _functionSwitch) + { + FunctionType enumType = (FunctionType)Enum.Parse(typeof(FunctionType), _functionKey); + + if (TKGSDKCallback.mFunctionSwitchCalllback != null) + { + Loom.QueueOnMainThread( + _ => { TKGSDKCallback.mFunctionSwitchCalllback?.Invoke(enumType, _functionSwitch); }, ""); + } + } + } + + /// + /// FunctionSwitchCalllback + /// + public class AndroidLoginCalllback : AndroidJavaProxy + { + private bool _isAutoLogin; + + public AndroidLoginCalllback(bool isAutoLogin = false) : base("com.touka.tkg.idal.ITKGLoginCallback") + { + _isAutoLogin = isAutoLogin; + } + + public void onLoginResult(int _code, string _msg, int _loginType, string _userId, string _token, string _email, + string _displayName, string _photoUrl) + { + TKGDebugger.LogDebug("AndroidLoginCalllback onLoginResult, code : " + _code + + " , msg : " + _msg + + " , _loginType : " + _loginType + + " , _userId : " + _userId + + " , _token : " + _token + + " , _email : " + _email + + " , _displayName : " + _displayName + + " , _photoUrl : " + _photoUrl + ); + TKGDebugger.LogDebug($"is auto login {_isAutoLogin}"); + LoginStatus loginStatusEnum = (LoginStatus)Enum.ToObject(typeof(LoginStatus), _code); + LoginType loginTypeEnum = (LoginType)Enum.ToObject(typeof(LoginType), _loginType); + Loom.QueueOnMainThread(pObj => + { + if (_isAutoLogin) + { + TKGSDKCallback.mAutoLoginCallback?.Invoke(loginStatusEnum, loginTypeEnum, _msg, _userId, _token, + _email, + _displayName, _photoUrl); + } + else + { + TKGSDKCallback.mLoginCallback?.Invoke(loginStatusEnum, loginTypeEnum, _msg, _userId, _token, _email, + _displayName, _photoUrl); + } + }, ""); + } + + + public void onLogout() + { + if (null != TKGSDKCallback.mLogoutCallback) + { + Loom.QueueOnMainThread(pObj => { TKGSDKCallback.mLogoutCallback?.Invoke(); }, ""); + } + } + + public void onDeleteAccount(int code, string userId) + { + if (null == TKGSDKCallback.mDeleteAccountCallback) return; + var codeType = (DeleteStatus)Enum.ToObject(typeof(DeleteStatus), code); + Loom.QueueOnMainThread(pObj => { TKGSDKCallback.mDeleteAccountCallback?.Invoke(codeType, userId); }, ""); + } + + + public void onBindAccount(int _code, string _msg, int _loginType, string _userId, string _token, string _email, + string _displayName, string _photoUrl, string userIds) + { + TKGDebugger.LogDebug("AndroidLoginCalllback onBindAccount, code : " + _code + + " , msg : " + _msg + + " , _loginType : " + _loginType + + " , _userId : " + _userId + + " , _token : " + _token + + " , _email : " + _email + + " , _displayName : " + _displayName + + " , _photoUrl : " + _photoUrl + + " , userIds : " + userIds + ); + if (null == TKGSDKCallback.mBindAccountCallback) return; + var bindAccountStatusEnum = (BindAccountStatus)Enum.ToObject(typeof(BindAccountStatus), _code); + var loginTypeEnum = (LoginType)Enum.ToObject(typeof(LoginType), _loginType); + var userIdList = userIds.Split(','); + Loom.QueueOnMainThread(pObj => + { + TKGSDKCallback.mBindAccountCallback?.Invoke(bindAccountStatusEnum, loginTypeEnum, _msg, _userId, _token, + _email, + _displayName, _photoUrl, userIdList); + }, ""); + } + } + + + /// + /// FunctionSwitchCalllback + /// + public class AdsRevenueCallback : AndroidJavaProxy + { + public AdsRevenueCallback() : base("com.touka.tkg.idal.IAdsRevenueCallback") + { + } + + public void revenueHandle(string _adsType, string _price, string _currnecy) + { + // FunctionType enumType = (AdsType)Enum.Parse(typeof(AdsType), _adsType); + + if (TKGSDKCallback.mAdsRevenueCallback != null) + { + AdsType adsType = AdsType.None; + switch (_adsType) + { + case "1": + adsType = AdsType.Splash; + break; + case "2": + adsType = AdsType.Banner; + break; + case "3": + adsType = AdsType.IV; + break; + case "4": + adsType = AdsType.RV; + break; + case "5": + adsType = AdsType.Native; + break; + } + + Loom.QueueOnMainThread( + _ => { TKGSDKCallback.mAdsRevenueCallback?.Invoke(adsType, _price, _currnecy); }, ""); + } + } + } + + + /// + /// FunctionSwitchCalllback + /// + public class SecondPurchaseCallback : AndroidJavaProxy + { + public SecondPurchaseCallback() : base("com.touka.tkg.idal.ISecondPurchaseCallback") + { + } + + public void onResult(string _orderID,string _poductName, string _productID, bool _result, string _gameExtraParam) + { + // FunctionType enumType = (AdsType)Enum.Parse(typeof(AdsType), _adsType); + + if (TKGSDKCallback.mSecondPurchaseCallback != null) + { + Loom.QueueOnMainThread( + _ => { TKGSDKCallback.mSecondPurchaseCallback?.Invoke(_orderID, _poductName, _productID, _result, _gameExtraParam); }, ""); } } } @@ -358,9 +563,7 @@ namespace Touka /* Loom.QueueOnMainThread((pObj) => { - + }, ""); */ - -} - +} \ No newline at end of file diff --git a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallbackIOS.cs b/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallbackIOS.cs deleted file mode 100644 index 21dabd81..00000000 --- a/Assets/TKGSDK/NativeSDK/Scripts/SDK/TKGSDKCallbackIOS.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using UnityEngine; - -namespace Touka -{ - public class TKGSDKCallbackIOS - { - - - } -} - diff --git a/Assets/TKGSDK/NativeSDK/Scripts/Utils/RequestHandler.cs b/Assets/TKGSDK/NativeSDK/Scripts/Utils/RequestHandler.cs new file mode 100644 index 00000000..5c663fad --- /dev/null +++ b/Assets/TKGSDK/NativeSDK/Scripts/Utils/RequestHandler.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; +using UnityEngine; + +namespace Touka +{ + public class RequestHandler : MonoBehaviour + { + private static RequestHandler _instance; + + public static RequestHandler Instance + { + get + { + if (_instance != null) return _instance; + _instance = FindObjectOfType(); + if (_instance != null) return _instance; + var obj = new GameObject(); + _instance = obj.AddComponent(); + return _instance; + } + } + + private void Awake() + { + if (_instance == null) + { + _instance = this; + } + else if (_instance != this) + { + Destroy(gameObject); + } + + DontDestroyOnLoad(gameObject); + } + + + public void SendGetRequest(string url, Dictionary headers = null, + Action callback = null + ) + { + StartCoroutine(GetRequestCoroutine(url, headers, callback)); + } + + public void SendPostRequest(string url, string jsonRequestBody, + Dictionary headers = null, Action callback = null) + { + StartCoroutine(PostRequestCoroutine(url, jsonRequestBody, headers, callback)); + } + + private static IEnumerator GetRequestCoroutine(string url, Dictionary headers, + Action callback) + { + try + { + var request = (HttpWebRequest)WebRequest.Create(url); + request.Method = "GET"; + + if (headers != null) + { + foreach (var header in headers) + { + request.Headers.Add(header.Key, header.Value); + } + } + + using (var response = (HttpWebResponse)request.GetResponse()) + { + var responseStream = response.GetResponseStream(); + if (responseStream == null) + { + throw new Exception("responseStream is null"); + } + + using (var reader = new StreamReader(responseStream)) + { + var jsonResponse = reader.ReadToEnd(); + Debug.Log(jsonResponse); + callback?.Invoke(0, jsonResponse); + } + } + } + catch (Exception e) + { + callback?.Invoke(-1, e.Message); + } + + + yield return null; + } + + private static IEnumerator PostRequestCoroutine(string url, string jsonRequestBody, + Dictionary headers, + Action callback) + { + try + { + var request = (HttpWebRequest)WebRequest.Create(url); + request.Method = "POST"; + request.ContentType = "application/json"; + + if (headers != null) + { + foreach (var header in headers) + { + request.Headers.Add(header.Key, header.Value); + } + } + + var byteArray = Encoding.UTF8.GetBytes(jsonRequestBody); + request.ContentLength = byteArray.Length; + + using (var requestStream = request.GetRequestStream()) + { + requestStream.Write(byteArray, 0, byteArray.Length); + } + + using (var response = (HttpWebResponse)request.GetResponse()) + { + var responseStream = response.GetResponseStream(); + if (responseStream == null) + { + throw new Exception("responseStream is null"); + } + + using (var reader = new StreamReader(responseStream)) + { + var jsonResponse = reader.ReadToEnd(); + callback?.Invoke(0, jsonResponse); + } + } + } + catch (Exception e) + { + callback?.Invoke(-1, e.Message); + } + + + yield return null; + } + } +} \ No newline at end of file diff --git a/Assets/TKGSDK/NativeSDK/Scripts/Utils/RequestHandler.cs.meta b/Assets/TKGSDK/NativeSDK/Scripts/Utils/RequestHandler.cs.meta new file mode 100644 index 00000000..8d0cc8ca --- /dev/null +++ b/Assets/TKGSDK/NativeSDK/Scripts/Utils/RequestHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b8ee56e924e14f78b5d238375ebb9b53 +timeCreated: 1690554307 \ No newline at end of file diff --git a/Assets/TKGSDK/NativeSDK/Scripts/Utils/Server.cs b/Assets/TKGSDK/NativeSDK/Scripts/Utils/Server.cs new file mode 100644 index 00000000..72b71154 --- /dev/null +++ b/Assets/TKGSDK/NativeSDK/Scripts/Utils/Server.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Text; +using UnityEngine; +using UnityEngine.Serialization; + +namespace Touka +{ + public class Server : NormalSingleton + { + // debug + private const string BASE_URL = "https://tk.dgtverse.cn/"; + + public void Login(LoginType loginType, Action callback) + { + var deviceId = PlayerPrefs.GetString("device_id", ""); + if (string.IsNullOrEmpty(deviceId)) + { + deviceId = SystemInfo.deviceUniqueIdentifier; + PlayerPrefs.SetString("device_id", deviceId); + } + + var thirdUserId = ""; + + if (loginType == LoginType.LOGIN_BY_GUESTER) + { + thirdUserId = deviceId.Replace("-", ""); + } + else if (loginType == LoginType.LOGIN_BY_GOOGLE) + { + thirdUserId = PlayerPrefs.GetString("google_user_id"); + } + else if (loginType == LoginType.LOGIN_BY_FACEBOOK) + { + thirdUserId = PlayerPrefs.GetString("facebook_user_id"); + } + + var body = new Dictionary() + { + ["user_type"] = (int)loginType, + ["third_uid"] = thirdUserId, + ["user_id"] = PlayerPrefs.GetString("user_id") + }; + Post("ztp/game/user/login", body, callback); + } + + + private static void Post(string url, Dictionary args, Action callback, + Dictionary headers = null) + { + if (args == null) + { + args = new Dictionary(); + } + + if (headers == null) + { + headers = new Dictionary(); + } + + AddBaseParameters(args); + EncryptionParameters(args); + var requestBody = ConvertDictionaryToJson(args); + Debug.Log("[server]" + url); + Debug.Log("[server]" + requestBody); + RequestHandler.Instance.SendPostRequest(BASE_URL + url, requestBody, headers, + (code, res) => + { + if (code == 0) + { + var resp = JsonUtility.FromJson>(res); + callback(resp.code == 0 ? 0 : resp.code, resp.msg, resp.data); + } + else + { + callback.Invoke(code, "", (T)new object()); + } + + Debug.Log("[server]" + "[res] " + res); + }); + } + + + private static void Get(string url, Action callback, + Dictionary headers = null) + { + if (headers == null) + { + headers = new Dictionary(); + } + + RequestHandler.Instance.SendGetRequest(BASE_URL + url, headers, + (code, res) => + { + if (code == 0) + { + var resp = JsonUtility.FromJson>(res); + callback(resp.code == 0 ? 0 : resp.code, resp.msg, resp.data); + } + else + { + callback.Invoke(code, "", (T)new object()); + } + + Debug.Log("[server]" + "[res] " + res); + }); + } + + private static string GetMD5Hash(string input) + { + using (var md5 = MD5.Create()) + { + var inputBytes = Encoding.ASCII.GetBytes(input); + var hashBytes = md5.ComputeHash(inputBytes); + + var builder = new StringBuilder(); + foreach (var t in hashBytes) + { + builder.Append(t.ToString("x2")); // Convert byte to hexadecimal string + } + + return builder.ToString(); + } + } + + private static void EncryptionParameters(Dictionary args) + { + const string secretKey = "tk~!@#$%^&*()_+0708"; + + var signString = + $"{secretKey}platform={args["platform"]}packagename={args["package_name"]}channel={args["channel"]}appversion={args["app_version"]}appversioncode={args["app_version_code"]}language={args["language"]}ip={args["ip"]}ts={args["ts"]}"; + var sign = GetMD5Hash(signString); + args["sign"] = sign; + } + + private static void AddBaseParameters(Dictionary args) + { + args.Add("platform", "Unity"); + args.Add("package_name", "Unity"); + args.Add("channel", "Unity"); + args.Add("app_version", "1.0.0"); + args.Add("app_version_code", "1"); + args.Add("language", "ZH"); + args.Add("ip", ""); + args.Add("device_id", PlayerPrefs.GetString("device_id")); + // var time = (int)Time.time; + var currentTime = DateTime.Now; + var timeSpan = currentTime - new DateTime(1970, 1, 1, 8, 0, 0, DateTimeKind.Utc); + var timestamp = (int)(timeSpan.TotalMilliseconds / 1000); + args.Add("ts", "" + timestamp); + } + + public static string ConvertDictionaryToJson(Dictionary dictionary) + { + StringBuilder jsonBuilder = new StringBuilder(); + jsonBuilder.Append("{"); + + int count = 0; + + foreach (KeyValuePair kvp in dictionary) + { + string key = kvp.Key; + object value = kvp.Value; + + jsonBuilder.AppendFormat("\"{0}\":", key); + + if (value is int || value is float || value is bool) + { + jsonBuilder.Append(value.ToString().ToLower()); + } + else if (value is string) + { + jsonBuilder.AppendFormat("\"{0}\"", value); + } + else + { + // Handle other types or nested dictionaries recursively + Dictionary nestedDictionary = value as Dictionary; + if (nestedDictionary != null) + { + string nestedJson = ConvertDictionaryToJson(nestedDictionary); + jsonBuilder.Append(nestedJson); + } + } + + count++; + if (count < dictionary.Count) + { + jsonBuilder.Append(","); + } + } + + jsonBuilder.Append("}"); + return jsonBuilder.ToString(); + } + + public void DeleteAccount(string userId, Action callback) + { + var args = new Dictionary { { "user_id", userId } }; + + Post("ztp/game/user/delete", args, + (code, msg, obj) => { callback.Invoke(code, code == 0 ? userId : msg); }); + } + + public void SaveCloudArchiving(string userId, string token, string content, Action callback) + { + var args = new Dictionary + { + { "user_id", userId }, + { "token", token }, + { "content", content } + }; + + var headers = new Dictionary { { "Authorization", "a5ca9093ac792ed386b641281eded3b1" } }; + + Post("ztp/third/game/user/progress/save", args, (code, msg, obj) => { callback.Invoke(code, msg); }, + headers); + } + + public void DetailCloudArchiving(string userId, string token, Action callback) + { + var headers = new Dictionary { { "Authorization", "a5ca9093ac792ed386b641281eded3b1" } }; + Get($"ztp/third/game/user/progress/detail?user_id={userId}&token={token}", + (code, msg, content) => { callback(code, msg, content.content); }, headers); + } + + public void Bind(LoginType loginType, BindType bindType, string thirdUid, string userId, + Action callback) + { + var args = new Dictionary + { + { "user_type", (int)loginType }, + { "third_uid", thirdUid }, + { "user_id", userId }, + { "is_force", (int)bindType }, + }; + Post("ztp/game/user/bind", args, callback); + } + } + + [System.Serializable] + public struct Response + { + public int code; + public string msg; + public T data; + } + + [System.Serializable] + public struct LoginInfo + { + public string user_id; + public string token; + public int user_type; + public int first_login; + } + + [System.Serializable] + public struct Bind + { + public string user_id; + public string token; + public string[] user_ids; + } + + [System.Serializable] + public struct Content + { + public string content; + } +} \ No newline at end of file diff --git a/Assets/TKGSDK/NativeSDK/Scripts/Utils/Server.cs.meta b/Assets/TKGSDK/NativeSDK/Scripts/Utils/Server.cs.meta new file mode 100644 index 00000000..e180399c --- /dev/null +++ b/Assets/TKGSDK/NativeSDK/Scripts/Utils/Server.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 814eb8c144e4424ea0e312f938df7fab +timeCreated: 1690559479 \ No newline at end of file diff --git a/Packages/manifest.json b/Packages/manifest.json index 61724bd5..27051762 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -1,7 +1,7 @@ { "dependencies": { "com.unity.2d.sprite": "1.0.0", - "com.unity.collab-proxy": "1.14.15", + "com.unity.collab-proxy": "2.0.5", "com.unity.ide.rider": "1.2.1", "com.unity.ide.visualstudio": "2.0.14", "com.unity.ide.vscode": "1.2.5", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index b52e0a6e..affccf1e 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -7,18 +7,18 @@ "dependencies": {} }, "com.unity.collab-proxy": { - "version": "1.14.15", + "version": "2.0.5", "depth": 0, "source": "registry", "dependencies": {}, - "url": "https://packages.unity.cn" + "url": "https://packages.unity.com" }, "com.unity.ext.nunit": { "version": "1.0.6", "depth": 1, "source": "registry", "dependencies": {}, - "url": "https://packages.unity.cn" + "url": "https://packages.unity.com" }, "com.unity.ide.rider": { "version": "1.2.1", @@ -27,7 +27,7 @@ "dependencies": { "com.unity.test-framework": "1.1.1" }, - "url": "https://packages.unity.cn" + "url": "https://packages.unity.com" }, "com.unity.ide.visualstudio": { "version": "2.0.14", @@ -36,14 +36,14 @@ "dependencies": { "com.unity.test-framework": "1.1.9" }, - "url": "https://packages.unity.cn" + "url": "https://packages.unity.com" }, "com.unity.ide.vscode": { "version": "1.2.5", "depth": 0, "source": "registry", "dependencies": {}, - "url": "https://packages.unity.cn" + "url": "https://packages.unity.com" }, "com.unity.purchasing": { "version": "4.1.3", @@ -57,7 +57,7 @@ "com.unity.modules.androidjni": "1.0.0", "com.unity.services.core": "1.0.1" }, - "url": "https://packages.unity.cn" + "url": "https://packages.unity.com" }, "com.unity.services.core": { "version": "1.0.1", @@ -66,7 +66,7 @@ "dependencies": { "com.unity.modules.unitywebrequest": "1.0.0" }, - "url": "https://packages.unity.cn" + "url": "https://packages.unity.com" }, "com.unity.test-framework": { "version": "1.1.31", @@ -77,7 +77,7 @@ "com.unity.modules.imgui": "1.0.0", "com.unity.modules.jsonserialize": "1.0.0" }, - "url": "https://packages.unity.cn" + "url": "https://packages.unity.com" }, "com.unity.textmeshpro": { "version": "2.1.6", @@ -86,7 +86,7 @@ "dependencies": { "com.unity.ugui": "1.0.0" }, - "url": "https://packages.unity.cn" + "url": "https://packages.unity.com" }, "com.unity.timeline": { "version": "1.2.18", @@ -98,7 +98,7 @@ "com.unity.modules.audio": "1.0.0", "com.unity.modules.particlesystem": "1.0.0" }, - "url": "https://packages.unity.cn" + "url": "https://packages.unity.com" }, "com.unity.ugui": { "version": "1.0.0", @@ -242,6 +242,18 @@ "depth": 0, "source": "builtin", "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.uielementsnative": "1.0.0" + } + }, + "com.unity.modules.uielementsnative": { + "version": "1.0.0", + "depth": 1, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", "com.unity.modules.imgui": "1.0.0", "com.unity.modules.jsonserialize": "1.0.0" } diff --git a/ProjectSettings/PackageManagerSettings.asset b/ProjectSettings/PackageManagerSettings.asset index d665bc9a..6457bee8 100644 --- a/ProjectSettings/PackageManagerSettings.asset +++ b/ProjectSettings/PackageManagerSettings.asset @@ -12,14 +12,19 @@ MonoBehaviour: m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: + m_EnablePreviewPackages: 0 + m_EnablePackageDependencies: 0 + m_AdvancedSettingsExpanded: 1 m_ScopedRegistriesSettingsExpanded: 1 oneTimeWarningShown: 0 m_Registries: - m_Id: main m_Name: - m_Url: https://packages.unity.cn + m_Url: https://packages.unity.com m_Scopes: [] m_IsDefault: 1 + m_Capabilities: 7 + m_ConfigSource: 0 m_UserSelectedRegistryName: m_UserAddingNewScopedRegistry: 0 m_RegistryInfoDraft: @@ -30,6 +35,8 @@ MonoBehaviour: m_Url: m_Scopes: [] m_IsDefault: 0 + m_Capabilities: 0 + m_ConfigSource: 0 m_Modified: 0 m_Name: m_Url: diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt index 625776a6..44822a76 100644 --- a/ProjectSettings/ProjectVersion.txt +++ b/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 2019.4.38f1c1 -m_EditorVersionWithRevision: 2019.4.38f1c1 (df80985e05f0) +m_EditorVersion: 2020.3.45f1 +m_EditorVersionWithRevision: 2020.3.45f1 (660cd1701bd5) diff --git a/ProjectSettings/UnityConnectSettings.asset b/ProjectSettings/UnityConnectSettings.asset index 2d5c92b2..4e0030db 100644 --- a/ProjectSettings/UnityConnectSettings.asset +++ b/ProjectSettings/UnityConnectSettings.asset @@ -9,8 +9,7 @@ UnityConnectSettings: m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events m_EventUrl: https://cdp.cloud.unity3d.com/v1/events m_ConfigUrl: https://config.uca.cloud.unity3d.com - m_CNEventUrl: https://cdp.cloud.unity.cn/v1/events - m_CNConfigUrl: https://cdp.cloud.unity.cn/config + m_DashboardUrl: https://dashboard.unity3d.com m_TestInitMode: 0 CrashReportingSettings: m_EventUrl: https://perf-events.cloud.unity.cn @@ -24,6 +23,7 @@ UnityConnectSettings: m_Enabled: 1 m_TestMode: 0 m_InitializeOnStartup: 1 + m_PackageRequiringCoreStatsPresent: 0 UnityAdsSettings: m_Enabled: 0 m_InitializeOnStartup: 1 diff --git a/ProjectSettings/VersionControlSettings.asset b/ProjectSettings/VersionControlSettings.asset new file mode 100644 index 00000000..dca28814 --- /dev/null +++ b/ProjectSettings/VersionControlSettings.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!890905787 &1 +VersionControlSettings: + m_ObjectHideFlags: 0 + m_Mode: Visible Meta Files + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/XcodeProject_Root_0912_1445.zip b/XcodeProject_Root_0912_1445.zip new file mode 100644 index 00000000..511c3baa Binary files /dev/null and b/XcodeProject_Root_0912_1445.zip differ