using SVSim.Database.Enums; using SVSim.Database.Models; using SVSim.Database.Models.Config; using SVSim.Database.Repositories.Card; using SVSim.Database.Repositories.Collectibles; namespace SVSim.Database.Services; public class ViewerEntitlements : IViewerEntitlements { private readonly IGameConfigService _config; private readonly ICardRepository _cards; private readonly ICollectionRepository _collection; public ViewerEntitlements(IGameConfigService config, ICardRepository cards, ICollectionRepository collection) { _config = config; _cards = cards; _collection = collection; } private FreeplayConfig Cfg => _config.Get(); public bool IsFreeplay => Cfg.Enabled; public long EffectiveBalance(Viewer viewer, SpendCurrency currency) { var cfg = Cfg; if (cfg.Enabled && currency != SpendCurrency.SpotPoint) return checked((long)cfg.CurrencyAmount); return currency switch { SpendCurrency.Crystal => (long)viewer.Currency.Crystals, SpendCurrency.Rupee => (long)viewer.Currency.Rupees, SpendCurrency.RedEther => (long)viewer.Currency.RedEther, SpendCurrency.SpotPoint => (long)viewer.Currency.SpotPoints, _ => throw new ArgumentOutOfRangeException(nameof(currency)), }; } public bool OwnsCard(Viewer viewer, long cardId) => Cfg.Enabled || viewer.Cards.Any(c => c.Card.Id == cardId && c.Count > 0); public bool OwnsCosmetic(Viewer viewer, CosmeticType type, int id) { if (Cfg.Enabled) return true; return type switch { CosmeticType.Sleeve => viewer.Sleeves.Any(s => s.Id == id), CosmeticType.Emblem => viewer.Emblems.Any(e => e.Id == id), CosmeticType.Degree => viewer.Degrees.Any(d => d.Id == id), CosmeticType.Skin => viewer.LeaderSkins.Any(s => s.Id == id), CosmeticType.MyPageBG => viewer.MyPageBackgrounds.Any(m => m.Id == id), _ => false, }; } public async Task> EffectiveOwnedCardsAsync(Viewer viewer, CancellationToken ct = default) { var defaults = await _cards.GetDefaultCards(); var defaultIds = defaults.Select(c => c.Id).ToHashSet(); var cfg = Cfg; if (cfg.Enabled) { var all = await _cards.GetAll(onlyCollectible: true); return all .Select(c => new OwnedCardEntry { Card = c, Count = cfg.CardCopies, IsProtected = defaultIds.Contains(c.Id), }) .ToList(); } var owned = viewer.Cards.Where(c => c.Count > 0 && !defaultIds.Contains(c.Card.Id)); return owned .Concat(defaults.Select(bc => new OwnedCardEntry { Card = bc, Count = 3, IsProtected = true })) .ToList(); } public async Task EffectiveCosmeticsAsync(Viewer viewer, CancellationToken ct = default) { var allSkins = await _collection.GetLeaderSkins(); if (Cfg.Enabled) { return new EffectiveCosmetics( await _collection.GetAllSleeveIds(), await _collection.GetAllEmblemIds(), await _collection.GetAllDegreeIds(), await _collection.GetAllMyPageBackgroundIds(), allSkins, allSkins.Select(s => s.Id).ToHashSet()); } return new EffectiveCosmetics( viewer.Sleeves.Select(s => s.Id).ToList(), viewer.Emblems.Select(e => e.Id).ToList(), viewer.Degrees.Select(d => d.Id).ToList(), viewer.MyPageBackgrounds.Select(m => m.Id).ToList(), allSkins, viewer.LeaderSkins.Select(s => s.Id).ToHashSet()); } }