using System; using System.Collections; using System.Collections.Generic; using System.Linq; using BITKit; using BITKit.Modification; using Cysharp.Threading.Tasks; using Newtonsoft.Json; using UnityEngine; using YooAsset; namespace BITFALL.Cosmetic { [Serializable] public struct CosmeticServiceSingleton:ICosmeticService { public ICosmetic[] Cosmetics=>CosmeticService.Singleton.Cosmetics; public event Action OnCosmeticsChanged { add => CosmeticService.Singleton.OnCosmeticsChanged += value; remove => CosmeticService.Singleton.OnCosmeticsChanged -= value; } public IDictionary Modifies => CosmeticService.Singleton.Modifies; public IDictionary Modified => CosmeticService.Singleton.Modified; public void Add(IModifyElement modify, object obj)=>CosmeticService.Singleton.Add(modify,obj); public void Remove(IModifyElement modify, out object obj)=>CosmeticService.Singleton.Remove(modify,out obj); } public class CosmeticService : MonoBehaviour,ICosmeticService { [DictionaryReferenceConfig(nameof(Cosmetic_Saved_Layout))] public const string Cosmetic_Saved_Layout= "Cosmetic_Saved_Layout"; internal static ICosmeticService Singleton { get; private set; } [SerializeField] private AssetableCosmetic[] initialCosmetics; public ICosmetic[] Cosmetics { get; set; } = Array.Empty(); public event Action OnCosmeticsChanged; private void Awake() { Singleton = this; } private async void Start() { Cosmetics = initialCosmetics.OfType().ToArray(); if (PlayerPrefs.HasKey(Cosmetic_Saved_Layout)) { var array = JsonConvert.DeserializeObject(PlayerPrefs.GetString(Cosmetic_Saved_Layout)); foreach (var path in array) { try { var asyncHandle = YooAssets.LoadAssetAsync(path); await asyncHandle; if (destroyCancellationToken.IsCancellationRequested) return; var so = asyncHandle.AssetObject.As(); _modifyManager.Modified.Add(so.Type, so); } catch (Exception e) { BIT4Log.LogException(e); } } } OnCosmeticsChanged?.Invoke(); destroyCancellationToken.Register(() => { var array = _modifyManager.Modified.Values.Select(x => x.As().AddressablePath).ToArray(); PlayerPrefs.SetString(Cosmetic_Saved_Layout, JsonConvert.SerializeObject(array)); PlayerPrefs.Save(); }); } private readonly IModifyManager _modifyManager = new ModifyManager(); public IDictionary Modifies => _modifyManager.Modifies; public IDictionary Modified => _modifyManager.Modified; public void Add(IModifyElement modify, object obj) { if (Modified.TryGetValue(modify, out var x)) { Modified.Remove(modify); } _modifyManager.Add(modify, obj); OnCosmeticsChanged?.Invoke(); } public void Remove(IModifyElement modify, out object obj) { _modifyManager.Remove(modify, out obj); OnCosmeticsChanged?.Invoke(); } } }