説明なし
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

UDPBindings.cs 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.Linq;
  6. using UnityEngine.Purchasing.Extension;
  7. using UnityEngine.Purchasing.MiniJSON;
  8. namespace UnityEngine.Purchasing
  9. {
  10. internal class UDPBindings : INativeUDPStore
  11. {
  12. private readonly object m_Bridge;
  13. private Action<bool, string> m_RetrieveProductsCallbackCache;
  14. public UDPBindings()
  15. {
  16. var udpIapBridge = UdpIapBridgeInterface.GetClassType();
  17. if (udpIapBridge != null)
  18. {
  19. m_Bridge = Activator.CreateInstance(udpIapBridge);
  20. }
  21. else
  22. {
  23. Debug.LogError("Failed to access UDP. Please make sure your UDP package is installed and up-to-date");
  24. throw new NotImplementedException();
  25. }
  26. }
  27. public void Initialize(Action<bool, string> callback)
  28. {
  29. if (m_Bridge != null)
  30. {
  31. var initMethod = UdpIapBridgeInterface.GetInitMethod();
  32. initMethod.Invoke(m_Bridge, new object[] { callback });
  33. }
  34. else
  35. {
  36. Debug.LogError("Cannot Initialize UDP store module. Please make sure your UDP package is installed and up-to-date");
  37. throw new NotImplementedException();
  38. }
  39. }
  40. public void Purchase(string productId, Action<bool, string> callback, string developerPayload = null)
  41. {
  42. if (m_Bridge != null)
  43. {
  44. var purchaseMethod = UdpIapBridgeInterface.GetPurchaseMethod();
  45. purchaseMethod.Invoke(m_Bridge, new object[] { productId, callback, developerPayload });
  46. }
  47. else
  48. {
  49. Debug.LogError("Cannot Purchase via UDP. Please make sure your UDP package is installed and up-to-date");
  50. throw new NotImplementedException();
  51. }
  52. }
  53. public void RetrieveProducts(ReadOnlyCollection<ProductDefinition> products, Action<bool, string> callback)
  54. {
  55. if (m_Bridge != null)
  56. {
  57. if (m_RetrieveProductsCallbackCache != null)
  58. {
  59. callback(false, /*lang=json,strict*/ "{ \"error\" : \"already retrieving products\" }");
  60. return;
  61. }
  62. m_RetrieveProductsCallbackCache = callback;
  63. Action<bool, object> retrieveCallback = OnInventoryQueried;
  64. var retrieveProductsMethod = UdpIapBridgeInterface.GetRetrieveProductsMethod();
  65. var ids = new List<String>();
  66. foreach (var product in products)
  67. {
  68. ids.Add(product.storeSpecificId);
  69. }
  70. retrieveProductsMethod.Invoke(m_Bridge, new object[] { new ReadOnlyCollection<string>(ids), retrieveCallback });
  71. }
  72. else
  73. {
  74. Debug.LogError("Cannot Retrieve Products from UDP. Please make sure your UDP package is installed and up-to-date");
  75. throw new NotImplementedException();
  76. }
  77. }
  78. public void FinishTransaction(ProductDefinition productDefinition, string transactionID)
  79. {
  80. if (m_Bridge != null)
  81. {
  82. var finishTransactionMethod = UdpIapBridgeInterface.GetFinishTransactionMethod();
  83. finishTransactionMethod.Invoke(m_Bridge, new object[] { transactionID });
  84. }
  85. else
  86. {
  87. Debug.LogError("Cannot Complete transaction for UDP. Please make sure your UDP package is installed and up-to-date");
  88. throw new NotImplementedException();
  89. }
  90. }
  91. private void OnInventoryQueried(bool success, object payload)
  92. {
  93. var actualSuccess = success;
  94. string parsedPayload;
  95. var inventoryType = InventoryInterface.GetClassType();
  96. if (success)
  97. {
  98. if (inventoryType != null)
  99. {
  100. var inventory = payload;
  101. if (inventory != null && inventory.GetType() == inventoryType)
  102. {
  103. var fetchedProducts = new HashSet<ProductDescription>();
  104. var getProductList = InventoryInterface.GetProductListMethod();
  105. var products = (IEnumerable)getProductList.Invoke(inventory, null);
  106. var productList = products.Cast<object>().ToList();
  107. foreach (var productInfo in productList)
  108. {
  109. var priceProp = ProductInfoInterface.GetPriceProp();
  110. var titleProp = ProductInfoInterface.GetTitleProp();
  111. var descProp = ProductInfoInterface.GetDescriptionProp();
  112. var currencyProp = ProductInfoInterface.GetCurrencyProp();
  113. var microsProp = ProductInfoInterface.GetPriceAmountMicrosProp();
  114. var metadata = new ProductMetadata(
  115. (string)priceProp.GetValue(productInfo, null),
  116. (string)titleProp.GetValue(productInfo, null),
  117. (string)descProp.GetValue(productInfo, null),
  118. (string)currencyProp.GetValue(productInfo, null),
  119. Convert.ToDecimal((long)microsProp.GetValue(productInfo, null)) / 1000000);
  120. var idProp = ProductInfoInterface.GetProductIdProp();
  121. var productId = (string)idProp.GetValue(productInfo, null);
  122. var desc = new ProductDescription(productId, metadata);
  123. var hasPurchase = InventoryInterface.HasPurchaseMethod();
  124. if ((bool)hasPurchase.Invoke(inventory, new object[] { productId }))
  125. {
  126. var getPurchaseInfo = InventoryInterface.GetPurchaseInfoMethod();
  127. var purchase = getPurchaseInfo.Invoke(inventory, new object[] { productId });
  128. var dic = StringPropertyToDictionary(purchase);
  129. var transactionId = dic["GameOrderId"];
  130. var storeSpecificId = dic["ProductId"];
  131. if (!string.IsNullOrEmpty(transactionId))
  132. {
  133. dic["transactionId"] = transactionId;
  134. }
  135. if (!string.IsNullOrEmpty(storeSpecificId))
  136. {
  137. dic["storeSpecificId"] = storeSpecificId;
  138. }
  139. desc = new ProductDescription(productId, metadata, dic.toJson(), transactionId);
  140. }
  141. fetchedProducts.Add(desc);
  142. }
  143. parsedPayload = JSONSerializer.SerializeProductDescs(fetchedProducts);
  144. }
  145. else
  146. {
  147. actualSuccess = false;
  148. parsedPayload = /*lang=json,strict*/ "{ \"error\" : \"Cannot load inventory from UDP. Please make sure your UDP package is installed and up-to-date\" }";
  149. }
  150. }
  151. else
  152. {
  153. actualSuccess = false;
  154. parsedPayload = /*lang=json,strict*/ "{ \"error\" : \"Cannot parse inventory type for UDP. Please make sure your UDP package is installed and up-to-date\" }";
  155. }
  156. }
  157. else
  158. {
  159. parsedPayload = (string)payload;
  160. }
  161. m_RetrieveProductsCallbackCache(actualSuccess, parsedPayload);
  162. m_RetrieveProductsCallbackCache = null;
  163. }
  164. #region INativeStore - Unused
  165. public void RetrieveProducts(string json)
  166. {
  167. throw new NotImplementedException();
  168. }
  169. public void Purchase(string productJSON, string developerPayload)
  170. {
  171. throw new NotImplementedException();
  172. }
  173. public void FinishTransaction(string productJSON, string transactionID)
  174. {
  175. throw new NotImplementedException();
  176. }
  177. #endregion
  178. #region helper functions
  179. /// <summary>
  180. /// Put the string property of <see cref="info"/> into a dictionary if the property is not empty string.
  181. /// </summary>
  182. /// <param name="info">Model object, namely <see cref="PurchaseInfo"/> or <see cref="UserInfo"/></param>
  183. /// <returns></returns>
  184. internal static Dictionary<string, string> StringPropertyToDictionary(object info)
  185. {
  186. var dictionary = new Dictionary<string, string>();
  187. if (info == null)
  188. {
  189. return dictionary;
  190. }
  191. var properties = info.GetType().GetProperties();
  192. foreach (var property in properties)
  193. {
  194. if (property.PropertyType == typeof(string))
  195. {
  196. var value = (string)property.GetValue(info, null);
  197. if (!string.IsNullOrEmpty(value))
  198. {
  199. dictionary[property.Name] = value;
  200. }
  201. }
  202. }
  203. return dictionary;
  204. }
  205. #endregion
  206. }
  207. }