using System; using System.Collections.Generic; #if IAP_ANALYTICS_SERVICE_ENABLED || IAP_ANALYTICS_SERVICE_ENABLED_WITH_SERVICE_COMPONENT using Unity.Services.Analytics; using Unity.Services.Core; #endif using UnityEngine.Purchasing.Extension; namespace UnityEngine.Purchasing { /// /// The core abstract implementation for Unity Purchasing. /// public abstract class UnityPurchasing { /// /// The main initialization call for Unity Purchasing. /// /// The IStoreListener to receive callbacks for future transactions /// The ConfigurationBuilder containing the product definitions mapped to stores [Obsolete("Use Initialize(IDetailedStoreListener, ConfigurationBuilder)", false)] public static void Initialize(IStoreListener listener, ConfigurationBuilder builder) { var logger = Debug.unityLogger; var unityServicesInitializationChecker = new UnityServicesInitializationChecker(logger); var legacyAnalyticsWrapper = new LegacyAnalyticsWrapper(GenerateLegacyUnityAnalytics(), new EmptyAnalyticsAdapter()); Initialize(listener, builder, logger, Application.persistentDataPath, GenerateUnityAnalytics(logger), legacyAnalyticsWrapper, builder.factory.GetCatalogProvider(), unityServicesInitializationChecker); } /// /// The main initialization call for Unity Purchasing. /// /// The IDetailedStoreListener to receive callbacks for future transactions /// The ConfigurationBuilder containing the product definitions mapped to stores public static void Initialize(IDetailedStoreListener listener, ConfigurationBuilder builder) { var logger = Debug.unityLogger; var unityServicesInitializationChecker = new UnityServicesInitializationChecker(logger); var legacyAnalyticsWrapper = new LegacyAnalyticsWrapper(GenerateLegacyUnityAnalytics(), new EmptyAnalyticsAdapter()); Initialize(listener, builder, logger, Application.persistentDataPath, GenerateUnityAnalytics(logger), legacyAnalyticsWrapper, builder.factory.GetCatalogProvider(), unityServicesInitializationChecker); } private static IAnalyticsAdapter GenerateUnityAnalytics(ILogger logger) { #if DISABLE_RUNTIME_IAP_ANALYTICS || (!IAP_ANALYTICS_SERVICE_ENABLED && !IAP_ANALYTICS_SERVICE_ENABLED_WITH_SERVICE_COMPONENT) return new EmptyAnalyticsAdapter(); #else try { #if IAP_ANALYTICS_SERVICE_ENABLED return new AnalyticsAdapter(AnalyticsService.Instance, logger); #elif IAP_ANALYTICS_SERVICE_ENABLED_WITH_SERVICE_COMPONENT return new CoreAnalyticsAdapter(AnalyticsService.Instance, logger); #endif } catch (ServicesInitializationException) { return new EmptyAnalyticsAdapter(); } #endif } static IAnalyticsAdapter GenerateLegacyUnityAnalytics() { #if DISABLE_RUNTIME_IAP_ANALYTICS || !ENABLE_CLOUD_SERVICES_ANALYTICS || !IAP_ANALYTICS_SERVICE_ENABLED return new EmptyAnalyticsAdapter(); #else return new LegacyAnalyticsAdapter(new LegacyUnityAnalytics()); #endif } /// /// This is useful in certain test scenarios, such as repeatedly testing /// an App's behaviour when purchases are restored. /// /// This is a static method since developers may wish to clear the log before /// initialising IAP. /// public static void ClearTransactionLog() { var log = new TransactionLog(Debug.unityLogger, Application.persistentDataPath); log.Clear(); } /// /// Created for integration testing. /// internal static void Initialize(IStoreListener listener, ConfigurationBuilder builder, ILogger logger, string persistentDatapath, IAnalyticsAdapter ugsAnalytics, IAnalyticsAdapter legacyAnalytics, ICatalogProvider catalog, IUnityServicesInitializationChecker unityServicesInitializationChecker) { unityServicesInitializationChecker.CheckAndLogWarning(); var transactionLog = new TransactionLog(logger, persistentDatapath); var manager = new PurchasingManager(transactionLog, logger, builder.factory.service, builder.factory.storeName, unityServicesInitializationChecker); var analyticsClient = new AnalyticsClient(ugsAnalytics, legacyAnalytics); // Proxy the PurchasingManager's callback interface to forward Transactions to Analytics. var proxy = new StoreListenerProxy(listener, analyticsClient, builder.factory); FetchAndMergeProducts(builder.useCatalogProvider, builder.products, catalog, response => { manager.Initialize(proxy, response); }); } internal static void FetchAndMergeProducts(bool useCatalog, HashSet localProductSet, ICatalogProvider catalog, Action> callback) { if (useCatalog && catalog != null) { catalog.FetchProducts(cloudProducts => { var updatedProductSet = new HashSet(localProductSet); foreach (var product in cloudProducts) { // Products are hashed by id, so this should remove the local product with the same id before adding the cloud product updatedProductSet.Remove(product); updatedProductSet.Add(product); } callback(updatedProductSet); }); } else { callback(localProductSet); } } } }