sinmai-mods/CachedDataManager/Manager/patch_DataManager.cs
2024-05-22 22:31:19 +07:00

206 lines
9.0 KiB
C#

// ReSharper disable CheckNamespace
// ReSharper disable InconsistentNaming
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml.Serialization;
namespace Manager;
public class patch_DataManager : DataManager
{
private const string _cacheDirectory = "dataCache";
[Serializable]
[XmlType(TypeName="KeyValuePair")]
public class SerializableKeyValuePair<TK, TV>
{
public TK Key;
public TV Value;
}
private static Dictionary<string, T> LoadCacheFile<T>(string fileName)
{
if (!File.Exists(fileName))
{
return new Dictionary<string, T>();
}
using var fs = File.OpenRead(fileName);
var serializer = new XmlSerializer(typeof(List<SerializableKeyValuePair<string, T>>));
var entries = (List<SerializableKeyValuePair<string, T>>)serializer.Deserialize(fs);
return entries.ToDictionary(e => e.Key, e => e.Value);
}
private static void SaveCacheFile<T>(string destination, Dictionary<string, T> collection)
{
if (collection == null)
{
return;
}
using var fs = File.Open(destination, FileMode.Create);
var serializer = new XmlSerializer(typeof(List<SerializableKeyValuePair<string, T>>));
serializer.Serialize(
fs,
collection
.Select(kvp => new SerializableKeyValuePair<string, T> { Key = kvp.Key, Value = kvp.Value })
.ToList());
}
private static void SaveCache()
{
if (!Directory.Exists(_cacheDirectory))
{
Directory.CreateDirectory(_cacheDirectory);
}
SaveCacheFile(Path.Combine(_cacheDirectory, "RomConfigs.xml"), Cache.RomConfigs);
SaveCacheFile(Path.Combine(_cacheDirectory, "DataConfigs.xml"), Cache.DataConfigs);
SaveCacheFile(Path.Combine(_cacheDirectory, "Charas.xml"), Cache.Charas);
SaveCacheFile(Path.Combine(_cacheDirectory, "CharaAwakes.xml"), Cache.CharaAwakes);
SaveCacheFile(Path.Combine(_cacheDirectory, "CharaGenres.xml"), Cache.CharaGenres);
SaveCacheFile(Path.Combine(_cacheDirectory, "Events.xml"), Cache.Events);
SaveCacheFile(Path.Combine(_cacheDirectory, "Musics.xml"), Cache.Musics);
SaveCacheFile(Path.Combine(_cacheDirectory, "MusicGenres.xml"), Cache.MusicGenres);
SaveCacheFile(Path.Combine(_cacheDirectory, "MusicGroups.xml"), Cache.MusicGroups);
SaveCacheFile(Path.Combine(_cacheDirectory, "MusicVersions.xml"), Cache.MusicVersions);
SaveCacheFile(Path.Combine(_cacheDirectory, "MusicNameSorts.xml"), Cache.MusicNameSorts);
SaveCacheFile(Path.Combine(_cacheDirectory, "MusicClearRanks.xml"), Cache.MusicClearRanks);
SaveCacheFile(Path.Combine(_cacheDirectory, "MusicDifficultys.xml"), Cache.MusicDifficultys);
SaveCacheFile(Path.Combine(_cacheDirectory, "MusicLevels.xml"), Cache.MusicLevels);
SaveCacheFile(Path.Combine(_cacheDirectory, "TournamentMusics.xml"), Cache.TournamentMusics);
SaveCacheFile(Path.Combine(_cacheDirectory, "Courses.xml"), Cache.Courses);
SaveCacheFile(Path.Combine(_cacheDirectory, "CourseModes.xml"), Cache.CourseModes);
SaveCacheFile(Path.Combine(_cacheDirectory, "LoginBonuses.xml"), Cache.LoginBonuses);
SaveCacheFile(Path.Combine(_cacheDirectory, "Maps.xml"), Cache.Maps);
SaveCacheFile(Path.Combine(_cacheDirectory, "MapColors.xml"), Cache.MapColors);
SaveCacheFile(Path.Combine(_cacheDirectory, "MapTreasures.xml"), Cache.MapTreasures);
SaveCacheFile(Path.Combine(_cacheDirectory, "MapBonusMusics.xml"), Cache.MapBonusMusics);
SaveCacheFile(Path.Combine(_cacheDirectory, "MapOtomodachis.xml"), Cache.MapOtomodachis);
SaveCacheFile(Path.Combine(_cacheDirectory, "MapSilhouettes.xml"), Cache.MapSilhouettes);
SaveCacheFile(Path.Combine(_cacheDirectory, "MapTitles.xml"), Cache.MapTitles);
SaveCacheFile(Path.Combine(_cacheDirectory, "ItemMusics.xml"), Cache.ItemMusics);
SaveCacheFile(Path.Combine(_cacheDirectory, "Icons.xml"), Cache.Icons);
SaveCacheFile(Path.Combine(_cacheDirectory, "Plates.xml"), Cache.Plates);
SaveCacheFile(Path.Combine(_cacheDirectory, "Titles.xml"), Cache.Titles);
SaveCacheFile(Path.Combine(_cacheDirectory, "Partners.xml"), Cache.Partners);
SaveCacheFile(Path.Combine(_cacheDirectory, "Frames.xml"), Cache.Frames);
SaveCacheFile(Path.Combine(_cacheDirectory, "Tickets.xml"), Cache.Tickets);
SaveCacheFile(Path.Combine(_cacheDirectory, "CollectionTypes.xml"), Cache.CollectionTypes);
SaveCacheFile(Path.Combine(_cacheDirectory, "CollectionGenres.xml"), Cache.CollectionGenres);
SaveCacheFile(Path.Combine(_cacheDirectory, "PhotoFrames.xml"), Cache.PhotoFrames);
SaveCacheFile(Path.Combine(_cacheDirectory, "Informations.xml"), Cache.Informations);
SaveCacheFile(Path.Combine(_cacheDirectory, "Udemaes.xml"), Cache.Udemaes);
SaveCacheFile(Path.Combine(_cacheDirectory, "Classes.xml"), Cache.Classes);
SaveCacheFile(Path.Combine(_cacheDirectory, "UdemaeBosses.xml"), Cache.UdemaeBosses);
SaveCacheFile(Path.Combine(_cacheDirectory, "UdemaeSeasonEvents.xml"), Cache.UdemaeSeasonEvents);
SaveCacheFile(Path.Combine(_cacheDirectory, "UdemaeSeasonRewards.xml"), Cache.UdemaeSeasonRewards);
SaveCacheFile(Path.Combine(_cacheDirectory, "Cards.xml"), Cache.Cards);
SaveCacheFile(Path.Combine(_cacheDirectory, "CardCharas.xml"), Cache.CardCharas);
SaveCacheFile(Path.Combine(_cacheDirectory, "CardTypes.xml"), Cache.CardTypes);
SaveCacheFile(Path.Combine(_cacheDirectory, "WeekdayBonuses.xml"), Cache.WeekdayBonuses);
SaveCacheFile(Path.Combine(_cacheDirectory, "Challenges.xml"), Cache.Challenges);
SaveCacheFile(Path.Combine(_cacheDirectory, "MusicRankings.xml"), Cache.MusicRankings);
SaveCacheFile(Path.Combine(_cacheDirectory, "MusicSorts.xml"), Cache.MusicSorts);
SaveCacheFile(Path.Combine(_cacheDirectory, "LoginBonusSorts.xml"), Cache.LoginBonusSorts);
SaveCacheFile(Path.Combine(_cacheDirectory, "IconSorts.xml"), Cache.IconSorts);
SaveCacheFile(Path.Combine(_cacheDirectory, "PlateSorts.xml"), Cache.PlateSorts);
SaveCacheFile(Path.Combine(_cacheDirectory, "TitleSorts.xml"), Cache.TitleSorts);
SaveCacheFile(Path.Combine(_cacheDirectory, "PartnerSorts.xml"), Cache.PartnerSorts);
SaveCacheFile(Path.Combine(_cacheDirectory, "FrameSorts.xml"), Cache.FrameSorts);
SaveCacheFile(Path.Combine(_cacheDirectory, "TicketSorts.xml"), Cache.TicketSorts);
SaveCacheFile(Path.Combine(_cacheDirectory, "CollectionGenreSorts.xml"), Cache.CollectionGenreSorts);
SaveCacheFile(Path.Combine(_cacheDirectory, "CharaSorts.xml"), Cache.CharaSorts);
SaveCacheFile(Path.Combine(_cacheDirectory, "CharaGenreSorts.xml"), Cache.CharaGenreSorts);
}
private static extern bool orig_Deserialize<T>(string filePath, out T dsr) where T : new();
private static bool Deserialize<T>(string filePath, out T dsr) where T : new()
{
var fileName = Path.GetFileName(filePath);
var collectionName = fileName switch
{
"UdemaeBoss.xml" => "UdemaeBosses",
"Class.xml" => "Classes",
"LoginBonus.xml" => "LoginBonuses",
"ScoreRanking.xml" => "TournamentMusics",
"Holiday.xml" => "WeekdayBonuses",
_ => fileName.Replace(".xml", "s"),
};
var collectionField =
typeof(CachedDataManager.SerializationCache).GetField(collectionName, BindingFlags.Public | BindingFlags.Instance);
if (collectionField == null)
{
System.Console.WriteLine("[CachedDataManager] [WARN] Could not find suitable collection for {0} (tried name {1})", fileName, collectionName);
return orig_Deserialize(filePath, out dsr);
}
try
{
var collection = (Dictionary<string, T>)collectionField.GetValue(Cache);
if (collection == null)
{
collection = LoadCacheFile<T>(Path.Combine(_cacheDirectory, $"{collectionName}.xml"));
collectionField.SetValue(Cache, collection);
}
if (collection.TryGetValue(filePath, out dsr))
{
return true;
}
if (!orig_Deserialize(filePath, out dsr))
{
return false;
}
collection.Add(filePath, dsr);
_cacheBusted = true;
return true;
}
catch (Exception e)
{
System.Console.WriteLine("[CachedDataManager] [ERROR] Could not load from cache: {0}", e);
return orig_Deserialize(filePath, out dsr);
}
}
private extern bool orig_IsLoaded();
public new bool IsLoaded()
{
var loaded = orig_IsLoaded();
if (!loaded || !_cacheBusted)
{
return loaded;
}
try
{
SaveCache();
}
catch (Exception e)
{
System.Console.WriteLine("[CachedDataManager] [ERROR] Could not save to cache: {0}", e);
}
_cacheBusted = false;
return true;
}
private static readonly CachedDataManager.SerializationCache Cache = new();
private static bool _cacheBusted;
}