using System.Collections.Generic; using System.Text; using KitsuneCafe.Sys; using KitsuneCafe.Sys.Attributes; using MessagePack; using MessagePack.Formatters; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; namespace KitsuneCafe.ItemSystem { public class ItemSystemResolver : IFormatterResolver { public static ItemSystemResolver Instance = new(); private readonly ItemFormatter itemFormatter = new(); public IMessagePackFormatter GetFormatter() { if (typeof(T) == typeof(Item)) { return (IMessagePackFormatter)itemFormatter; } return null; } } public class ItemFormatter : IMessagePackFormatter { private readonly Dictionary items = new(); private readonly Dictionary addresses = new(); public ItemFormatter() { var handle = Addressables.LoadResourceLocationsAsync( new string[] { "Item" }, Addressables.MergeMode.Union ); handle.WaitForCompletion(); var ops = new List(); foreach (var location in handle.Result) { var assetHandle = Addressables.LoadAssetAsync(location); assetHandle.Completed += item => { items.Add(location.PrimaryKey, item.Result); addresses.Add(item.Result, location.PrimaryKey); }; ops.Add(assetHandle); } var groupOp = Addressables.ResourceManager.CreateGenericGroupOperation(ops); groupOp.WaitForCompletion(); Addressables.Release(handle); } public Item Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) { if (reader.TryReadNil()) { return null; } var address = reader.ReadString(); return items[address]; } public void Serialize(ref MessagePackWriter writer, Item value, MessagePackSerializerOptions options) { if (value == null) { writer.WriteNil(); return; } var address = addresses[value]; var bytes = Encoding.ASCII.GetBytes(address); writer.WriteString(bytes); } } [CreateAssetMenu(menuName = KitsuneCafeMenu.Item + "Item")] public class Item : BaseItem, IStackable { [SerializeField] private bool stackable; public bool IsStackable => stackable; [SerializeField, ShowIf("stackable")] private int maxStackCount = 1; public int MaxStackCount => maxStackCount; private void Reset() { GenerateNewId(); } } }