Playvoi/Playvoi.Client/Assets/ShiroginSDK/Runtime/Modules/Data/Scripts/StoreData.cs

201 lines
No EOL
6.1 KiB
C#

using System;
using System.Collections.Generic;
using ShiroginSDK.Runtime.Modules.IAP.Enums;
using UnityEngine;
namespace ShiroginSDK.Runtime.Modules.Data.Scripts
{
[Serializable]
public class ProductPurchase
{
public string ProductId;
public int PurchaseCount;
public long LastPurchaseUnix;
public StoreCategory StoreCategory;
public ProductPurchase(string id, int count, long unix, StoreCategory type = StoreCategory.UnknownPacks)
{
ProductId = id;
PurchaseCount = count;
LastPurchaseUnix = unix;
StoreCategory = type;
}
}
[Serializable]
public class LimitedOfferState
{
public string OfferId;
public bool Seen;
public bool Purchased;
public long ExpireUnix; // 0 = unlimited
public bool IsActive(long nowUnix)
{
return ExpireUnix == 0 || nowUnix < ExpireUnix;
}
}
[Serializable]
public class StoreData : BaseData
{
public const string REMOVE_ADS_PRODUCT_ID = "remove_ads";
public List<ProductPurchase> Purchases = new();
public List<LimitedOfferState> LimitedOffers = new();
public long DailyShopNextRefreshUnix;
protected override string PrefsKey => "STORE_DATA";
// --------------------------------------------------------------------
// 🚫 REMOVE ADS
// --------------------------------------------------------------------
public bool HasRemovedAds => HasPurchased(REMOVE_ADS_PRODUCT_ID);
private static long NowUnix()
{
return DateTimeOffset.UtcNow.ToUnixTimeSeconds();
}
private ProductPurchase FindPurchase(string pid)
{
return Purchases.Find(p => p.ProductId == pid);
}
private LimitedOfferState FindOffer(string oid)
{
return LimitedOffers.Find(o => o.OfferId == oid);
}
// --------------------------------------------------------------------
// 🧾 PURCHASE MANAGEMENT
// --------------------------------------------------------------------
public void MarkPurchased(string productId, int count = 1, StoreCategory type = StoreCategory.UnknownPacks)
{
if (string.IsNullOrEmpty(productId))
{
Debug.LogWarning("[StoreData] Tried to mark a purchase with null/empty productId.");
return;
}
var existing = FindPurchase(productId);
if (existing == null)
{
Purchases.Add(new ProductPurchase(productId, Mathf.Max(1, count), NowUnix(), type));
}
else
{
existing.PurchaseCount += Mathf.Max(1, count);
existing.LastPurchaseUnix = NowUnix();
existing.StoreCategory = type;
}
Save();
Debug.Log($"[StoreData] ✅ Purchase marked → {productId} ({type})");
}
public int GetPurchaseCount(string productId)
{
return FindPurchase(productId)?.PurchaseCount ?? 0;
}
public bool HasPurchased(string productId)
{
return GetPurchaseCount(productId) > 0;
}
public int GetTotalPurchased(StoreCategory type)
{
var total = 0;
foreach (var p in Purchases)
if (p.StoreCategory == type)
total += p.PurchaseCount;
return total;
}
public bool HasPurchasedType(StoreCategory type)
{
return Purchases.Exists(p => p.StoreCategory == type);
}
public void ResetPurchases(StoreCategory type)
{
Purchases.RemoveAll(p => p.StoreCategory == type);
Save();
Debug.Log($"[StoreData] 🔄 Reset purchases of type {type}");
}
public void SetRemoveAds(bool purchased)
{
if (purchased)
MarkPurchased(REMOVE_ADS_PRODUCT_ID, 1, StoreCategory.RemoveAdsPacks);
else
Purchases.RemoveAll(p => p.ProductId == REMOVE_ADS_PRODUCT_ID);
Save();
Debug.Log($"[StoreData] 🧩 Remove Ads state updated → {purchased}");
}
// --------------------------------------------------------------------
// 🕒 DAILY SHOP
// --------------------------------------------------------------------
public void SetDailyShopRefresh(long nextUnix)
{
DailyShopNextRefreshUnix = nextUnix;
Save();
}
public bool NeedsDailyShopRefresh(long nowUnix)
{
return nowUnix >= DailyShopNextRefreshUnix;
}
public void ForceRefreshNow(int hoursToNext = 24)
{
DailyShopNextRefreshUnix = NowUnix() + hoursToNext * 3600L;
Save();
}
// --------------------------------------------------------------------
// 🎁 LIMITED OFFERS
// --------------------------------------------------------------------
public void UpsertOffer(string offerId, long expireUnix = 0)
{
var offer = FindOffer(offerId);
if (offer == null)
LimitedOffers.Add(new LimitedOfferState
{
OfferId = offerId,
Seen = false,
Purchased = false,
ExpireUnix = expireUnix
});
else
offer.ExpireUnix = expireUnix;
Save();
}
public void MarkOfferSeen(string offerId)
{
var offer = FindOffer(offerId);
if (offer == null) return;
offer.Seen = true;
Save();
}
public bool IsOfferActive(string offerId)
{
var offer = FindOffer(offerId);
return offer != null && offer.IsActive(NowUnix());
}
public void MarkOfferPurchased(string offerId)
{
var offer = FindOffer(offerId);
if (offer == null) return;
offer.Purchased = true;
Save();
}
}
}