Collections.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. using Newtonsoft.Json;
  2. using SongCore.Data;
  3. using SongCore.Utilities;
  4. using IPA.Utilities;
  5. using System;
  6. using System.Collections.Concurrent;
  7. using System.Collections.Generic;
  8. using System.IO;
  9. using System.Linq;
  10. using UnityEngine;
  11. namespace SongCore
  12. {
  13. public static class Collections
  14. {
  15. internal static CustomBeatmapLevelPack WipLevelPack;
  16. internal static string dataPath = Path.Combine(IPA.Utilities.UnityGame.InstallPath, "UserData", "SongCore", "SongCoreExtraData.dat");
  17. internal static ConcurrentDictionary<string, ExtraSongData> customSongsData = new ConcurrentDictionary<string, ExtraSongData>();
  18. internal static ConcurrentDictionary<string, string> levelHashDictionary = new ConcurrentDictionary<string, string>();
  19. internal static ConcurrentDictionary<string, List<string>> hashLevelDictionary = new ConcurrentDictionary<string, List<string>>();
  20. private static List<string> _capabilities = new List<string>();
  21. public static System.Collections.ObjectModel.ReadOnlyCollection<string> capabilities
  22. {
  23. get { return _capabilities.AsReadOnly(); }
  24. }
  25. private static List<BeatmapCharacteristicSO> _customCharacteristics = new List<BeatmapCharacteristicSO>();
  26. public static System.Collections.ObjectModel.ReadOnlyCollection<BeatmapCharacteristicSO> customCharacteristics
  27. {
  28. get { return _customCharacteristics.AsReadOnly(); }
  29. }
  30. public static bool songWithHashPresent(string hash)
  31. {
  32. if (hashLevelDictionary.ContainsKey(hash.ToUpper()))
  33. return true;
  34. else
  35. return false;
  36. }
  37. public static string hashForLevelID(string levelID)
  38. {
  39. if (levelHashDictionary.TryGetValue(levelID, out var hash))
  40. return hash;
  41. return "";
  42. }
  43. public static List<string> levelIDsForHash(string hash)
  44. {
  45. if (hashLevelDictionary.TryGetValue(hash.ToUpper(), out var songs))
  46. return songs;
  47. return new List<string>();
  48. }
  49. public static void AddSong(string levelID, string path)
  50. {
  51. if (!customSongsData.ContainsKey(levelID))
  52. customSongsData.TryAdd(levelID, new ExtraSongData(levelID, path));
  53. // Utilities.Logging.Log("Entry: :" + levelID + " " + customSongsData.Count);
  54. }
  55. public static ExtraSongData RetrieveExtraSongData(string levelID, string loadIfNullPath = "")
  56. {
  57. // Logging.Log(levelID);
  58. // Logging.Log(loadIfNullPath);
  59. if (customSongsData.TryGetValue(levelID, out var songData))
  60. return songData;
  61. if (!string.IsNullOrWhiteSpace(loadIfNullPath))
  62. {
  63. AddSong(levelID, loadIfNullPath);
  64. if (customSongsData.TryGetValue(levelID, out songData))
  65. return songData;
  66. }
  67. return null;
  68. }
  69. public static ExtraSongData.DifficultyData RetrieveDifficultyData(IDifficultyBeatmap beatmap)
  70. {
  71. ExtraSongData songData = null;
  72. if (beatmap.level is CustomPreviewBeatmapLevel)
  73. {
  74. var customLevel = beatmap.level as CustomPreviewBeatmapLevel;
  75. songData = RetrieveExtraSongData(Hashing.GetCustomLevelHash(customLevel), customLevel.customLevelPath);
  76. }
  77. if (songData == null) return null;
  78. ExtraSongData.DifficultyData diffData = songData._difficulties.FirstOrDefault(x => x._difficulty == beatmap.difficulty && (x._beatmapCharacteristicName == beatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.characteristicNameLocalizationKey || x._beatmapCharacteristicName == beatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName));
  79. return diffData;
  80. }
  81. public static void LoadExtraSongData()
  82. {
  83. customSongsData = Newtonsoft.Json.JsonConvert.DeserializeObject<ConcurrentDictionary<string, ExtraSongData>>(File.ReadAllText(dataPath));
  84. if (customSongsData == null)
  85. customSongsData = new ConcurrentDictionary<string, ExtraSongData>();
  86. }
  87. public static void SaveExtraSongData()
  88. {
  89. File.WriteAllText(dataPath, Newtonsoft.Json.JsonConvert.SerializeObject(customSongsData, Formatting.None));
  90. }
  91. public static void RegisterCapability(string capability)
  92. {
  93. if (!_capabilities.Contains(capability))
  94. _capabilities.Add(capability);
  95. }
  96. public static BeatmapCharacteristicSO RegisterCustomCharacteristic(Sprite Icon, string CharacteristicName, string HintText, string SerializedName, string CompoundIdPartName, bool requires360Movement = false, bool containsRotationEvents = false, int sortingOrder = 99)
  97. {
  98. BeatmapCharacteristicSO newChar = ScriptableObject.CreateInstance<BeatmapCharacteristicSO>();
  99. newChar.SetField("_icon", Icon);
  100. newChar.SetField("_descriptionLocalizationKey", HintText);
  101. newChar.SetField("_serializedName", SerializedName);
  102. newChar.SetField("_characteristicNameLocalizationKey", CharacteristicName);
  103. newChar.SetField("_compoundIdPartName", CompoundIdPartName);
  104. newChar.SetField("_requires360Movement", requires360Movement);
  105. newChar.SetField("_containsRotationEvents", containsRotationEvents);
  106. newChar.SetField("_sortingOrder", sortingOrder);
  107. if (!_customCharacteristics.Any(x => x.serializedName == newChar.serializedName))
  108. {
  109. _customCharacteristics.Add(newChar);
  110. return newChar;
  111. }
  112. return null;
  113. }
  114. //SongFolderEntry(string name, string path, FolderLevelPack pack, string imagePath = "", bool wip = false)
  115. public static SeperateSongFolder AddSeperateSongFolder(string name, string folderPath, FolderLevelPack pack, Sprite image = null, bool wip = false, bool cachezips = false)
  116. {
  117. UI.BasicUI.GetIcons();
  118. if (!Directory.Exists(folderPath))
  119. {
  120. try
  121. {
  122. Directory.CreateDirectory(folderPath);
  123. }
  124. catch (Exception ex)
  125. {
  126. Logging.logger.Error("Failed to make folder for: " + name + "\n" + ex);
  127. }
  128. }
  129. Data.SongFolderEntry entry = new SongFolderEntry(name, folderPath, pack, "", wip, cachezips);
  130. ModSeperateSongFolder seperateSongFolder = new ModSeperateSongFolder(entry, image == null ? UI.BasicUI.FolderIcon : image);
  131. if (Loader.SeperateSongFolders == null) Loader.SeperateSongFolders = new List<SeperateSongFolder>();
  132. Loader.SeperateSongFolders.Add(seperateSongFolder);
  133. return seperateSongFolder;
  134. }
  135. public static void DeregisterizeCapability(string capability)
  136. {
  137. _capabilities.Remove(capability);
  138. }
  139. }
  140. }