LocalCustomLevelProvider.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using BeatLyrics.Common;
  2. using BeatLyrics.Tool.Models;
  3. using BeatLyrics.Tool.Utils;
  4. using Newtonsoft.Json;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12. namespace BeatLyrics.Tool.DataProvider.BeatMaps
  13. {
  14. internal static class LocalCustomLevelProvider
  15. {
  16. public static LevelInfo[] GetAlLevelInfos(Action<int, int> reportProgress = null)
  17. {
  18. var bsDir = DirProvider.BeatSaberDir;
  19. if (null == bsDir) throw new InvalidOperationException("`BeatSaberDir' NotFound");
  20. var levelsDir = Path.Combine(bsDir, "Beat Saber_Data", "CustomLevels");
  21. if (false == Directory.Exists(levelsDir)) throw new DirectoryNotFoundException($"Dir `{levelsDir}' NotFound");
  22. var dirs = Directory.GetDirectories(levelsDir);
  23. var ret = new List<LevelInfo>(dirs.Length);
  24. var loadedCount = 0;
  25. Parallel.For(0, dirs.Length, index =>
  26. {
  27. var dir = dirs[index];
  28. var item = new LevelInfo { Directory = dir, DirectoryTime = new DirectoryInfo(dir).CreationTime };
  29. try
  30. {
  31. var infoPath = Path.Combine(dir, "info.dat");
  32. if (File.Exists(infoPath))
  33. {
  34. var toHashData = new MemoryStream();
  35. var infoData = File.ReadAllBytes(infoPath);
  36. toHashData.Write(infoData, 0, infoData.Length);
  37. var infoJson = JsonConvert.DeserializeAnonymousType(Encoding.UTF8.GetString(infoData), new
  38. {
  39. _coverImageFilename = (string)null,
  40. _songFilename = (string)null,
  41. _songName = (string)null,
  42. _songSubName = (string)null,
  43. _songAuthorName = (string)null,
  44. _levelAuthorName = (string)null,
  45. _difficultyBeatmapSets = new[]
  46. {
  47. new
  48. {
  49. _difficultyBeatmaps=new []
  50. {
  51. new
  52. {
  53. _beatmapFilename=(string)null
  54. }
  55. }
  56. }
  57. },
  58. });
  59. item.CoverPath = Path.Combine(dir, infoJson._coverImageFilename);
  60. item.MediaPath = Path.Combine(dir, infoJson._songFilename);
  61. item.SongName = infoJson._songName;
  62. item.SongSubName = infoJson._songSubName;
  63. item.SongAuthor = infoJson._songAuthorName;
  64. item.LevelAuthor = infoJson._levelAuthorName;
  65. var toHash =
  66. infoJson._difficultyBeatmapSets.SelectMany(p =>
  67. p._difficultyBeatmaps.Select(r => File.ReadAllBytes(Path.Combine(dir, r._beatmapFilename))))
  68. .Aggregate(toHashData, (n, p) =>
  69. {
  70. n.Write(p, 0, p.Length);
  71. return n;
  72. });
  73. item.Hash = Hasher.Sha1Hex(toHash.ToArray());
  74. item.ReloadLocalLyricInfo();
  75. item.IsValid = true;
  76. }
  77. else
  78. {
  79. item.Error = "file `info.dat' not found";
  80. }
  81. }
  82. catch (Exception e)
  83. {
  84. item.Error = e.ToString();
  85. }
  86. ret.Add(item);
  87. reportProgress?.Invoke(dirs.Length, Interlocked.Increment(ref loadedCount));
  88. });
  89. return ret.ToArray();
  90. }
  91. public static void ReloadLocalLyricInfo(this LevelInfo item)
  92. {
  93. var defaultFilePath = DirProvider.GetDefaultFile(item.Hash);
  94. var defaultFileName = "";
  95. if (File.Exists(defaultFilePath)) defaultFileName = File.ReadAllText(defaultFilePath);
  96. var lsDir = DirProvider.GetLyricDir(item.Hash);
  97. if (Directory.Exists(lsDir))
  98. {
  99. item.LocalLyrics = Directory.GetFiles(lsDir).Select(p =>
  100. {
  101. var fileName = Path.GetFileName(p);
  102. return new LocalLyricInfo
  103. {
  104. FileName = fileName,
  105. IsDefault = fileName == defaultFileName
  106. };
  107. }).ToArray();
  108. }
  109. }
  110. }
  111. }