123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746 |
- #if UNITY_EDITOR
- using System;
- using System.IO;
- using System.Net;
- using System.Collections.Generic;
- #elif UNITY_ANDROID
- using System;
- using System.Collections.Generic;
- using UnityEngine.Advertisements.Purchasing;
- #elif UNITY_IOS
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using AOT;
- using UnityEngine.Advertisements.Purchasing;
- #endif
- using UnityEngine.Advertisements;
- using UnityEngine.Advertisements.Utilities;
- namespace UnityEngine.Monetization
- {
- #if UNITY_EDITOR
- sealed internal class Platform : IMonetizationPlatform
- {
- public static Placeholder m_Placeholder;
- bool isInitialized;
- Configuration m_Configuration;
- static string s_BaseUrl = "http://editor-support.unityads.unity3d.com/games";
- static string s_Version = "3.7.5";
- private UnityLifecycleManager _callbackExecutor;
- public event EventHandler<PlacementContentReadyEventArgs> OnPlacementContentReady;
- public event EventHandler<PlacementContentStateChangeEventArgs> OnPlacementContentStateChange
- {
- add {}
- remove {}
- }
- public event EventHandler<UnityServicesErrorEventArgs> onError
- {
- add {}
- remove {}
- }
- public string version { get; } = "3.7.5";
- public Platform()
- {
- var callbackExecutorGameObject = new GameObject("UnityAdsCallbackExecutorObject")
- {
- hideFlags = HideFlags.HideAndDontSave | HideFlags.HideInInspector
- };
- _callbackExecutor = new UnityLifecycleManager();
- Object.DontDestroyOnLoad(callbackExecutorGameObject);
- }
- public void Initialize(string gameId, bool testMode)
- {
- var placeHolderGameObject = new GameObject("UnityMonetizationEditorPlaceHolderObject")
- {
- hideFlags = HideFlags.HideAndDontSave | HideFlags.HideInInspector
- };
- m_Placeholder = placeHolderGameObject.AddComponent<Placeholder>();
- string configurationUrl = string.Join("/", new string[]
- {
- s_BaseUrl,
- gameId,
- string.Join("&", new string[]
- {
- "configuration?platform=editor",
- "unityVersion=" + Uri.EscapeDataString(Application.unityVersion),
- "sdkVersionName=" + Uri.EscapeDataString(s_Version)
- })
- });
- WebRequest request = WebRequest.Create(configurationUrl);
- request.BeginGetResponse(result =>
- {
- WebResponse response = request.EndGetResponse(result);
- var reader = new StreamReader(response.GetResponseStream());
- string responseBody = reader.ReadToEnd();
- try
- {
- m_Configuration = new Configuration(responseBody);
- if (!m_Configuration.enabled)
- {
- Debug.LogWarning("gameId " + gameId + " is not enabled");
- }
- }
- catch (Exception exception)
- {
- Debug.LogError("Failed to parse configuration for gameId: " + gameId);
- Debug.Log(responseBody);
- Debug.LogError(exception.Message);
- }
- reader.Close();
- response.Close();
- if (m_Configuration != null)
- {
- foreach (KeyValuePair<string, PlacementContent> entry in m_Configuration.placementContents)
- {
- _callbackExecutor.Post(() =>
- {
- OnPlacementContentReady?.Invoke(this, new PlacementContentReadyEventArgs(entry.Key, entry.Value));
- });
- }
- }
- }, null);
- isInitialized = true;
- UnityEngine.Advertisements.Advertisement.Initialize(gameId, testMode);
- Debug.Log("UnityMonetizationEditor: Initialize(" + gameId + ", " + testMode + ");");
- }
- public PlacementContent GetPlacementContent(string placementID)
- {
- if (m_Configuration != null && m_Configuration.placementContents.ContainsKey(placementID))
- {
- return m_Configuration.placementContents[placementID];
- }
- else
- {
- return new ShowAdPlacementContent("fakeId", new EditorShowAdOperations());
- }
- }
- public INativePromoAdapter CreateNativePromoAdapter(PromoAdPlacementContent placementContent)
- {
- return new EditorNativePromoAdapter(placementContent);
- }
- public void SetMetaData(MetaData metaData)
- {
- }
- public void SetPurchasingAdapter(IPurchasingAdapter adapter)
- {
- }
- public bool isSupported
- {
- get
- {
- return Application.isEditor;
- }
- }
- public bool IsReady(string placementID)
- {
- return isInitialized && m_Configuration != null;
- }
- }
- #elif UNITY_ANDROID
- sealed internal class Platform : AndroidJavaProxy, IMonetizationPlatform, IPurchasingEventSender
- {
- private static readonly IDictionary<string, PlacementContentType> PlacementContentTypesMap = new Dictionary<string, PlacementContentType>
- {
- {"SHOW_AD", PlacementContentType.ShowAd},
- {"PROMO_AD", PlacementContentType.PromoAd},
- {"SINK_PROMO", PlacementContentType.SinkPromo},
- {"CUSTOM", PlacementContentType.Custom}
- };
- public event EventHandler<PlacementContentReadyEventArgs> OnPlacementContentReady;
- public event EventHandler<PlacementContentStateChangeEventArgs> OnPlacementContentStateChange;
- public event EventHandler<UnityServicesErrorEventArgs> onError;
- readonly AndroidJavaObject m_CurrentActivity;
- readonly IUnityLifecycleManager m_CallbackExecutor;
- readonly Purchase m_UnityMonetizationPurchase;
- readonly AndroidAnalytics m_UnityMonetizationAnalytics;
- private IDictionary<string, PlacementContent> m_PlacementContents = new Dictionary<string, PlacementContent>();
- private AndroidJavaClass m_unityMonetizationClass = new AndroidJavaClass("com.unity3d.services.monetization.UnityMonetization");
- private AndroidJavaClass m_unityServicesClass = new AndroidJavaClass("com.unity3d.services.UnityServices");
- private AndroidJavaClass m_unityPurchasingClass = new AndroidJavaClass("com.unity3d.services.purchasing.UnityPurchasing");
- public Platform() : base("com.unity3d.services.monetization.IUnityMonetizationListener")
- {
- var unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
- this.m_CurrentActivity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");
- this.m_UnityMonetizationPurchase = new Purchase();
- this.m_UnityMonetizationAnalytics = new AndroidAnalytics();
- m_CallbackExecutor = new UnityLifecycleManager();
- }
- void onPlacementContentReady(string placementId, AndroidJavaObject placementcontent)
- {
- PlacementContentType type = this.getPlacementContentTypeForAndroidObject(placementcontent);
- IPlacementContentOperations operations = this.getPlacementContentOperationsForType(type, placementcontent);
- PlacementContent m_placementcontent = this.getPlacementContentForType(type, placementId, operations);
- m_placementcontent.extras = JavaMapUtilities.GetDictionaryForJavaMap(placementcontent.Call<AndroidJavaObject>("getExtras"));
- if (m_PlacementContents.ContainsKey(placementId))
- {
- m_PlacementContents.Remove(placementId);
- }
- m_PlacementContents.Add(placementId, m_placementcontent);
- m_CallbackExecutor.Post(() =>
- {
- OnPlacementContentReady?.Invoke(this, new PlacementContentReadyEventArgs(placementId, m_placementcontent));
- });
- }
- private IPlacementContentOperations getPlacementContentOperationsForType(PlacementContentType type, AndroidJavaObject placementcontent)
- {
- switch (type)
- {
- case PlacementContentType.ShowAd:
- return new AndroidShowAdOperations(m_CallbackExecutor, placementcontent);
- case PlacementContentType.PromoAd:
- return new AndroidPromoAdOperations(m_CallbackExecutor, placementcontent);
- default:
- return new AndroidPlacementContentOperations(placementcontent);
- }
- }
- private PlacementContent getPlacementContentForType(PlacementContentType type, string placementId, IPlacementContentOperations operations)
- {
- switch (type)
- {
- case PlacementContentType.ShowAd:
- return new ShowAdPlacementContent(placementId, operations as IShowAdOperations);
- case PlacementContentType.PromoAd:
- return new PromoAdPlacementContent(placementId, operations as IPromoAdOperations);
- default:
- return new PlacementContent(placementId, operations);
- }
- }
- private PlacementContentState getPlacementContentStateForJavaPlacementContentState(AndroidJavaObject javaObject)
- {
- return (PlacementContentState)JavaEnumUtilities.GetEnumOrdinal(javaObject);
- }
- void onPlacementContentStateChange(string placementId, AndroidJavaObject placementcontent, AndroidJavaObject previousState, AndroidJavaObject newState)
- {
- if (m_PlacementContents.ContainsKey(placementId))
- {
- PlacementContent m_placementContent = m_PlacementContents[placementId];
- PlacementContentState m_previousState = this.getPlacementContentStateForJavaPlacementContentState(previousState);
- PlacementContentState m_newState = this.getPlacementContentStateForJavaPlacementContentState(newState);
- m_CallbackExecutor.Post(() =>
- {
- OnPlacementContentStateChange?.Invoke(this,
- new PlacementContentStateChangeEventArgs(placementId, m_placementContent, m_previousState, m_newState));
- });
- }
- }
- void onUnityServicesError(AndroidJavaObject error, string message)
- {
- var errOrdinal = error?.Call<int>("ordinal") ?? -1;
- m_CallbackExecutor.Post(() =>
- {
- onError?.Invoke(this, new UnityServicesErrorEventArgs(errOrdinal, message));
- });
- }
- public void Initialize(string gameId, bool testMode)
- {
- m_UnityMonetizationPurchase.Initialize(this);
- m_UnityMonetizationAnalytics.Initialize();
- m_unityMonetizationClass.CallStatic("initialize", this.m_CurrentActivity, gameId, this, testMode);
- }
- public void SetPurchasingAdapter(IPurchasingAdapter adapter)
- {
- m_unityPurchasingClass.CallStatic("setAdapter", new AndroidPurchasingAdapter(adapter));
- }
- public string version => m_unityServicesClass.CallStatic<string>("getVersion");
- public bool isSupported => m_unityServicesClass.CallStatic<bool>("isSupported");
- private PlacementContentType getPlacementContentTypeForAndroidObject(AndroidJavaObject javaObject)
- {
- var placementcontentType = javaObject.SafeStringCall("getType");
- if (PlacementContentTypesMap.ContainsKey(placementcontentType))
- {
- return PlacementContentTypesMap[placementcontentType];
- }
- return PlacementContentType.Custom;
- }
- public bool IsReady(string placementID)
- {
- return m_unityMonetizationClass.CallStatic<bool>("isReady", placementID);
- }
- public PlacementContent GetPlacementContent(string placementID)
- {
- if (m_PlacementContents.ContainsKey(placementID))
- {
- return m_PlacementContents[placementID];
- }
- return null;
- }
- public INativePromoAdapter CreateNativePromoAdapter(PromoAdPlacementContent placementContent)
- {
- return new AndroidNativePromoAdapter(placementContent);
- }
- public void SetMetaData(MetaData metaData)
- {
- var metaDataObject = new AndroidJavaObject("com.unity3d.ads.metadata.MetaData", m_CurrentActivity);
- metaDataObject.Call("setCategory", metaData.category);
- foreach (var entry in metaData)
- {
- metaDataObject.Call<bool>("set", entry.Key, entry.Value);
- }
- metaDataObject.Call("commit");
- }
- void IPurchasingEventSender.SendPurchasingEvent(string payload)
- {
- m_UnityMonetizationPurchase.SendEvent(payload);
- }
- private class AndroidPurchasingAdapter : AndroidJavaProxy
- {
- private IPurchasingAdapter adapter;
- public AndroidPurchasingAdapter(IPurchasingAdapter adapter) : base("com.unity3d.services.purchasing.core.IPurchasingAdapter")
- {
- this.adapter = adapter;
- }
- public void retrieveProducts(AndroidJavaObject listener)
- {
- this.adapter.RetrieveProducts(new AndroidRetrieveProductsListener(listener));
- }
- public void onPurchase(string productID, AndroidJavaObject javaListener, AndroidJavaObject javaExtras)
- {
- IDictionary<string, object> extras = JavaMapUtilities.GetDictionaryForJavaMap(javaExtras);
- this.adapter.Purchase(productID, new AndroidTransactionListener(javaListener), extras);
- }
- private class AndroidRetrieveProductsListener : IRetrieveProductsListener
- {
- private AndroidJavaObject listener;
- public AndroidRetrieveProductsListener(AndroidJavaObject listener)
- {
- this.listener = listener;
- }
- public void OnProductsRetrieved(ICollection<Product> products)
- {
- var productsList = this.getJavaProductList(products);
- listener.Call("onProductsRetrieved", productsList);
- }
- private AndroidJavaObject getJavaProductList(ICollection<Product> products)
- {
- AndroidJavaObject javaProductList = new AndroidJavaObject("java.util.ArrayList");
- foreach (var product in products)
- {
- javaProductList.Call<bool>("add", this.getJavaProduct(product));
- }
- return javaProductList;
- }
- private AndroidJavaObject getJavaProduct(Product product)
- {
- AndroidJavaObject builder = new AndroidJavaClass("com.unity3d.services.purchasing.core.Product")
- .CallStatic<AndroidJavaObject>("newBuilder");
- builder.Call<AndroidJavaObject>("withProductId", product.productId);
- builder.Call<AndroidJavaObject>("withLocalizedPriceString", product.localizedPriceString);
- builder.Call<AndroidJavaObject>("withLocalizedTitle", product.localizedTitle);
- builder.Call<AndroidJavaObject>("withIsoCurrencyCode", product.isoCurrencyCode);
- builder.Call<AndroidJavaObject>("withLocalizedPrice", (double)product.localizedPrice);
- builder.Call<AndroidJavaObject>("withLocalizedDescription", product.localizedDescription);
- builder.Call<AndroidJavaObject>("withProductType", product.productType);
- return builder.Call<AndroidJavaObject>("build");
- }
- }
- private class AndroidTransactionListener : ITransactionListener
- {
- private AndroidJavaObject listener;
- public AndroidTransactionListener(AndroidJavaObject listener)
- {
- this.listener = listener;
- }
- public void OnTransactionComplete(TransactionDetails details)
- {
- listener.Call("onTransactionComplete", AndroidNativePromoAdapter.getJavaTransactionDetails(details));
- }
- public void OnTransactionError(TransactionErrorDetails details)
- {
- listener.Call("onTransactionError", AndroidNativePromoAdapter.getJavaTransactionErrorDetails(details));
- }
- }
- }
- }
- #elif UNITY_IOS
- public class Platform : IMonetizationPlatform
- {
- private static readonly IDictionary<string, PlacementContentType> PlacementContentTypesMap = new Dictionary<string, PlacementContentType>
- {
- {"SHOW_AD", PlacementContentType.ShowAd},
- {"PROMO_AD", PlacementContentType.PromoAd},
- {"SINK_PROMO", PlacementContentType.SinkPromo},
- {"CUSTOM", PlacementContentType.Custom}
- };
- [DllImport("__Internal")]
- static extern bool UnityMonetizationIsReady(string placementId);
- [DllImport("__Internal")]
- static extern void UnityMonetizationInitialize(string gameId, bool isTestMode);
- [DllImport("__Internal")]
- static extern bool UnityMonetizationIsSupported();
- [DllImport("__Internal")]
- static extern string UnityMonetizationGetPlacementContentType(IntPtr pPlacementContent);
- [DllImport("__Internal")]
- [return : MarshalAs(UnmanagedType.LPWStr)]
- static extern string UnityMonetizationGetPlacementContentExtras(IntPtr pPlacementContent);
- [DllImport("__Internal")]
- static extern void UnityAdsSetMetaData(string category, string data);
- [DllImport("__Internal")]
- static extern string UnityAdsGetVersion();
- private readonly IUnityLifecycleManager _callbackExecutor;
- private readonly IDictionary<string, PlacementContent> _placementContents = new Dictionary<string, PlacementContent>();
- public event EventHandler<PlacementContentReadyEventArgs> OnPlacementContentReady;
- public event EventHandler<PlacementContentStateChangeEventArgs> OnPlacementContentStateChange;
- public event EventHandler<UnityServicesErrorEventArgs> onError;
- public Platform()
- {
- _callbackExecutor = new UnityLifecycleManager();
- }
- public void Initialize(string gameId, bool testMode)
- {
- PlatformCallbacksWrapper.Platform = this;
- new IosAnalytics().Initialize();
- new PurchasingPlatform().Initialize();
- UnityMonetizationInitialize(gameId, testMode);
- }
- public bool IsReady(string placementId)
- {
- return UnityMonetizationIsReady(placementId);
- }
- public void SetPurchasingAdapter(IPurchasingAdapter adapter)
- {
- PurchasingAdapter.Adapter = adapter;
- }
- public PlacementContent GetPlacementContent(string placementId)
- {
- if (_placementContents.ContainsKey(placementId))
- {
- return _placementContents[placementId];
- }
- return null;
- }
- public INativePromoAdapter CreateNativePromoAdapter(PromoAdPlacementContent placementContent)
- {
- return new IosNativePromoAdapter(placementContent);
- }
- public void SetMetaData(MetaData metaData)
- {
- UnityAdsSetMetaData(metaData.category, metaData.ToJSON());
- }
- public bool isSupported => UnityMonetizationIsSupported();
- public string version => UnityAdsGetVersion();
- private void OnNativePlacementContentReady(string placementId, IntPtr pPlacementContent)
- {
- var type = GetPlacementContentTypeForPlacementContentPtr(pPlacementContent);
- var operations = GetPlacementContentOperationsForType(type, pPlacementContent);
- var placementContent = GetPlacementContentForType(type, placementId, operations);
- var extras = GetPlacementContentExtras(pPlacementContent);
- placementContent.extras = extras;
- if (_placementContents.ContainsKey(placementId))
- {
- _placementContents.Remove(placementId);
- }
- _placementContents.Add(placementId, placementContent);
- _callbackExecutor.Post(() =>
- {
- OnPlacementContentReady?.Invoke(this, new PlacementContentReadyEventArgs(placementId, placementContent));
- });
- }
- private IDictionary<string, object> GetPlacementContentExtras(IntPtr pPlacementContent)
- {
- var json = UnityMonetizationGetPlacementContentExtras(pPlacementContent);
- if (json == null)
- {
- return new Dictionary<string, object>();
- }
- var deserialized = MiniJSON.Json.Deserialize(json);
- if (deserialized is IDictionary<string, object> objects)
- {
- return objects;
- }
- return new Dictionary<string, object>();
- }
- private static PlacementContentType GetPlacementContentTypeForPlacementContentPtr(IntPtr pPlacementContent)
- {
- string type = UnityMonetizationGetPlacementContentType(pPlacementContent);
- return PlacementContentTypesMap[type];
- }
- private IPlacementContentOperations GetPlacementContentOperationsForType(PlacementContentType type, IntPtr pPlacementContent)
- {
- switch (type)
- {
- case PlacementContentType.ShowAd:
- return new IosShowAdOperations(pPlacementContent, _callbackExecutor);
- case PlacementContentType.PromoAd:
- return new IosPromoAdOperations(pPlacementContent, _callbackExecutor);
- default:
- return new IosPlacementContentOperations(pPlacementContent);
- }
- }
- private PlacementContent GetPlacementContentForType(PlacementContentType type, string placementId, IPlacementContentOperations operations)
- {
- switch (type)
- {
- case PlacementContentType.ShowAd:
- return new ShowAdPlacementContent(placementId, operations as IShowAdOperations);
- case PlacementContentType.PromoAd:
- return new PromoAdPlacementContent(placementId, operations as IPromoAdOperations);
- default:
- return new PlacementContent(placementId, operations);
- }
- }
- internal void OnNativePlacementContentStateChanged(string placementId, IntPtr pPlacementContent, int previousState, int newState)
- {
- if (_placementContents.ContainsKey(placementId))
- {
- var placementContent = _placementContents[placementId];
- _callbackExecutor.Post(() =>
- {
- OnPlacementContentStateChange?.Invoke(this, new PlacementContentStateChangeEventArgs(placementId, placementContent, (PlacementContentState)previousState, (PlacementContentState)newState));
- });
- }
- }
- private void OnNativeError(long error, string message)
- {
- onError?.Invoke(this, new UnityServicesErrorEventArgs(error, message));
- }
- private static class PlatformCallbacksWrapper
- {
- internal static Platform Platform { get; set; }
- delegate void OnPlacementContentReadyCallback(string placementId, IntPtr placementContent);
- delegate void OnPlacementContentStateChangedCallback(string placementId, IntPtr placementContent, int previousState, int newState);
- delegate void OnErrorCallback(long error, string message);
- [StructLayout(LayoutKind.Sequential)]
- struct UnityMonetiztionCallbacks
- {
- public OnPlacementContentReadyCallback onPlacementContentReadyCallback;
- public OnPlacementContentStateChangedCallback onPlacementContentStateChangedCallback;
- public OnErrorCallback onErrorCallback;
- }
- [DllImport("__Internal")]
- private static extern void UnityMonetizationSetMonetizationCallbacks(ref UnityMonetiztionCallbacks callback);
- static PlatformCallbacksWrapper()
- {
- var callbacks = new UnityMonetiztionCallbacks
- {
- onPlacementContentReadyCallback = OnPlacementContentReady,
- onPlacementContentStateChangedCallback = OnPlacementContentChanged,
- onErrorCallback = OnError
- };
- UnityMonetizationSetMonetizationCallbacks(ref callbacks);
- }
- [MonoPInvokeCallback(typeof(OnPlacementContentReadyCallback))]
- private static void OnPlacementContentReady(string placementId, IntPtr placementContent)
- {
- Platform?.OnNativePlacementContentReady(placementId, placementContent);
- }
- [MonoPInvokeCallback(typeof(OnPlacementContentStateChangedCallback))]
- private static void OnPlacementContentChanged(string placementId, IntPtr placementContent, int previousState, int newState)
- {
- Platform?.OnNativePlacementContentStateChanged(placementId, placementContent, previousState, newState);
- }
- [MonoPInvokeCallback(typeof(OnPlacementContentStateChangedCallback))]
- private static void OnError(long error, string message)
- {
- Platform?.OnNativeError(error, message);
- }
- }
- private static class PurchasingAdapter
- {
- internal static IPurchasingAdapter Adapter { private get; set; }
- delegate void OnRetrieveProductsCallback(IntPtr listener);
- delegate void OnPurchaseProductCallback(string productId, IntPtr callbacks);
- [StructLayout(LayoutKind.Sequential)]
- struct UnityPurchasingCallbacks
- {
- public OnRetrieveProductsCallback onRetrieveProductsCallback;
- public OnPurchaseProductCallback onPurchaseProductCallback;
- }
- [DllImport("__Internal")]
- private static extern void UnityPurchasingSetPurchasingAdapterCallbacks(ref UnityPurchasingCallbacks callback);
- static PurchasingAdapter()
- {
- var callbacks = new UnityPurchasingCallbacks
- {
- onRetrieveProductsCallback = OnRetrieveProducts,
- onPurchaseProductCallback = OnPurchaseProduct
- };
- UnityPurchasingSetPurchasingAdapterCallbacks(ref callbacks);
- }
- [MonoPInvokeCallback(typeof(OnRetrieveProductsCallback))]
- private static void OnRetrieveProducts(IntPtr pCallback)
- {
- Adapter?.RetrieveProducts(new IosRetrieveProductsListener(pCallback));
- }
- [MonoPInvokeCallback(typeof(OnPurchaseProductCallback))]
- private static void OnPurchaseProduct(string productId, IntPtr pCallbacks)
- {
- Adapter?.Purchase(productId, new IosTransactionListener(pCallbacks), new Dictionary<string, object>());
- }
- }
- private class IosRetrieveProductsListener : IRetrieveProductsListener
- {
- // Note, this struct layout matches UnityMonetizationPurchasingAdapter.mm
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- public struct NativeProduct
- {
- [MarshalAs(UnmanagedType.LPWStr)]
- public string productId;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string localizedTitle;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string localizedDescription;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string localizedPriceString;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string isoCurrencyCode;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string productType;
- [MarshalAs(UnmanagedType.R8)]
- public double localizedPrice;
- }
- [DllImport("__Internal")]
- private static extern IntPtr UnityPurchasingAdapterAllocateProductsArray(int num);
- [DllImport("__Internal")]
- private static extern void UnityPurchasingAddItemToProductsArray(IntPtr pArray, ref NativeProduct product);
- [DllImport("__Internal")]
- private static extern void UnityPurchasingInvokeRetrieveProductsCallback(IntPtr callback, IntPtr pArray);
- private readonly IntPtr _pCallback;
- public IosRetrieveProductsListener(IntPtr callback)
- {
- _pCallback = callback;
- }
- public void OnProductsRetrieved(ICollection<Product> products)
- {
- var pProducts = UnityPurchasingAdapterAllocateProductsArray(products.Count);
- foreach (var product in products)
- {
- var nativeProduct = new NativeProduct
- {
- productId = product.productId,
- localizedTitle = product.localizedTitle,
- localizedDescription = product.localizedDescription,
- localizedPriceString = product.localizedPriceString,
- isoCurrencyCode = product.isoCurrencyCode,
- productType = product.productType,
- localizedPrice = (double)product.localizedPrice
- };
- UnityPurchasingAddItemToProductsArray(pProducts, ref nativeProduct);
- }
- UnityPurchasingInvokeRetrieveProductsCallback(_pCallback, pProducts);
- }
- }
- private class IosTransactionListener : ITransactionListener
- {
- [DllImport("__Internal")]
- private static extern void UnityPurchasingInvokeTransactionCompleteCallback(IntPtr pCallbacks, [MarshalAs(UnmanagedType.LPWStr)] string transactionDetails);
- [DllImport("__Internal")]
- private static extern void UnityPurchasingInvokeTransactionErrorCallback(IntPtr pCallbacks, [MarshalAs(UnmanagedType.LPWStr)] string transactionErrorDetails);
- private readonly IntPtr _pCallbacks;
- public IosTransactionListener(IntPtr pCallbacks)
- {
- _pCallbacks = pCallbacks;
- }
- public void OnTransactionComplete(TransactionDetails details)
- {
- UnityPurchasingInvokeTransactionCompleteCallback(_pCallbacks, MiniJSON.Json.Serialize(details.ToJsonDictionary()));
- }
- public void OnTransactionError(TransactionErrorDetails details)
- {
- UnityPurchasingInvokeTransactionErrorCallback(_pCallbacks, MiniJSON.Json.Serialize(details.ToJsonDictionary()));
- }
- }
- }
- #endif
- }
|