|
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using SUISS.Storage;
- using UnityEngine;
- using UnityEngine.Purchasing;
-
- namespace CIG
- {
- public class IAPCatalog<T> where T : StoreProduct
- {
- public IAPCatalog(CIGWebService webService, Func<Dictionary<string, object>, T> storeProductFactory)
- {
- this._webService = webService;
- this._storeProductFactory = storeProductFactory;
- this.LoadFromStorage();
- this.LoadDefaultPricePoints();
- }
-
- private static string DEFAULT_PRICEPOINTS_ASSET_NAME
- {
- get
- {
- return "defaultpricepoints-android";
- }
- }
-
- public IEnumerator UpdatePricePoints()
- {
- if (this.AreCachedPricePointsOutDated() && this._webService != null)
- {
- yield return this._webService.WWWWithTimeout(this._webService.PricePoints(), delegate (CIGWebService.WWWResponse response)
- {
- if (!response.TimedOut)
- {
- if (string.IsNullOrEmpty(response.Error) && !string.IsNullOrEmpty(response.Text))
- {
- List<Dictionary<string, object>> productMetadata;
- int num;
- if (this.ValidatePricePoints(response.Text, out productMetadata, out num))
- {
- this.UpdateRemoteProducts(productMetadata);
- }
- else
- {
- UnityEngine.Debug.LogError("Invalid pricepoints received. - Not using them.");
- }
- }
- else
- {
- UnityEngine.Debug.LogErrorFormat("Error downloading pricepoints. {0}", new object[]
- {
- response.Text
- });
- }
- }
- else
- {
- UnityEngine.Debug.LogErrorFormat("Error downloading pricepoints: Timedout", new object[0]);
- }
- }, 5f);
- }
- yield break;
- }
-
- public void UpdateProducts(Product[] products)
- {
- int num = products.Length;
- for (int i = 0; i < num; i++)
- {
- Product product = products[i];
- T t = this.FindProduct(product.definition.id);
- if (t != null)
- {
- Dictionary<string, object> dictionary = t.Serialize();
- dictionary["ProductTitle"] = product.metadata.localizedTitle;
- dictionary["ProductDescription"] = product.metadata.localizedDescription;
- dictionary["ProductCurrencyCode"] = product.metadata.isoCurrencyCode;
- dictionary["ProductFormattedPrice"] = "99";
- dictionary["ProductPrice"] = product.metadata.localizedPrice;
- this.AddOrUpdateProduct(dictionary);
- }
- }
- this.SaveToStorage();
- }
-
- public T FindProduct(string identifier)
- {
- return this._products.Find((T x) => x.Identifier == identifier);
- }
-
- public T FindProduct(Predicate<T> predicate)
- {
- T[] availableProducts = this.GetAvailableProducts(predicate);
- return (availableProducts.Length <= 0) ? ((T)((object)null)) : availableProducts[0];
- }
-
- public T[] GetAvailableProducts(Predicate<T> predicate)
- {
- List<T> list = new List<T>();
- int count = this._products.Count;
- for (int i = 0; i < count; i++)
- {
- T t = this._products[i];
- if (t.Available && predicate(t))
- {
- list.Add(t);
- }
- }
- list.Sort();
- return list.ToArray();
- }
-
- public T[] AvailableProducts
- {
- get
- {
- return this._products.FindAll((T x) => x.Available).ToArray();
- }
- }
-
- private T AddOrUpdateProduct(Dictionary<string, object> productMetadata)
- {
- T t = this.FindProduct((string)productMetadata["ProductIdentifier"]);
- if (t != null)
- {
- t.Update(productMetadata);
- }
- else
- {
- t = this._storeProductFactory(productMetadata);
- this._products.Add(t);
- }
- return t;
- }
-
- private void LoadDefaultPricePoints()
- {
- int num = -1;
- object obj;
- if (this.storage.TryGetValue("DefaultPricePointsVersionKey", out obj) && obj is int)
- {
- num = (int)obj;
- }
- TextAsset textAsset = Resources.Load<TextAsset>(IAPCatalog<T>.DEFAULT_PRICEPOINTS_ASSET_NAME);
- if (textAsset == null)
- {
- UnityEngine.Debug.LogErrorFormat("Unable to open TextAsset {0}.", new object[]
- {
- IAPCatalog<T>.DEFAULT_PRICEPOINTS_ASSET_NAME
- });
- return;
- }
- List<Dictionary<string, object>> productMetadata;
- int num2;
- if (!this.ValidatePricePoints(textAsset.text, out productMetadata, out num2))
- {
- UnityEngine.Debug.LogWarningFormat("Invalid default pricepoints. - Not using them.", new object[0]);
- return;
- }
- if (num != -1 && num2 <= num)
- {
- return;
- }
- this.UpdateProducts(productMetadata);
- if (!this.storage.ContainsKey("DefaultPricePointsVersionKey"))
- {
- this.storage.Add("DefaultPricePointsVersionKey", -1);
- }
- this.storage["DefaultPricePointsVersionKey"] = num2;
- this.SaveToStorage();
- }
-
- private void UpdateRemoteProducts(List<Dictionary<string, object>> productMetadata)
- {
- this.UpdateProducts(productMetadata);
- if (!this.storage.ContainsKey("GameVersionKey"))
- {
- this.storage.Add("GameVersionKey", string.Empty);
- }
- if (!this.storage.ContainsKey("CacheDateTimeKey"))
- {
- this.storage.Add("CacheDateTimeKey", 0L);
- }
- this.storage["GameVersionKey"] = "3.0.6";
- this.storage["CacheDateTimeKey"] = DateTime.UtcNow.ToBinary();
- this.SaveToStorage();
- }
-
- private void UpdateProducts(List<Dictionary<string, object>> productMetadata)
- {
- int count = this._products.Count;
- for (int i = 0; i < count; i++)
- {
- T t = this._products[i];
- t.Available = false;
- }
- count = productMetadata.Count;
- for (int j = 0; j < count; j++)
- {
- this.AddOrUpdateProduct(productMetadata[j]);
- }
- }
-
- private bool AreCachedPricePointsOutDated()
- {
- object obj;
- if (!this.storage.TryGetValue("GameVersionKey", out obj))
- {
- return true;
- }
- if (string.IsNullOrEmpty(obj as string))
- {
- return true;
- }
- if ((string)obj != "3.0.6")
- {
- return true;
- }
- if (!this.storage.TryGetValue("CacheDateTimeKey", out obj))
- {
- return true;
- }
- if (!(obj is long))
- {
- return true;
- }
- DateTime d = DateTime.FromBinary((long)obj);
- return DateTime.UtcNow - d > IAPCatalog<T>.PRICEPOINTS_EXPIRATIONTIME;
- }
-
- private bool ValidatePricePoints(string pricepointsRawText, out List<Dictionary<string, object>> productMetadata, out int version)
- {
- productMetadata = IAPCatalog<T>.ParsePricePoints(pricepointsRawText, out version);
- if (productMetadata.Count == 0)
- {
- return false;
- }
- Dictionary<string, object> dictionary = productMetadata[0];
- return dictionary.ContainsKey("ProductIdentifier") && dictionary.ContainsKey("ProductPrice") && dictionary.ContainsKey("CustomProperties");
- }
-
- private static List<Dictionary<string, object>> ParsePricePoints(string pricePoints, out int version)
- {
- version = -1;
- List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
- if (string.IsNullOrEmpty(pricePoints))
- {
- return list;
- }
- Dictionary<string, string> dictionary = new Dictionary<string, string>();
- foreach (string text in pricePoints.Split(new char[]
- {
- '\n'
- }))
- {
- int num = text.IndexOf('=');
- if (num >= 0)
- {
- string text2 = text.Substring(0, num).Trim();
- string value = text.Substring(num + 1).Trim();
- if (dictionary.ContainsKey(text2))
- {
- UnityEngine.Debug.LogWarningFormat("Result dictionary already contains key '{0}'", new object[]
- {
- text2
- });
- }
- dictionary[text2] = value;
- }
- }
- string objA = null;
- foreach (KeyValuePair<string, string> keyValuePair in dictionary)
- {
- if (keyValuePair.Key == "version")
- {
- if (!int.TryParse(keyValuePair.Value, out version))
- {
- UnityEngine.Debug.LogWarningFormat("Failed to parse pricepoints version '{0}' to int.", new object[]
- {
- keyValuePair.Value
- });
- }
- }
- else
- {
- int num2 = keyValuePair.Key.LastIndexOf('.');
- if (num2 >= 0)
- {
- string text3 = keyValuePair.Key.Substring(0, num2);
- string text4 = keyValuePair.Key.Substring(num2 + 1, keyValuePair.Key.Length - num2 - 1);
- Dictionary<string, object> dictionary2;
- Dictionary<string, string> dictionary3;
- if (!object.Equals(objA, text3))
- {
- dictionary2 = new Dictionary<string, object>();
- dictionary3 = new Dictionary<string, string>();
- dictionary2.Add("CustomProperties", dictionary3);
- list.Add(dictionary2);
- objA = text3;
- }
- else
- {
- dictionary2 = list[list.Count - 1];
- dictionary3 = (Dictionary<string, string>)dictionary2["CustomProperties"];
- }
- if (text4.Equals("name"))
- {
- dictionary2["ProductIdentifier"] = keyValuePair.Value;
- }
- else if (text4.Equals("dollar"))
- {
- decimal num3;
- if (decimal.TryParse(keyValuePair.Value, out num3))
- {
- dictionary2["ProductPrice"] = num3;
- dictionary2["ProductDollarPrice"] = num3;
- dictionary2["ProductFormattedPrice"] = num3.ToString("0.00") + "元";//TODODO 价格在defaultpricepoints-android这个文件里
- dictionary2["ProductCurrencyCode"] = "USD";
- }
- }
- else if (text4.Equals("euro"))
- {
- decimal num4;
- if (decimal.TryParse(keyValuePair.Value, out num4))
- {
- dictionary2["ProductPrice"] = num4;
- dictionary2["ProductEuroPrice"] = num4;
- dictionary2["ProductFormattedPrice"] = num4.ToString("0.00") + "元";//TODODO 价格在defaultpricepoints-android这个文件里
- dictionary2["ProductCurrencyCode"] = "EUR";
- }
- }
- else if (text4.Equals("description"))
- {
- dictionary2["ProductDescription"] = keyValuePair.Value;
- }
- else if (text4.Equals("available"))
- {
- bool flag;
- if (bool.TryParse(keyValuePair.Value, out flag))
- {
- dictionary2["Available"] = flag;
- }
- }
- else
- {
- dictionary3.Add(text4, keyValuePair.Value);
- }
- }
- }
- }
- return list;
- }
-
- private void SaveToStorage()
- {
- List<object> list = new List<object>();
- for (int i = 0; i < this._products.Count; i++)
- {
- List<object> list2 = list;
- T t = this._products[i];
- list2.Add(t.Serialize());
- }
- if (!this.storage.ContainsKey("StoreProductsKey"))
- {
- this.storage.Add("StoreProductsKey", list);
- }
- else
- {
- this.storage["StoreProductsKey"] = list;
- }
- Storage.SaveLifecycle(StorageLifecycle.Purchases, false);
- }
-
- private void LoadFromStorage()
- {
- if (this.storage.ContainsKey("StoreProductsKey"))
- {
- List<object> list = (List<object>)this.storage["StoreProductsKey"];
- for (int i = 0; i < list.Count; i++)
- {
- this.AddOrUpdateProduct((Dictionary<string, object>)list[i]);
- }
- }
- }
-
- private Dictionary<string, object> storage
- {
- get
- {
- return Storage.Get(StorageLifecycle.Purchases).GetDictionary("IAPCatalogStorage");
- }
- }
-
- private const string STORE_PRODUCTS_KEY = "StoreProductsKey";
-
- private const string GAME_VERSION_KEY = "GameVersionKey";
-
- private const string CACHE_DATETIME_KEY = "CacheDateTimeKey";
-
- private const string DEFAULT_PRICEPOINTS_VERSION_KEY = "DefaultPricePointsVersionKey";
-
- private const StorageLifecycle IAPCATALOG_LIFECYCLE = StorageLifecycle.Purchases;
-
- private const string IAPCATALOG_KEY = "IAPCatalogStorage";
-
- private static readonly TimeSpan PRICEPOINTS_EXPIRATIONTIME = new TimeSpan(1, 0, 0, 0);
-
- private const string PRICE_POINTS_VERSION_KEY = "version";
-
- private Func<Dictionary<string, object>, T> _storeProductFactory;
-
- private CIGWebService _webService;
-
- private List<T> _products = new List<T>();
- }
- }
|