lib_unity_purchase/Runtime/Stores/WindowsStore/WinRTStore.cs

193 lines
6.8 KiB
C#
Raw Normal View History

2024-01-29 18:49:33 +08:00
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Uniject;
using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.Purchasing.Default;
using UnityEngine.Purchasing.Extension;
namespace UnityEngine.Purchasing
{
/// <summary>
/// Handles Windows 8.1.
/// </summary>
internal class WinRTStore : AbstractStore, IWindowsIAPCallback, IMicrosoftExtensions
{
private IWindowsIAP win8;
private IStoreCallback callback;
private readonly IUtil util;
private readonly ILogger logger;
private bool m_CanReceivePurchases = false;
public WinRTStore(IWindowsIAP win8, IUtil util, ILogger logger)
{
this.win8 = win8;
this.util = util;
this.logger = logger;
}
/// <summary>
/// Allow the windows IAP service to be swapped
/// out since the Application developer can switch
/// between sandbox/live after this store is
/// constructed.
/// </summary>
public void SetWindowsIAP(IWindowsIAP iap)
{
win8 = iap;
}
public override void Initialize(IStoreCallback biller)
{
callback = biller;
}
public override void RetrieveProducts(ReadOnlyCollection<ProductDefinition> productDefs)
{
var dummyProducts = from def in productDefs
where def.type != ProductType.Subscription
select new WinProductDescription(
def.storeSpecificId, "$0.01",
"Fake title - " + def.storeSpecificId,
"Fake description - " + def.storeSpecificId,
"USD", 0.01m, null, null, def.type == ProductType.Consumable);
win8.BuildDummyProducts(dummyProducts.ToList());
init(0);
}
public override void FinishTransaction(ProductDefinition product, string transactionId)
{
win8.FinaliseTransaction(transactionId);
}
private void init(int delay)
{
win8.Initialize(this);
win8.RetrieveProducts(true);
}
public override void Purchase(ProductDefinition product, string developerPayload)
{
win8.Purchase(product.storeSpecificId);
}
// An Action<bool> invoked on pause/resume.
public void restoreTransactions(bool pausing)
{
if (!pausing)
{
if (m_CanReceivePurchases)
{
win8.RetrieveProducts(false);
}
}
}
public void RestoreTransactions()
{
win8.RetrieveProducts(false);
// setting this here assumes that the Retrieve actually worked, but in the
// case where it didn't we still want to persist that the user has tried to restore
// to see if the automatic attempts (on app FG) resolve things
m_CanReceivePurchases = true;
}
public void logError(string error)
{
// Uncomment to get diagnostics printed on screen.
logger.LogError("Unity Purchasing", error);
}
public void OnProductListReceived(WinProductDescription[] winProducts)
{
util.RunOnMainThread(() =>
{
// Convert windows products to Unity Purchasing products.
var products = from product in winProducts
let metadata = new ProductMetadata(
product.price, product.title, product.description,
product.ISOCurrencyCode, product.priceDecimal)
select new ProductDescription(
product.platformSpecificID,
metadata,
product.receipt,
product.transactionID);
// need to determine if that list includes any purchases or just products
// and then use that to set m_CanReceivePurchases
callback.OnProductsRetrieved(products.ToList());
});
}
public void log(string message)
{
util.RunOnMainThread(() =>
{
logger.Log(message);
});
}
public void OnPurchaseFailed(string productId, string error)
{
util.RunOnMainThread(() =>
{
logger.LogFormat(LogType.Error, "Purchase failed: {0}, {1}", productId, error);
if ("AlreadyPurchased" == error)
{
try
{
callback.OnPurchaseFailed(new PurchaseFailureDescription(productId,
(PurchaseFailureReason)Enum.Parse(typeof(PurchaseFailureReason), "DuplicateTransaction"), error));
}
catch
{
callback.OnPurchaseFailed(new PurchaseFailureDescription(productId,
(PurchaseFailureReason)Enum.Parse(typeof(PurchaseFailureReason), "Unknown"), error));
}
}
else if ("NotPurchased" == error)
{
callback.OnPurchaseFailed(new PurchaseFailureDescription(productId,
(PurchaseFailureReason)Enum.Parse(typeof(PurchaseFailureReason), "UserCancelled"), error));
}
else
{
callback.OnPurchaseFailed(new PurchaseFailureDescription(productId,
(PurchaseFailureReason)Enum.Parse(typeof(PurchaseFailureReason), "Unknown"), error));
}
});
}
public void OnPurchaseSucceeded(string productId, string receipt, string tranId)
{
util.RunOnMainThread(() =>
{
m_CanReceivePurchases = true;
callback.OnPurchaseSucceeded(productId, receipt, tranId);
});
}
// When using an incorrect product id:
// "Exception from HRESULT: 0x805A0194"
public void OnProductListError(string message)
{
util.RunOnMainThread(() =>
{
if (message.Contains("801900CC"))
{
callback.OnSetupFailed(InitializationFailureReason.AppNotKnown, null);
}
else
{
logError("Unable to retrieve product listings. UnityIAP will automatically retry...");
logError(message);
init(3000);
}
});
}
}
}