#if UNITY_EDITOR using Eiko.YaSDK.Editor; #endif using System; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using Eiko.YaSDK.Data; using UnityEngine; using UnityEngine.Audio; namespace Eiko.YaSDK { public class YandexSDK : MonoBehaviour { public AudioSource audio; #if UNITY_EDITOR [HideInInspector] public CanvasAddEditor editorCanvas; #endif public const int ReloadAdsSeconds = 30; public bool AdsEnabled { get; private set; } public static YandexSDK instance; [DllImport("__Internal")] private static extern void GetUserData(); [DllImport("__Internal")] private static extern void ShowFullscreenAd(); [DllImport("__Internal")] private static extern void SetData(string key,string value); [DllImport("__Internal")] private static extern void SetScore(string key, int value); [DllImport("__Internal")] private static extern void InitPlayerData(); /// /// Returns an int value which is sent to index.html /// /// /// [DllImport("__Internal")] private static extern int ShowRewardedAd(string placement); //[DllImport("__Internal")] //private static extern void GerReward(); [DllImport("__Internal")] private static extern void AuthenticateUser(); [DllImport("__Internal")] private static extern void InitPurchases(); [DllImport("__Internal")] private static extern void Purchase(string id); [DllImport("__Internal")] private static extern string GetLang(); [DllImport("__Internal")] private static extern void Review(); [DllImport("__Internal")] private static extern void GetPurchases(); public event Action addsOnReloaded; public event Action onUserDataReceived; public event Action onInterstitialShown; public event Action onInterstitialFailed; /// /// Пользователь открыл рекламу /// public event Action onRewardedAdOpened; /// /// Пользователь должен получить награду за просмотр рекламы /// public event Action onRewardedAdReward; /// /// Пользователь закрыл рекламу /// public event Action onRewardedAdClosed; /// /// Вызов/просмотр рекламы повлёк за собой ошибку /// public event Action onRewardedAdError; /// /// Покупка успешно совершена /// public event Action onPurchaseSuccess; /// /// Покупка не удалась: в консоли разработчика не добавлен товар с таким id, /// пользователь не авторизовался, передумал и закрыл окно оплаты, /// истекло отведенное на покупку время, не хватило денег и т. д. /// public event Action onPurchaseFailed; public event Action onClose; public event Action onPurchaseInitialize; public event Action onPurchaseInitializeFailed; public Queue rewardedAdPlacementsAsInt = new Queue(); public Queue rewardedAdsPlacements = new Queue(); private Action actionReview; public bool addsAvailable; private bool IsReviewed = false; public UserData user; public string adsPurchize="AddOff"; public string Lang = "ru"; private void Awake() { if (instance == null) { instance = this; DontDestroyOnLoad(gameObject); #if !UNITY_EDITOR && UNITY_WEBGL Lang = GetLang(); #endif } else { Destroy(gameObject); } StartCoroutine(WaitAddReload()); #if UNITY_EDITOR editorCanvas = Instantiate(editorCanvas); #endif onPurchaseSuccess += PurchizeCallbackAds; } /// /// Call this to ask user to authenticate /// public void Authenticate() { #if !UNITY_EDITOR && UNITY_WEBGL AuthenticateUser(); #endif } /// /// Call this to show interstitial ad. Don't call frequently. There is a 3 minute delay after each show. /// public void ShowInterstitial() { if(addsAvailable&& PlayerPrefs.GetInt("AdsOff")==0) { AudioListener.pause = true; AudioListener.volume = 0; audio.volume = 0; StartCoroutine(WaitAddReload()); #if !UNITY_EDITOR && UNITY_WEBGL ShowFullscreenAd(); #else editorCanvas.OpenFullScreen(); #endif Time.timeScale = 0; } else { Debug.LogWarning("Ad not ready!"); } } /// /// Call this to show rewarded ad /// /// public void ShowRewarded(string placement) { #if !UNITY_EDITOR && UNITY_WEBGL int placemantId = ShowRewardedAd(placement); #else int placemantId = 0; #endif rewardedAdPlacementsAsInt.Enqueue(placemantId); rewardedAdsPlacements.Enqueue(placement); Time.timeScale = 0; AudioListener.pause = true; AudioListener.volume = 0; audio.volume=0; #if UNITY_EDITOR editorCanvas.OpenReward(placemantId); #endif } public void AdsOff() { PlayerPrefs.SetInt("AdsOff", 1); AdsEnabled = false; StopAllCoroutines(); Debug.Log("AdsOff"); addsAvailable = false; } public void ProcessPurchizeAdsDisabled(Action action= null) { this.action = action; ProcessPurchase(adsPurchize); } private Action action; private void PurchizeCallbackAds(Purchase purchase) { if (purchase.productID == adsPurchize) { AdsOff(); onPurchaseSuccess -= PurchizeCallbackAds; action?.Invoke(); } } /// /// Call this to receive user data /// public void RequestUserData() { #if !UNITY_EDITOR && UNITY_WEBGL GetUserData(); #endif } public void InitializePurchases() { #if !UNITY_EDITOR && UNITY_WEBGL InitPurchases(); #endif } public void ProcessPurchase(string id) { #if !UNITY_EDITOR && UNITY_WEBGL Purchase(id); #else OnPurchaseSuccess(id); #endif } public void StoreUserData(string data) { user = JsonUtility.FromJson(data); onUserDataReceived?.Invoke(); } /// /// Callback from index.html /// public void OnInterstitialShown() { Time.timeScale = 1; AudioListener.pause = false; AudioListener.volume = 1; audio.volume = 1; onInterstitialShown?.Invoke(); } /// /// Callback from index.html /// /// public void OnInterstitialError(string error) { Time.timeScale = 1; AudioListener.pause = false; AudioListener.volume = 1; onInterstitialFailed?.Invoke(error); } /// /// Callback from index.html /// /// public void OnRewardedOpen(int placement) { onRewardedAdOpened?.Invoke(placement); } /// /// Callback from index.html /// /// public void OnRewarded(int placement) { Time.timeScale = 1; if (placement == rewardedAdPlacementsAsInt.Dequeue()) { onRewardedAdReward?.Invoke(rewardedAdsPlacements.Dequeue()); } } /// /// Callback from index.html /// /// public void OnRewardedClose(int placement) { AudioListener.pause = false; AudioListener.volume = 1; audio.volume = 1; Time.timeScale = 1; onRewardedAdClosed?.Invoke(placement); } /// /// Callback from index.html /// /// public void OnRewardedError(string placement) { Time.timeScale = 1; AudioListener.pause = false; AudioListener.volume = 1; audio.volume = 1; onRewardedAdError?.Invoke(placement); rewardedAdsPlacements.Clear(); rewardedAdPlacementsAsInt.Clear(); } public void OnPurchaseSuccess(string json) { var purchase = JsonUtility.FromJson(json); onPurchaseSuccess?.Invoke(purchase); } /// /// Callback from index.html /// /// public void OnPurchaseFailed(string error) { onPurchaseFailed?.Invoke(error); } /// /// Browser tab has been closed /// /// public void OnClose() { onClose?.Invoke(); } public event Action GettedPurchase; public void TryGetPurchases() { GetPurchases(); } public IEnumerator WaitAddReload() { addsAvailable = false; yield return new WaitForSecondsRealtime(ReloadAdsSeconds); addsAvailable = true; addsOnReloaded?.Invoke(); } public void ShowReview(Action action = null) { actionReview = action; if (IsReviewed) { OnReview(JsonUtility.ToJson( new ReviewCallback() { CanReview = false, FeedbackSent = false, Reason = IsReviewed ? "GAME_RATED" : "Success" })); return; } #if !UNITY_EDITOR && UNITY_WEBGL Review(); #else editorCanvas.ShowReview(); #endif } public void OnReview(string callback) { ReviewCallback review = JsonUtility.FromJson(callback); if(review.FeedbackSent) { IsReviewed = true; } actionReview?.Invoke(review); } public event Action onDataRecived; public event Action noAutorized; public void OnGetData(string json) { GetDataCallback callback; if (!string.IsNullOrEmpty(json)) { callback = JsonUtility.FromJson(json); if(callback.data==null) { callback.data = new KeyValuePairStringCallback[0]; } if(callback.score == null) { callback.score = new KeyValuePairIntCallback[0]; } } else { callback = new GetDataCallback(); callback.data = new KeyValuePairStringCallback[0]; callback.score = new KeyValuePairIntCallback[0]; } onDataRecived?.Invoke(callback); } public void NoAutorized() { noAutorized?.Invoke(); } public void SetPlayerData(string key, string value) { #if !UNITY_EDITOR SetData(key, value); #endif } public void SetPlayerScore(string key, int value) { #if !UNITY_EDITOR SetScore(key, value); #endif } public void InitData() { #if !UNITY_EDITOR InitPlayerData(); #else StartCoroutine(InitDataEmit()); #endif } #if UNITY_EDITOR private IEnumerator InitDataEmit() { yield return new WaitForSeconds(1); NoAutorized(); } #endif public void OnPurchaseInitialize() { onPurchaseInitialize?.Invoke(); } [ContextMenu("Test")] public void Test() { string a = "{\"purchases\":[{\"productID\":\"BuyAll\",\"purchaseTime\":0,\"purchaseToken\":\"957ff7fa-938a-4c14-9454-d8a4e990347a\"},{\"productID\":\"Skin11Unlocked\",\"purchaseTime\":0,\"purchaseToken\":\"111ab5c1-33ba-4835-92f3-acb7135ead2f\"},{\"productID\":\"BuyAll\",\"purchaseTime\":0,\"purchaseToken\":\"4fe915c5-59b9-43ef-9993-e96488c3fbd0\"},{\"productID\":\"Skin12Unlocked\",\"purchaseTime\":0,\"purchaseToken\":\"bf1cd480-cd97-44cb-9938-5f81db24c0e6\"},{\"productID\":\"AddOff\",\"purchaseTime\":0,\"purchaseToken\":\"044f9005-9a8e-4a16-9256-eaa513468d1f\"},{\"productID\":\"BuyAll\",\"purchaseTime\":0,\"purchaseToken\":\"a140dc49-2d57-403f-9352-7be76ba039e2\"},{\"productID\":\"AddOff\",\"purchaseTime\":0,\"purchaseToken\":\"a6894793-fc17-43c8-a03e-fb2afd1369e7\"}]}"; var b = JsonUtility.FromJson(a); foreach (var item in b.purchases) { Debug.Log(item.productID); } } public void OnPurchaseInitializeFailed(string error) { onPurchaseInitializeFailed?.Invoke(error); } public event Action onGetPurchaseFailed; public void OnGetPurchaseFailed() { onGetPurchaseFailed?.Invoke(); } } [Serializable] public class GetDataCallback { public KeyValuePairStringCallback[] data; public KeyValuePairIntCallback[] score; } [Serializable] public class KeyValuePairStringCallback { public string key; public string value; } [Serializable] public class KeyValuePairIntCallback { public string key; public int value; } public struct ReviewCallback { public bool CanReview; public string Reason; public bool FeedbackSent; } public struct UserData { public string id; public string name; public string avatarUrlSmall; public string avatarUrlMedium; public string avatarUrlLarge; } [Serializable] public class GetPurchasesCallback { public Purchase[] purchases; public string signature; } [Serializable] public class Purchase { public string productID; public string purchaseToken; public string developerPayload; public string signature; } }