using System; using System.Collections.Generic; using System.Diagnostics; using SUISS.Core; using SUISS.Storage; using UnityEngine; namespace CIG { public sealed class IAPValidationManager { public IAPValidationManager(CIGWebService webService) { this._webService = webService; this._webService.PullRequestCompleted += this.OnWebServicesPullRequestCompleted; this.DeserializePurchases(this._unverifiedPurchases, "UnverifiedPurchases"); this.DeserializePurchases(this._untrackedPurchases, "UntrackedPurchases"); } //[DebuggerBrowsable(DebuggerBrowsableState.Never)] public event Action purchaseVerifiedEvent; public void AddPurchase(string productID, string transactionID, string receipt) { IAPValidationManager.ValidationPurchase item = new IAPValidationManager.ValidationPurchase(productID, transactionID, receipt, this._webService.GeneratePurchaseReceiptParameters()); this._unverifiedPurchases.Add(item); this._untrackedPurchases.Add(item); this.SerializePurchases(this._unverifiedPurchases, "UnverifiedPurchases"); this.SerializePurchases(this._untrackedPurchases, "UntrackedPurchases"); this.ValidatePurchases(); } public void ValidatePurchases() { if (this._unverifiedPurchases.Count > 0) { IAPValidationManager.ValidationPurchase purchase = this._unverifiedPurchases[0]; UnityEngine.Debug.LogFormat("Verifying purchase {0}", new object[] { purchase.ProductID }); if (this._webService != null) { this._webService.WWWWithTimeout(this._webService.ValidatePurchase(purchase.ProductID, purchase.Receipt, purchase.MetaData), delegate(CIGWebService.WWWResponse result) { if (!result.TimedOut) { if (string.IsNullOrEmpty(result.Error) && !string.IsNullOrEmpty(result.Text)) { string value = result.Text.Trim(); if ("OK".Equals(value) || "ERROR".Equals(value)) { UnityEngine.Debug.Log("Purchase verified " + purchase.ProductID); this._unverifiedPurchases.Remove(purchase); this.SerializePurchases(this._unverifiedPurchases, "UnverifiedPurchases"); bool flag = "OK".Equals(value); if (flag) { SingletonMonobehaviour.Instance.Properties["is_paying_user"] = true.ToString(); } if (this.purchaseVerifiedEvent != null) { this.purchaseVerifiedEvent(purchase.ProductID, purchase.TransactionID, flag); } this.ValidatePurchases(); } else { UnityEngine.Debug.LogError("Verify purchase request unknown result: " + result.Text); } } else { UnityEngine.Debug.LogError("Verify purchase request error: " + result.Text); } } else { UnityEngine.Debug.LogError("Verify purchase request error, request timedout."); } }, 5f); } else { UnityEngine.Debug.LogError("IAPValidationManagere._webService is null!"); } } } private void OnWebServicesPullRequestCompleted() { Dictionary properties = SingletonMonobehaviour.Instance.Properties; if (properties.ContainsKey("verified_iaps")) { bool flag = false; List list = new List(properties["verified_iaps"].Split(new char[] { ',' })); int count = this._untrackedPurchases.Count; for (int i = count - 1; i >= 0; i--) { IAPValidationManager.ValidationPurchase validationPurchase = this._untrackedPurchases[i]; string transactionID = validationPurchase.TransactionID; if (list.Contains(transactionID)) { string productID = validationPurchase.ProductID; CIG3StoreProduct cig3StoreProduct = SingletonMonobehaviour.Instance.Store.FindProduct(productID); if (cig3StoreProduct != null) { } else { UnityEngine.Debug.LogErrorFormat("[Adjust Analytics] Product with productId={0} not found, verification not sent to Adjust.", new object[] { productID }); } this._untrackedPurchases.RemoveAt(i); flag = true; } } if (flag) { this.SerializePurchases(this._untrackedPurchases, "UntrackedPurchases"); } } } private void SerializePurchases(List purchases, string serializationKey) { List list = new List(); for (int i = 0; i < purchases.Count; i++) { list.Add(purchases[i].Serialize()); } if (!this.storage.ContainsKey(serializationKey)) { this.storage.Add(serializationKey, null); } this.storage[serializationKey] = list; Storage.SaveLifecycle(StorageLifecycle.Purchases, false); } private void DeserializePurchases(List purchases, string serializationKey) { purchases.Clear(); if (this.storage.ContainsKey(serializationKey)) { List list = (List)this.storage[serializationKey]; int count = list.Count; for (int i = 0; i < count; i++) { purchases.Add(new IAPValidationManager.ValidationPurchase((Dictionary)list[i])); } } } private Dictionary storage { get { return Storage.Get(StorageLifecycle.Purchases).GetDictionary("IAPValidationStorage"); } } private const string UNVERIFIED_PURCHASES_KEY = "UnverifiedPurchases"; private const string UntrackedPurchasesKey = "UntrackedPurchases"; private const StorageLifecycle VALIDATION_LIFECYCLE = StorageLifecycle.Purchases; private const string IsPayingUserServerKey = "is_paying_user"; private const string VerifiedIAPsKey = "verified_iaps"; private CIGWebService _webService; private List _unverifiedPurchases = new List(); private List _untrackedPurchases = new List(); private class ValidationPurchase { public ValidationPurchase(string productID, string transactionID, string receipt, Dictionary metaData) { this.TransactionID = transactionID; this.ProductID = productID; this.Receipt = receipt; this.MetaData = metaData; } public ValidationPurchase(Dictionary storageDictionary) { string empty = string.Empty; this.Receipt = empty; this.TransactionID = empty; if (storageDictionary.ContainsKey("TransactionID")) { this.TransactionID = (string)storageDictionary["TransactionID"]; } if (storageDictionary.ContainsKey("ProductID")) { this.ProductID = (string)storageDictionary["ProductID"]; } if (storageDictionary.ContainsKey("Receipt")) { this.Receipt = (string)storageDictionary["Receipt"]; } if (storageDictionary.ContainsKey("MetaData")) { this.MetaData = this.LoadDictionary(storageDictionary, "MetaData"); } else { this.MetaData = new Dictionary(); } } public override string ToString() { return string.Concat(new string[] { "[PurchaseEntry: TransactionID=", this.TransactionID, ", productID=", this.ProductID, "]" }); } public string TransactionID { get; private set; } public string ProductID { get; private set; } public string Receipt { get; private set; } public Dictionary MetaData { get; private set; } private void SaveDictionary(Dictionary storage, string key, Dictionary values) { Dictionary dictionary = new Dictionary(); foreach (KeyValuePair keyValuePair in values) { dictionary.Add(keyValuePair.Key, keyValuePair.Value); } storage[key] = dictionary; } private Dictionary LoadDictionary(Dictionary storage, string key) { if (!storage.ContainsKey(key)) { return new Dictionary(); } if (!(storage[key] is Dictionary)) { throw new InvalidOperationException(string.Format("Found {0} at storage[{1}]. Expecting {2}", storage[key].GetType().Name, key, typeof(Dictionary).Name)); } Dictionary dictionary = new Dictionary(); Dictionary dictionary2 = (Dictionary)storage[key]; foreach (KeyValuePair keyValuePair in dictionary2) { if (!(dictionary2[keyValuePair.Key] is TField)) { throw new InvalidOperationException(string.Format("Found {0} at storage[{1}]. Expecting {2}", storage[key].GetType().Name, key, typeof(TField).Name)); } dictionary.Add(keyValuePair.Key, (TField)((object)dictionary2[keyValuePair.Key])); } return dictionary; } public Dictionary Serialize() { Dictionary dictionary = new Dictionary(); dictionary["TransactionID"] = this.TransactionID; dictionary["ProductID"] = this.ProductID; dictionary["Receipt"] = this.Receipt; this.SaveDictionary(dictionary, "MetaData", this.MetaData); return dictionary; } private const string ProductIDKey = "ProductID"; private const string TransactionIDKey = "TransactionID"; private const string ReceiptKey = "Receipt"; private const string MetaDataKey = "MetaData"; } } }