#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;
}
}