ArcacheLoader.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using SongCore.Utilities;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. namespace SongCore.Arcache
  8. {
  9. public static class ArcacheLoader
  10. {
  11. private static readonly Lz4ArchiveReader JsonArchive;
  12. private static readonly Dictionary<string, float> OggLengthDictionary = new();
  13. static ArcacheLoader()
  14. {
  15. var basePath = CustomLevelPathHelper.customLevelsDirectoryPath;
  16. var jsonArcBase = Path.Combine(basePath, "bsa");
  17. var lengthCache = Path.Combine(basePath, "bslp");
  18. Logging.logger.Info("ArcacheLoader: Loading jsonArc");
  19. JsonArchive = new Lz4ArchiveReader(jsonArcBase, true);
  20. Logging.logger.Info("ArcacheLoader: Loading oggLengthCache");
  21. OggLengthDictionary = LengthPack.Read(lengthCache);
  22. Logging.logger.Info($"ArcacheLoader: Load finished. Json Archive:{JsonArchive.Entries.Count}, ogg Length:{OggLengthDictionary.Count}");
  23. }
  24. public static void InitFastLoad()
  25. {
  26. //Just fire static ctor
  27. }
  28. private static string ConvertFullPathToArchivePath(string fullPath)
  29. {
  30. // assume full path is "...\ffde (Country Rounds - EpicTroller)\Info.dat"
  31. // ^ ^
  32. var parts = fullPath.Split(new[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries);
  33. var vPath = $"{parts[parts.Length - 2]}/{parts[parts.Length - 1]}";
  34. return vPath.ToLower();
  35. }
  36. public static string ReadJson(string fullPath)
  37. {
  38. var vPath = ConvertFullPathToArchivePath(fullPath);
  39. if (JsonArchive.Entries.TryGetValue(vPath, out var entry)) return JsonArchive.ReadText(entry, Encoding.UTF8);
  40. Logging.Log($"Archive[Json] Cache miss:{fullPath} -- {vPath}");
  41. return File.ReadAllText(fullPath);
  42. }
  43. public static byte[] ReadAllBytes(string fullPath)
  44. {
  45. var vPath = ConvertFullPathToArchivePath(fullPath);
  46. if (JsonArchive.Entries.TryGetValue(vPath, out var entry)) return JsonArchive.ReadData(entry);
  47. Logging.Log($"Archive[Data] Cache miss:{fullPath} -- {vPath}");
  48. return File.ReadAllBytes(fullPath);
  49. }
  50. public static bool GetCachedOggLength(string fullPath, out float len)
  51. {
  52. var vPath = ConvertFullPathToArchivePath(fullPath);
  53. if (OggLengthDictionary.TryGetValue(vPath, out var data))
  54. {
  55. len = data;
  56. return true;
  57. }
  58. Logging.Log($"Archive[OggLen] Cache miss:{fullPath} -- {vPath}");
  59. len = -1;
  60. return false;
  61. }
  62. public static string[] ExtractCustomLevelFoldersFromArchive()
  63. {
  64. return JsonArchive.Entries.Keys
  65. .Select(p => Path.Combine(CustomLevelPathHelper.customLevelsDirectoryPath, p.Split('/')[0]).ToLower())
  66. .Distinct().ToArray();
  67. }
  68. public static bool ArchiveExists(string fullPath)
  69. {
  70. var vPath = ConvertFullPathToArchivePath(fullPath);
  71. var archiveExists = JsonArchive.Entries.ContainsKey(vPath);
  72. if (archiveExists == false)
  73. {
  74. if (File.Exists(fullPath))
  75. {
  76. Logging.logger.Info($"Arcache: Provide by real FS {fullPath}");
  77. return true;
  78. }
  79. Logging.logger.Warn($"Arcache: file not exist? {fullPath} -> {vPath}");
  80. }
  81. return archiveExists;
  82. }
  83. public static string ExtractParentDirectoryName(string fullPath)
  84. {
  85. return Path.GetFileName(Path.GetDirectoryName(fullPath))?.ToLower();
  86. }
  87. }
  88. }