2023-12-26 03:40:48 +00:00
|
|
|
namespace Guru
|
|
|
|
|
{
|
2023-12-27 12:24:16 +00:00
|
|
|
using System;
|
|
|
|
|
using UnityEngine;
|
2024-05-07 12:37:57 +00:00
|
|
|
using System.Collections.Generic;
|
2024-08-08 18:40:36 +00:00
|
|
|
using Newtonsoft.Json;
|
2024-05-07 12:37:57 +00:00
|
|
|
using System.Linq;
|
2023-12-27 12:24:16 +00:00
|
|
|
|
2024-08-08 18:40:36 +00:00
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
class PurchasedProduct
|
|
|
|
|
{
|
|
|
|
|
public string productName;
|
|
|
|
|
public string productId;
|
|
|
|
|
public string receipt;
|
|
|
|
|
public bool appleProductIsRestored;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
class GuruSDKSerializedModel
|
|
|
|
|
{
|
|
|
|
|
//-------------- data ---------------
|
|
|
|
|
|
|
|
|
|
public string uid = "";
|
2024-08-09 02:02:26 +00:00
|
|
|
public int b_level = 0;
|
|
|
|
|
public int b_play = 0;
|
|
|
|
|
public bool no_ads = false;
|
2024-08-08 18:40:36 +00:00
|
|
|
public List<PurchasedProduct> purchased = new List<PurchasedProduct>(10);
|
|
|
|
|
|
|
|
|
|
//-------------- data ---------------
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-26 03:40:48 +00:00
|
|
|
[Serializable]
|
|
|
|
|
internal class GuruSDKModel
|
|
|
|
|
{
|
2023-12-27 12:24:16 +00:00
|
|
|
private const float SaveInterval = 3;
|
|
|
|
|
private const string SaveKey = "com.guru.sdk.model.save";
|
2024-08-09 06:29:21 +00:00
|
|
|
private DateTime _lastSavedTime = new DateTime(1970,1,1);
|
|
|
|
|
|
2024-08-08 18:40:36 +00:00
|
|
|
private bool _noAds = false;
|
|
|
|
|
private readonly BindableProperty<int> _bLevel;
|
|
|
|
|
private readonly BindableProperty<int> _bPlay;
|
|
|
|
|
private string _uid;
|
|
|
|
|
private List<PurchasedProduct> _purchased;
|
2023-12-27 12:24:16 +00:00
|
|
|
|
|
|
|
|
|
2023-12-26 03:40:48 +00:00
|
|
|
private static GuruSDKModel _instance;
|
|
|
|
|
public static GuruSDKModel Instance
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
if (null == _instance) _instance = new GuruSDKModel();
|
2023-12-26 03:40:48 +00:00
|
|
|
return _instance;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-08 18:40:36 +00:00
|
|
|
public GuruSDKModel()
|
2023-12-26 03:40:48 +00:00
|
|
|
{
|
2024-08-09 06:29:21 +00:00
|
|
|
// 读取内存值
|
2024-08-08 18:40:36 +00:00
|
|
|
GuruSDKSerializedModel model = LoadModel();
|
|
|
|
|
_uid = model.uid;
|
2024-08-09 02:02:26 +00:00
|
|
|
_noAds = model.no_ads;
|
|
|
|
|
_bLevel = new BindableProperty<int>(model.b_level);
|
|
|
|
|
_bPlay = new BindableProperty<int>(model.b_play);
|
2024-08-08 18:40:36 +00:00
|
|
|
_purchased = model.purchased;
|
2023-12-26 03:40:48 +00:00
|
|
|
}
|
2024-08-09 10:21:01 +00:00
|
|
|
|
2024-08-08 18:40:36 +00:00
|
|
|
public int BLevel
|
2023-12-26 03:40:48 +00:00
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
get => _bLevel.Value;
|
2024-01-07 14:59:02 +00:00
|
|
|
set
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
if (value < _bLevel.Value)
|
|
|
|
|
{
|
|
|
|
|
// b_level 必须比上一次的值大
|
|
|
|
|
Debug.LogWarning($"[SDK] :: Set b_level [{value}] should not be less than original value [{_bLevel.Value}]");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
_bLevel.Value = value;
|
|
|
|
|
Save();
|
2024-01-07 14:59:02 +00:00
|
|
|
}
|
2023-12-26 03:40:48 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-08 18:40:36 +00:00
|
|
|
public int BPlay
|
2023-12-26 03:40:48 +00:00
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
get => _bPlay.Value;
|
2024-01-07 14:59:02 +00:00
|
|
|
set
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
_bPlay.Value = value;
|
|
|
|
|
Save();
|
2024-01-07 14:59:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string UserId
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
get => _uid;
|
2024-08-07 11:33:12 +00:00
|
|
|
set
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
_uid = value;
|
2024-08-07 11:33:12 +00:00
|
|
|
Save();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-08-06 19:28:44 +00:00
|
|
|
|
2024-08-08 18:40:36 +00:00
|
|
|
|
|
|
|
|
public bool IsIapUser => _purchased.Count > 0;
|
2024-05-17 02:28:35 +00:00
|
|
|
|
2024-05-21 00:41:29 +00:00
|
|
|
public bool IsNoAds
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
get => _noAds;
|
2024-05-21 00:41:29 +00:00
|
|
|
set
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
_noAds = value;
|
2024-05-21 00:41:29 +00:00
|
|
|
Save();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-08-08 18:40:36 +00:00
|
|
|
|
|
|
|
|
public void SetOnBLevelChanged(Action<int> action)
|
|
|
|
|
{
|
|
|
|
|
_bLevel.OnValueChanged += action;
|
|
|
|
|
}
|
2023-12-26 03:40:48 +00:00
|
|
|
|
2024-08-08 18:40:36 +00:00
|
|
|
public void SetOnBPlayChanged(Action<int> action)
|
|
|
|
|
{
|
|
|
|
|
_bPlay.OnValueChanged += action;
|
|
|
|
|
}
|
2023-12-26 03:40:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#region 初始化
|
2024-08-08 18:40:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
private GuruSDKSerializedModel LoadModel()
|
2023-12-26 03:40:48 +00:00
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
GuruSDKSerializedModel model = null;
|
2023-12-26 03:40:48 +00:00
|
|
|
if (PlayerPrefs.HasKey(SaveKey))
|
|
|
|
|
{
|
|
|
|
|
var json = PlayerPrefs.GetString(SaveKey, "");
|
|
|
|
|
if (!string.IsNullOrEmpty(json))
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
model = JsonUtility.FromJson<GuruSDKSerializedModel>(json);
|
2023-12-26 03:40:48 +00:00
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
Debug.LogError(e);
|
2023-12-26 03:40:48 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-08-08 18:40:36 +00:00
|
|
|
if(model == null) model = new GuruSDKSerializedModel();
|
2023-12-26 03:40:48 +00:00
|
|
|
return model;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2024-08-09 06:29:21 +00:00
|
|
|
/// 保存至 PlayerPrefs 数据
|
2023-12-26 03:40:48 +00:00
|
|
|
/// </summary>
|
2024-08-09 06:29:21 +00:00
|
|
|
/// <param name="writeToDisk"></param>
|
2024-08-09 10:21:01 +00:00
|
|
|
private void SetToMemory()
|
2023-12-26 03:40:48 +00:00
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
var model = new GuruSDKSerializedModel()
|
|
|
|
|
{
|
|
|
|
|
uid = _uid,
|
2024-08-09 02:02:26 +00:00
|
|
|
b_level = _bLevel.Value,
|
|
|
|
|
b_play = _bPlay.Value,
|
|
|
|
|
no_ads = _noAds,
|
2024-08-08 18:40:36 +00:00
|
|
|
purchased = _purchased,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var json = JsonUtility.ToJson(model);
|
2024-08-09 06:29:21 +00:00
|
|
|
if (!string.IsNullOrEmpty(json))
|
|
|
|
|
{
|
|
|
|
|
PlayerPrefs.SetString(SaveKey, json);
|
|
|
|
|
}
|
2023-12-26 03:40:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 保存数据
|
|
|
|
|
/// </summary>
|
2024-08-09 06:29:21 +00:00
|
|
|
/// <param name="forceSave"></param>
|
|
|
|
|
public void Save(bool forceSave = false)
|
2023-12-26 03:40:48 +00:00
|
|
|
{
|
2024-08-09 10:21:01 +00:00
|
|
|
SetToMemory(); // 每次保存都要设置到 PlayerPrefs 内
|
|
|
|
|
|
|
|
|
|
bool shouldWriteToDisk = forceSave || (DateTime.Now - _lastSavedTime)>= TimeSpan.FromSeconds(SaveInterval);
|
|
|
|
|
if (!shouldWriteToDisk) return;
|
|
|
|
|
_lastSavedTime = DateTime.Now; // 更新最后保存时间
|
|
|
|
|
PlayerPrefs.Save(); // 写入到磁盘
|
2023-12-26 03:40:48 +00:00
|
|
|
}
|
2024-05-17 02:28:35 +00:00
|
|
|
|
2023-12-26 03:40:48 +00:00
|
|
|
#endregion
|
2023-12-27 12:24:16 +00:00
|
|
|
|
2024-01-19 12:45:56 +00:00
|
|
|
|
|
|
|
|
#region 订单记录
|
2024-08-08 18:40:36 +00:00
|
|
|
|
2024-01-19 12:45:56 +00:00
|
|
|
public bool HasPurchasedProduct(string receipt)
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
if(_purchased.Count == 0) return false;
|
|
|
|
|
return _purchased.Exists(p => p.receipt == receipt);
|
2024-01-19 12:45:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 添加已支付订单
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="receipt"></param>
|
|
|
|
|
/// <param name="productName"></param>
|
|
|
|
|
/// <param name="productId"></param>
|
2024-08-08 18:40:36 +00:00
|
|
|
/// <param name="appleProductIsRestored"></param>
|
2024-01-19 12:45:56 +00:00
|
|
|
public void AddReceipt(string receipt, string productName, string productId, bool appleProductIsRestored = false)
|
|
|
|
|
{
|
|
|
|
|
if (!HasPurchasedProduct(receipt))
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
_purchased.Add(new PurchasedProduct()
|
2024-01-19 12:45:56 +00:00
|
|
|
{
|
|
|
|
|
receipt = receipt,
|
|
|
|
|
productName = productName,
|
|
|
|
|
productId = productId,
|
|
|
|
|
appleProductIsRestored = appleProductIsRestored
|
|
|
|
|
});
|
|
|
|
|
Save();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string[] GetReceipts(string productName)
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
var receipts = new List<string>();
|
|
|
|
|
receipts.AddRange(from purchasedProduct in _purchased where purchasedProduct.productName == productName select purchasedProduct.receipt);
|
2024-01-19 12:45:56 +00:00
|
|
|
return receipts.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public string[] GetReceiptsById(string productId)
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
var receipts = new List<string>();
|
|
|
|
|
receipts.AddRange(from purchasedProduct in _purchased where purchasedProduct.productId == productId select purchasedProduct.receipt);
|
2024-01-19 12:45:56 +00:00
|
|
|
return receipts.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-12-27 12:24:16 +00:00
|
|
|
#endregion
|
2023-12-26 03:40:48 +00:00
|
|
|
|
2024-08-07 15:14:15 +00:00
|
|
|
|
|
|
|
|
#region 清除数据
|
|
|
|
|
|
|
|
|
|
public void ClearData()
|
|
|
|
|
{
|
2024-08-08 18:40:36 +00:00
|
|
|
PlayerPrefs.DeleteKey(SaveKey);
|
2024-08-07 15:14:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
2023-12-26 03:40:48 +00:00
|
|
|
}
|
|
|
|
|
|
2024-08-08 18:40:36 +00:00
|
|
|
|
2023-12-26 03:40:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|