|
|
|
using System.Collections;
|
|
|
|
using UnityEngine;
|
|
|
|
using TMPro;
|
|
|
|
using System;
|
|
|
|
using UnityEngine.Purchasing;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using static UnityEngine.Networking.UnityWebRequest;
|
|
|
|
using UnityEngine.Purchasing.Extension;
|
|
|
|
using UnityEngine.UI;
|
|
|
|
//using UnityEngine.WSA;
|
|
|
|
using DG.Tweening;
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
public class ConsumableItem
|
|
|
|
{
|
|
|
|
public string Name;
|
|
|
|
public string Id;
|
|
|
|
public string desc;
|
|
|
|
public float price;
|
|
|
|
}
|
|
|
|
[Serializable]
|
|
|
|
public class NonConsumableItem
|
|
|
|
{
|
|
|
|
public string Name;
|
|
|
|
public string Id;
|
|
|
|
public string desc;
|
|
|
|
public float price;
|
|
|
|
}
|
|
|
|
[Serializable]
|
|
|
|
public class SubscriptionItem
|
|
|
|
{
|
|
|
|
public string Name;
|
|
|
|
public string Id;
|
|
|
|
public string desc;
|
|
|
|
public float price;
|
|
|
|
public int timeDuration;// in Days
|
|
|
|
}
|
|
|
|
|
|
|
|
public class ShopManager : MonoBehaviour, IDetailedStoreListener
|
|
|
|
{
|
|
|
|
IStoreController m_StoreContoller;
|
|
|
|
|
|
|
|
public List<ConsumableItem> cItem;
|
|
|
|
public List<ConsumableItem> pItem;
|
|
|
|
public List<int> coinsRewards;
|
|
|
|
//public NonConsumableItem ncItem;
|
|
|
|
//public SubscriptionItem sItem;
|
|
|
|
|
|
|
|
public TMP_InputField inp;
|
|
|
|
|
|
|
|
|
|
|
|
public Data data;
|
|
|
|
public Payload payload;
|
|
|
|
public PayloadData payloadData;
|
|
|
|
|
|
|
|
public List<ButtonState> PipeButtons;
|
|
|
|
//public List<Button> PurchaseButtons;
|
|
|
|
[Serializable]
|
|
|
|
public class ButtonState
|
|
|
|
{
|
|
|
|
public bool isPurchased;
|
|
|
|
public bool isEquipped;
|
|
|
|
public Button PurchaseButton;
|
|
|
|
public Button EquipButton;
|
|
|
|
public TextMeshProUGUI equipButtonText;
|
|
|
|
}
|
|
|
|
private void Start()
|
|
|
|
{
|
|
|
|
int coins = PlayerPrefs.GetInt("Coin");
|
|
|
|
coinTxt.text = coins.ToString();
|
|
|
|
SetupBuilder();
|
|
|
|
PipePrefGetter();
|
|
|
|
}
|
|
|
|
void PipePrefGetter()
|
|
|
|
{
|
|
|
|
if (!PlayerPrefs.HasKey("PipeButtonIsEquipped" + 0))
|
|
|
|
{
|
|
|
|
PlayerPrefs.SetInt("PipeButtonIsEquipped" + 0, 1);
|
|
|
|
PlayerPrefs.SetInt("PipeButtonIsPurchased" + 0, 1);
|
|
|
|
}
|
|
|
|
for (int i = 0; i < PipeButtons.Count; i++)
|
|
|
|
{
|
|
|
|
PipeButtons[i].isEquipped = PlayerPrefs.GetInt("PipeButtonIsEquipped" + i) == 1 ? true : false;
|
|
|
|
PipeButtons[i].isPurchased = PlayerPrefs.GetInt("PipeButtonIsPurchased" + i) == 1 ? true : false;
|
|
|
|
|
|
|
|
if (PipeButtons[i].isPurchased == false)
|
|
|
|
{
|
|
|
|
PipeButtons[i].PurchaseButton.gameObject.SetActive(true);
|
|
|
|
PipeButtons[i].EquipButton.gameObject.SetActive(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PipeButtons[i].EquipButton.gameObject.SetActive(true);
|
|
|
|
PipeButtons[i].PurchaseButton.gameObject.SetActive(false);
|
|
|
|
if (PipeButtons[i].isEquipped == true)
|
|
|
|
{
|
|
|
|
PipeButtons[i].equipButtonText.text = "Equipped";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PipeButtons[i].equipButtonText.text = "Equip";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#region setup and initialize
|
|
|
|
void SetupBuilder()
|
|
|
|
{
|
|
|
|
|
|
|
|
var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
|
|
|
|
|
|
|
|
for (int i = 0; i < cItem.Count; i++)
|
|
|
|
{
|
|
|
|
|
|
|
|
builder.AddProduct(cItem[i].Id, ProductType.Consumable);
|
|
|
|
}
|
|
|
|
for (int i = 1; i < pItem.Count; i++)//Starting from 1 because 1 set of pipe is already bought by default.
|
|
|
|
{
|
|
|
|
builder.AddProduct(pItem[i].Id, ProductType.NonConsumable);
|
|
|
|
}
|
|
|
|
//builder.AddProduct(ncItem.Id, ProductType.NonConsumable);
|
|
|
|
//builder.AddProduct(sItem.Id, ProductType.Subscription);
|
|
|
|
|
|
|
|
UnityPurchasing.Initialize(this, builder);
|
|
|
|
}
|
|
|
|
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
|
|
|
|
{
|
|
|
|
print("Success");
|
|
|
|
m_StoreContoller = controller;
|
|
|
|
//CheckNonConsumable(ncItem.Id);
|
|
|
|
//CheckSubscription(sItem.Id);
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region button clicks
|
|
|
|
public void Consumable_Btn_Pressed(int index)
|
|
|
|
{
|
|
|
|
//AddCoins(50);
|
|
|
|
currentPurchaseType = PurchaseType.Coins;
|
|
|
|
m_StoreContoller.InitiatePurchase(cItem[index].Id);
|
|
|
|
}
|
|
|
|
public void Consumable_Btn_Pressed_Pipes(int index)
|
|
|
|
{
|
|
|
|
//AddCoins(50);
|
|
|
|
currentPurchaseType = PurchaseType.Pipes;
|
|
|
|
Debug.Log("Purchasing pipes1... : " + pItem[index].Id);
|
|
|
|
m_StoreContoller.InitiatePurchase(pItem[index].Id);
|
|
|
|
|
|
|
|
//Debug.Log("Purchasing pipes2... : "+ pItem[index].Id);
|
|
|
|
}
|
|
|
|
|
|
|
|
//public void NonConsumable_Btn_Pressed()
|
|
|
|
//{
|
|
|
|
// //RemoveAds();
|
|
|
|
// m_StoreContoller.InitiatePurchase(ncItem.Id);
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
//public void Subscription_Btn_Pressed()
|
|
|
|
//{
|
|
|
|
// //ActivateElitePass();
|
|
|
|
// m_StoreContoller.InitiatePurchase(sItem.Id);
|
|
|
|
//}
|
|
|
|
#endregion
|
|
|
|
public PurchaseType currentPurchaseType;
|
|
|
|
public enum PurchaseType
|
|
|
|
{
|
|
|
|
Coins, Pipes,
|
|
|
|
}
|
|
|
|
#region main
|
|
|
|
//processing purchase
|
|
|
|
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs purchaseEvent)
|
|
|
|
{
|
|
|
|
//Retrive the purchased product
|
|
|
|
Debug.Log("Process Purchase");
|
|
|
|
var product = purchaseEvent.purchasedProduct;
|
|
|
|
|
|
|
|
print("Purchase Complete" + product.definition.id + " Purchase Type: " + currentPurchaseType.ToString());
|
|
|
|
if (currentPurchaseType == PurchaseType.Coins)
|
|
|
|
{
|
|
|
|
for (int h = 0; h < cItem.Count; h++)
|
|
|
|
{
|
|
|
|
if (product.definition.id == cItem[h].Id)//consumable item is pressed
|
|
|
|
{
|
|
|
|
//string receipt = product.receipt;
|
|
|
|
//data = JsonUtility.FromJson<Data>(receipt);
|
|
|
|
//payload = JsonUtility.FromJson<Payload>(data.Payload);
|
|
|
|
//payloadData = JsonUtility.FromJson<PayloadData>(payload.json);
|
|
|
|
|
|
|
|
//int quantity = payloadData.quantity;
|
|
|
|
|
|
|
|
//for (int i = 0; i < quantity; i++)
|
|
|
|
//{
|
|
|
|
AddCoins(h);
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (currentPurchaseType == PurchaseType.Pipes)
|
|
|
|
{
|
|
|
|
for (int h = 0; h < pItem.Count; h++)
|
|
|
|
{
|
|
|
|
Debug.Log("product.definition.id : " + product.definition.id);
|
|
|
|
Debug.Log("pItem[h].Id : " + pItem[h].Id);
|
|
|
|
if (product.definition.id == pItem[h].Id)//consumable item is pressed
|
|
|
|
{
|
|
|
|
//string receipt = product.receipt;
|
|
|
|
//data = JsonUtility.FromJson<Data>(receipt);
|
|
|
|
//payload = JsonUtility.FromJson<Payload>(data.Payload);
|
|
|
|
//payloadData = JsonUtility.FromJson<PayloadData>(payload.json);
|
|
|
|
|
|
|
|
//int quantity = payloadData.quantity;
|
|
|
|
|
|
|
|
//for (int i = 0; i < quantity; i++)
|
|
|
|
//{
|
|
|
|
AddPipes(h);
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//else if (product.definition.id == ncItem.Id)//non consumable
|
|
|
|
//{
|
|
|
|
// RemoveAds();
|
|
|
|
//}
|
|
|
|
//else if (product.definition.id == sItem.Id)//subscribed
|
|
|
|
//{
|
|
|
|
// ActivateElitePass();
|
|
|
|
//}
|
|
|
|
|
|
|
|
return PurchaseProcessingResult.Complete;
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CheckNonConsumable(string id)
|
|
|
|
{
|
|
|
|
if (m_StoreContoller != null)
|
|
|
|
{
|
|
|
|
var product = m_StoreContoller.products.WithID(id);
|
|
|
|
if (product != null)
|
|
|
|
{
|
|
|
|
if (product.hasReceipt)//purchased
|
|
|
|
{
|
|
|
|
RemoveAds();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ShowAds();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CheckSubscription(string id)
|
|
|
|
{
|
|
|
|
|
|
|
|
var subProduct = m_StoreContoller.products.WithID(id);
|
|
|
|
if (subProduct != null)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (subProduct.hasReceipt)
|
|
|
|
{
|
|
|
|
var subManager = new SubscriptionManager(subProduct, null);
|
|
|
|
var info = subManager.getSubscriptionInfo();
|
|
|
|
/*print(info.getCancelDate());
|
|
|
|
print(info.getExpireDate());
|
|
|
|
print(info.getFreeTrialPeriod());
|
|
|
|
print(info.getIntroductoryPrice());
|
|
|
|
print(info.getProductId());
|
|
|
|
print(info.getPurchaseDate());
|
|
|
|
print(info.getRemainingTime());
|
|
|
|
print(info.getSkuDetails());
|
|
|
|
print(info.getSubscriptionPeriod());
|
|
|
|
print(info.isAutoRenewing());
|
|
|
|
print(info.isCancelled());
|
|
|
|
print(info.isExpired());
|
|
|
|
print(info.isFreeTrial());
|
|
|
|
print(info.isSubscribed());*/
|
|
|
|
|
|
|
|
|
|
|
|
if (info.isSubscribed() == UnityEngine.Purchasing.Result.True)
|
|
|
|
{
|
|
|
|
print("We are subscribed");
|
|
|
|
ActivateElitePass();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
print("Un subscribed");
|
|
|
|
DeActivateElitePass();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
print("receipt not found !!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception)
|
|
|
|
{
|
|
|
|
|
|
|
|
print("It only work for Google store, app store, amazon store, you are using fake store!!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
print("product not found !!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region error handeling
|
|
|
|
public void OnInitializeFailed(InitializationFailureReason error)
|
|
|
|
{
|
|
|
|
print("failed" + error);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void OnInitializeFailed(InitializationFailureReason error, string message)
|
|
|
|
{
|
|
|
|
print("initialize failed" + error + message);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
|
|
|
|
{
|
|
|
|
print("purchase failed" + failureReason);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void OnPurchaseFailed(Product product, PurchaseFailureDescription failureDescription)
|
|
|
|
{
|
|
|
|
print("purchase failed" + failureDescription);
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region extra
|
|
|
|
|
|
|
|
[Header("Consumable")]
|
|
|
|
public Text coinTxt;
|
|
|
|
void AddCoins(int index)
|
|
|
|
{
|
|
|
|
int toAdd = coinsRewards[index];
|
|
|
|
int coins = PlayerPrefs.GetInt("Coin");
|
|
|
|
Debug.Log(toAdd + " Coins purchased");
|
|
|
|
coins += toAdd;
|
|
|
|
PlayerPrefs.SetInt("Coin", coins);
|
|
|
|
StartCoroutine(startCoinShakeEffect(coins - toAdd, coins, .5f));
|
|
|
|
|
|
|
|
}
|
|
|
|
public void EquipUnEquipPipe(int buttonIndex)
|
|
|
|
{
|
|
|
|
if (PipeButtons[buttonIndex].isEquipped)
|
|
|
|
{
|
|
|
|
PlayerPrefs.SetInt("PipeButtonIsEquipped" + buttonIndex, 0);
|
|
|
|
PlayerPrefs.SetInt("PipeButtonIsEquipped" + 0, 1);
|
|
|
|
PipeIndexSetter(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
|
|
|
|
for (int i = 0; i < PipeButtons.Count; i++)
|
|
|
|
{
|
|
|
|
if (i != buttonIndex)
|
|
|
|
{
|
|
|
|
PipeButtons[i].isEquipped = false;
|
|
|
|
PlayerPrefs.SetInt("PipeButtonIsEquipped" + i, 0);
|
|
|
|
PipeButtons[i].equipButtonText.text = "Equip";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PipeButtons[i].isEquipped = true;
|
|
|
|
PlayerPrefs.SetInt("PipeButtonIsEquipped" + i, 1);
|
|
|
|
PipeButtons[i].equipButtonText.text = "Equipped";
|
|
|
|
PipeIndexSetter(buttonIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
public void PipeIndexSetter(int index)
|
|
|
|
{
|
|
|
|
GameManager.PipeIndex = index;
|
|
|
|
}
|
|
|
|
void AddPipes(int index)
|
|
|
|
{
|
|
|
|
PlayerPrefs.SetInt("PipeButtonIsPurchased" + index, 1);
|
|
|
|
PipeButtons[index].isPurchased = true;
|
|
|
|
PipeButtons[index].EquipButton.gameObject.SetActive(true);
|
|
|
|
PipeButtons[index].PurchaseButton.gameObject.SetActive(false);
|
|
|
|
Debug.Log("Pipe " + index + " purchased");
|
|
|
|
}
|
|
|
|
float val;
|
|
|
|
IEnumerator startCoinShakeEffect(int oldValue, int newValue, float animTime)
|
|
|
|
{
|
|
|
|
float ct = 0;
|
|
|
|
float nt;
|
|
|
|
float tot = animTime;
|
|
|
|
coinTxt.transform.DOShakePosition(0.5f);
|
|
|
|
// coinTxt.GetComponent<Animation>().Play("textShake");
|
|
|
|
while (ct < tot)
|
|
|
|
{
|
|
|
|
ct += Time.deltaTime;
|
|
|
|
nt = ct / tot;
|
|
|
|
val = Mathf.Lerp(oldValue, newValue, nt);
|
|
|
|
coinTxt.text = ((int)(val)).ToString();
|
|
|
|
yield return null;
|
|
|
|
}
|
|
|
|
//coinTxt.GetComponent<Animation>().Stop();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[Header("Non Consumable")]
|
|
|
|
public GameObject AdsPurchasedWindow;
|
|
|
|
public GameObject adsBanner;
|
|
|
|
void RemoveAds()
|
|
|
|
{
|
|
|
|
DisplayAds(false);
|
|
|
|
}
|
|
|
|
void ShowAds()
|
|
|
|
{
|
|
|
|
DisplayAds(true);
|
|
|
|
|
|
|
|
}
|
|
|
|
void DisplayAds(bool x)
|
|
|
|
{
|
|
|
|
if (!x)
|
|
|
|
{
|
|
|
|
AdsPurchasedWindow.SetActive(true);
|
|
|
|
adsBanner.SetActive(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AdsPurchasedWindow.SetActive(false);
|
|
|
|
adsBanner.SetActive(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[Header("Subscription")]
|
|
|
|
public GameObject subActivatedWindow;
|
|
|
|
public GameObject premiumBanner;
|
|
|
|
|
|
|
|
void ActivateElitePass()
|
|
|
|
{
|
|
|
|
setupElitePass(true);
|
|
|
|
}
|
|
|
|
void DeActivateElitePass()
|
|
|
|
{
|
|
|
|
setupElitePass(false);
|
|
|
|
}
|
|
|
|
void setupElitePass(bool x)
|
|
|
|
{
|
|
|
|
if (x)// active
|
|
|
|
{
|
|
|
|
subActivatedWindow.SetActive(true);
|
|
|
|
premiumBanner.SetActive(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
subActivatedWindow.SetActive(false);
|
|
|
|
premiumBanner.SetActive(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
public class SkuDetails
|
|
|
|
{
|
|
|
|
public string productId;
|
|
|
|
public string type;
|
|
|
|
public string title;
|
|
|
|
public string name;
|
|
|
|
public string iconUrl;
|
|
|
|
public string description;
|
|
|
|
public string price;
|
|
|
|
public long price_amount_micros;
|
|
|
|
public string price_currency_code;
|
|
|
|
public string skuDetailsToken;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
public class PayloadData
|
|
|
|
{
|
|
|
|
public string orderId;
|
|
|
|
public string packageName;
|
|
|
|
public string productId;
|
|
|
|
public long purchaseTime;
|
|
|
|
public int purchaseState;
|
|
|
|
public string purchaseToken;
|
|
|
|
public int quantity;
|
|
|
|
public bool acknowledged;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
public class Payload
|
|
|
|
{
|
|
|
|
public string json;
|
|
|
|
public string signature;
|
|
|
|
public List<SkuDetails> skuDetails;
|
|
|
|
public PayloadData payloadData;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
public class Data
|
|
|
|
{
|
|
|
|
public string Payload;
|
|
|
|
public string Store;
|
|
|
|
public string TransactionID;
|
|
|
|
}
|