using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using static System.Text.Json.JsonSerializer; namespace AnotherReplayReader { public sealed class Cache { public static string OldCacheDirectory => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "RA3Bar.Lanyi.AnotherReplayReader"); public static string CacheDirectory => App.LibsFolder; public static string CacheFilePath => Path.Combine(CacheDirectory, "AnotherReplayReader.cache"); private readonly ConcurrentDictionary _storage = new(); public Task Initialization { get; } public Cache() { Initialization = Task.Run(async () => { try { if (!Directory.Exists(CacheDirectory)) { Directory.CreateDirectory(CacheDirectory); } try { var old = new DirectoryInfo(OldCacheDirectory); if (old.Exists) { foreach (var file in old.EnumerateFiles()) { try { file.MoveTo(Path.Combine(CacheDirectory, file.Name)); } catch { } } try { old.Delete(); } catch { } } } catch { } using var cacheStream = File.OpenRead(CacheFilePath); var futureCache = DeserializeAsync>(cacheStream).ConfigureAwait(false); if (await futureCache is not { } cached) { return; } foreach (var kv in cached) { _storage.TryAdd(kv.Key, kv.Value); } } catch { } }); } public T GetOrDefault(string key, T defaultValue) { try { if (_storage.TryGetValue(key, out var valueString)) { return Deserialize(valueString) ?? defaultValue; } } catch { } return defaultValue; } public void Set(string key, T value) { try { _storage[key] = Serialize(value); } catch { } } public void SetValues(params (string Key, object Value)[] values) { try { foreach (var (key, value) in values) { _storage[key] = Serialize(value); } } catch { } } public void Remove(string key) { _storage.TryRemove(key, out _); } public async Task Save() { try { using var cacheStream = File.Open(CacheFilePath, FileMode.Create, FileAccess.Write); await SerializeAsync(cacheStream, _storage).ConfigureAwait(false); } catch { } } } }