/// <summary> /// 有償石の商品リストの取得 /// </summary> public static void CallListApi(Action onCompleted) { #if SHARK_OFFLINE CoroutineUpdator.Create(null, () => { Masters.BillingDB.GetList().RemoveAll(x => x.platform != SharkDefine.DEVICE_TYPE); onCompleted?.Invoke(); }); return; #endif //リクエスト作成 var request = new SharkWebRequest <Dictionary <string, object> >("billing/list"); request.SetRequestHeader("AccessToken", UserData.Get().hash); //通信完了時コールバック登録 request.onSuccess = (response) => { //商品リスト更新 Masters.BillingDB.SetList(response[Masters.BillingDB.tableName].ToString()); Masters.BillingGroupDB.SetList(response[Masters.BillingGroupDB.tableName].ToString()); Masters.BillingItemDB.SetList(response[Masters.BillingItemDB.tableName].ToString()); //通信完了 onCompleted?.Invoke(); }; //通信開始 request.Send(); }
/// <summary> /// ショップ関連のデータ取得通信 /// </summary> public static void CallNowShopApi(Action <List <UserShopData> > onCompleted) { #if SHARK_OFFLINE CoroutineUpdator.Create(null, () => onCompleted?.Invoke(new List <UserShopData>())); return; #endif //リクエスト作成 var request = new SharkWebRequest <NowShopResponseData>("shop/nowShop"); request.SetRequestHeader("AccessToken", UserData.Get().hash); //通信完了時コールバック登録 request.onSuccess = (response) => { var jArray = new JArray(response.mShopItem.SelectMany(x => x).ToArray()); Masters.ShopDB.SetList(response.mShop.ToString()); Masters.ShopGroupDB.SetList(response.mShopGroup.ToString()); Masters.ShopItemDB.SetList(jArray.ToString()); //通信完了 onCompleted?.Invoke(response.tShop); }; //通信開始 request.Send(); }
/// <summary> /// 初期化 /// </summary> public void Initialize(string[] productIds, Action onInitialized, Action onInitializeFailed) { var module = StandardPurchasingModule.Instance(); var builder = ConfigurationBuilder.Instance(module); //商品の登録 builder.AddProducts(productIds.Select(x => new ProductDefinition(x, ProductType.Consumable))); //コールバック登録 this.onInitialized = onInitialized; this.onInitializeFailed = onInitializeFailed; #if UNITY_EDITOR || (!UNITY_ANDROID && !UNITY_IOS) //ダミー初期化 CoroutineUpdator.Create(null, this.onInitialized); #else //初期化 UnityPurchasing.Initialize(this, builder); #endif }
/// <summary> /// 送信 /// </summary> public void Send() { if (this.status == Status.Success) { //既にDL成功済みなので、1フレ後に完了処理を呼ぶ this.status = Status.Downloading; CoroutineUpdator.Create(null, () => { this.status = Status.Success; this.onCompleted?.Invoke(this); }); return; } this.status = Status.Downloading; TaskUpdator.Run(async() => { try { //タイムアウト設定 SharkHttpClient.instance.Timeout = TimeSpan.FromSeconds(60); //DL開始 this.bytes = await SharkHttpClient.instance.GetByteArrayAsync(GetURL(this.version, this.hash)); //DL完了 this.status = Status.Success; } catch (Exception e) { //エラー this.status = Status.Error; Debug.LogErrorFormat("FileDownloadHandle Error : name={0}, error={1}", this.name, e.Message); } if (Application.isPlaying) { //完了を通知 CoroutineUpdator.Create(null, () => this.onCompleted?.Invoke(this)); } }); }
/// <summary> /// ロード実行 /// </summary> public void Load(Action onLoaded = null) { this.onLoaded = onLoaded; if (this.Count == 0) { CoroutineUpdator.Create(null, this.onLoaded); return; } for (int i = 0, imax = this.Count; i < imax; i++) { if (i < imax - 1) { this[i].Load(); } else { this[i].Load(this.onLoaded); } } }
/// <summary> /// 購入 /// </summary> public void Purchase(string productId, Action <string> onProcessPurchase, Action <PurchaseFailureReason> onPurchaseFailed) { this.onProcessPurchase = onProcessPurchase; this.onPurchaseFailed = onPurchaseFailed; if (this.pendingProducts.Count > 0) { this.onPurchaseFailed?.Invoke(PurchaseFailureReason.ExistingPurchasePending); return; } if (this.controller != null) { var product = this.controller.products.WithID(productId); if (product != null) { this.controller.InitiatePurchase(product); return; } } CoroutineUpdator.Create(null, () => this.onPurchaseFailed?.Invoke(PurchaseFailureReason.Unknown)); }
/// <summary> /// 有償石の購入 /// </summary> public static void CallBuyApi( string productId, string receipt, Action <UserBillingData> onCompleted, Action <BillingBuyErrorType, int> onError) { #if DEBUG if (receipt == "dummy") { CoroutineUpdator.Create(null, () => { var billingData = Masters.BillingDB.GetList().Find(x => x.productId == productId); var billingItems = Masters.BillingItemDB.GetList().FindAll(x => x.billingItemId == billingData.billingItemId); UserData.Get().chargeGem += (ulong)billingItems.Where(x => x.itemType == (uint)ItemType.ChargeGem).Sum(x => x.itemNum); UserData.Get().freeGem += (ulong)billingItems.Where(x => x.itemType == (uint)ItemType.FreeGem).Sum(x => x.itemNum); UserData.Get().coin += (ulong)billingItems.Where(x => x.itemType == (uint)ItemType.Coin).Sum(x => x.itemNum); onCompleted?.Invoke(new UserBillingData { billingId = billingData.id }); }); return; } #endif //リクエスト作成 var request = new SharkWebRequest <BuyResponseData>("billing/buy"); request.SetRequestHeader("AccessToken", UserData.Get().hash); //リクエストパラメータセット request.SetRequestParameter(new Dictionary <string, object> { { "productId", productId }, { "receipt", receipt }, { "platform", SharkDefine.DEVICE_TYPE }, }); //通信完了時コールバック登録 request.onSuccess = (response) => { //サーバーでアイテム付与成功 if (response.tBilling.status == (uint)UserBillingData.Status.AddItem) { //クライアントもアイテム付与 foreach (var item in response.mBillingItem) { UserData.Get().AddItem((ItemType)item.itemType, item.itemId, item.itemNum); } // tUsers更新 if (response.tUsers != null) { UserData.Get().Set(response.tUsers); } //通信完了 onCompleted?.Invoke(response.tBilling); } //何らかのエラー else { BillingBuyErrorType errorType = BillingBuyErrorType.None; int errorCode = 0; if (response.tBilling.status == (uint)UserBillingData.Status.ReceiptChkFailed) { //レシート検証に失敗:念のためペンディングは解除しない errorType = BillingBuyErrorType.BillingStatusType; errorCode = (int)UserBillingData.Status.ReceiptChkFailed; } #if UNITY_EDITOR || UNITY_ANDROID else if (response.result.purchaseState == (int)GoogleBuyResult.PurchaseState.Canceled) { //キャンセル済み:ペンディング解除OK errorType = BillingBuyErrorType.GooglePurchaseState; errorCode = (int)GoogleBuyResult.PurchaseState.Canceled; } else if (response.result.purchaseState == (int)GoogleBuyResult.PurchaseState.Pending) { //ペンディング中:ペンディング解除NG errorType = BillingBuyErrorType.GooglePurchaseState; errorCode = (int)GoogleBuyResult.PurchaseState.Pending; } #endif //エラー通知 onError?.Invoke(errorType, errorCode); } }; //エラーコールバック登録 request.onError = (errodCode) => { onError?.Invoke(BillingBuyErrorType.ErrorCodeType, errodCode); }; //通信開始 request.Send(); }
/// <summary> /// ロード /// </summary> public static AssetLoadHandle Load <T>(string path, Action <T> onLoaded = null) where T : UnityEngine.Object { //既に読み込みがかかっているか検索 AssetLoadHandle handle = FindHandle <T>(path); //ハンドルが既存だった場合 if (handle != null) { //参照カウンタ増加 handle.referenceCount++; //コールバックを積む callbacks.Add(new Tuple <AssetLoadHandle, Action>(handle, () => { if (onLoaded != null) { onLoaded((T)handle.asset); } })); //ハンドルがロード済みなら積まれているコールバックを順に消化 if (!handle.keepWaiting) { CoroutineUpdator.Create(null, InvokeCallback);//1フレ後に処理したい } } //ハンドルが存在しなかったら else { bool isSubAsset = false; var info = FindAssetBundleInfo(path, out isSubAsset); //AssetBundleの場合 if (info != null) { //ハンドル作成 → ロード完了したら積まれているコールバックを順に消化 handle = new AssetBundleLoadHandle(path, info, isSubAsset, typeof(T), InvokeCallback, OnError); } //Resourcesの場合 else { //ハンドル作成 → ロード完了したら積まれているコールバックを順に消化 handle = new ResourcesLoadHandle(path, typeof(T), InvokeCallback, OnError); } //参照カウンタ増加 handle.referenceCount++; handles.Add(handle); //コールバックを積む callbacks.Add(new Tuple <AssetLoadHandle, Action>(handle, () => { if (onLoaded != null) { onLoaded((T)handle.asset); } })); //ロード開始 LoadStartIfCan(); } return(handle); }