using Dalamud.Hooking; using Dalamud.IoC; using Dalamud.Plugin; using Dalamud.Utility.Signatures; using Ktisis.Structs.Env; using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Numerics; using System.Reflection; namespace VoidBox; public record struct EnvCollectionEntry(SavedEnv Env, bool IsBuiltin); public sealed class EnvCollection : IList { private static readonly JsonSerializer _jsonSerializer = JsonSerializer.CreateDefault(); public static List Config => Service.Config.Envs; private readonly List _builtin; private readonly List _copy = []; public EnvCollection() { var asm = Assembly.GetExecutingAssembly(); var path = $"{asm.GetName().Name}.Assets.BuiltinEnvs.json"; try { using var stream = asm.GetManifestResourceStream(path) ?? throw new FileNotFoundException(path); using var streamReader = new StreamReader(stream); using var reader = new JsonTextReader(streamReader); _builtin = _jsonSerializer.Deserialize>(reader) ?? throw new NullReferenceException(); } catch (Exception e) { Service.PluginLog.Error($"Failed to parse builtin envs: {e}"); _builtin = []; } _builtin.Insert(0, SavedEnv.Unchanged); } public EnvCollectionEntry this[int index] { get { if (index < _builtin.Count) { return new(_builtin[index], true); } index -= _builtin.Count; return new(Config[index], false); } set => throw new NotSupportedException(); } public IReadOnlyList Builtin => _builtin; public int Count => throw new NotImplementedException(); public bool IsReadOnly => throw new NotImplementedException(); public void Add(EnvCollectionEntry item) { throw new NotSupportedException(); } public void Clear() { throw new NotSupportedException(); } public bool Contains(EnvCollectionEntry item) { return item.IsBuiltin ? _builtin.Contains(item.Env) : Config.Contains(item.Env); } public void CopyTo(EnvCollectionEntry[] array, int arrayIndex) { throw new NotImplementedException(); } public IEnumerator GetEnumerator() { foreach (var env in _builtin) { yield return new(env, true); } foreach (var env in Config) { yield return new(env, false); } } public int IndexOf(EnvCollectionEntry item) { if (item.IsBuiltin) { var index = _builtin.IndexOf(item.Env); if (index != -1) { return index; } } else { var index = Config.IndexOf(item.Env); if (index != -1) { return _builtin.Count + index; } } return -1; } public void Insert(int index, EnvCollectionEntry item) { throw new NotSupportedException(); } public bool Remove(EnvCollectionEntry item) { throw new NotSupportedException(); } public void RemoveAt(int index) { throw new NotSupportedException(); } public IEnumerable Copy() { _copy.Clear(); foreach (var env in this) { _copy.Add(env); } return _copy; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } }