public static string GetCustomLevelHash(StandardLevelInfoSaveData level, string customLevelPath) { if (GetCachedSongData(customLevelPath, out var directoryHash, out var songHash)) { return(songHash); } byte[] combinedBytes = new byte[0]; combinedBytes = combinedBytes.Concat(File.ReadAllBytes(customLevelPath + '/' + "info.dat")).ToArray(); for (var i = 0; i < level.difficultyBeatmapSets.Length; i++) { for (var i2 = 0; i2 < level.difficultyBeatmapSets[i].difficultyBeatmaps.Length; i2++) { if (File.Exists(customLevelPath + '/' + level.difficultyBeatmapSets[i].difficultyBeatmaps[i2].beatmapFilename)) { combinedBytes = combinedBytes.Concat(File.ReadAllBytes(customLevelPath + '/' + level.difficultyBeatmapSets[i].difficultyBeatmaps[i2].beatmapFilename)).ToArray(); } } } string hash = CreateSha1FromBytes(combinedBytes.ToArray()); cachedSongHashData[customLevelPath] = new SongHashData(directoryHash, hash); return(hash); }
/// <summary> /// /// </summary> /// <param name="path">path to the folder of the song</param> /// <param name="hash"></param> /// <returns></returns> public static CustomPreviewBeatmapLevel LoadSong(string path) { StandardLevelInfoSaveData saveData = GetStandardLevelInfoSaveData(path); string hash; return(LoadSong(saveData, path, out hash)); }
public static void Postfix(string stringData, ref StandardLevelInfoSaveData __result) { //Plugin.logger.Debug("In DeserializeFromJSONString"); if (__result == null) { //Plugin.logger.Info("Result null with data:\n" + stringData); return; } __result = CustomLevelInfoSaveData.DeserializeFromJSONString(stringData, __result); /* * if (__result is CustomLevelInfoSaveData info) * { * Plugin.logger.Info(info.songName + ":"); * foreach (var pair in (IDictionary<string, object>)info.customData) * { * Plugin.logger.Info(" \"" + pair.Key + "\": " + pair.Value); * } * foreach (var set in info.difficultyBeatmapSets) * { * foreach (var beatmap in set.difficultyBeatmaps) * { * if (beatmap is CustomLevelInfoSaveData.DifficultyBeatmap b) * { * Plugin.logger.Info(" " + set.beatmapCharacteristicName + " -> " + b.difficulty + ":"); * foreach (var pair in (IDictionary<string, object>)b.customData) * { * Plugin.logger.Info(" \"" + pair.Key + "\": " + pair.Value); * } * } * } * } * } */ }
static bool Prefix(string customLevelPath, string difficultyFileName, StandardLevelInfoSaveData standardLevelInfoSaveData, ref BeatmapData __result) { string path = Path.Combine(customLevelPath, difficultyFileName); if (File.Exists(path)) { string json = File.ReadAllText(path); CustomBeatmapSaveData bsd = CustomBeatmapSaveData.DeserializeFromJSONString(json); // NOTE: logic depends on the above call always returning non-null when the vanilla version would! if (bsd == null) { __result = BeatmapDataLoader.GetBeatmapDataFromJson(json, standardLevelInfoSaveData.beatsPerMinute, standardLevelInfoSaveData.shuffle, standardLevelInfoSaveData.shufflePeriod); } else if (standardLevelInfoSaveData is CustomLevelInfoSaveData lisd) { __result = CustomBeatmapDataLoader.GetBeatmapDataFromBeatmapSaveData(bsd.notes, bsd.obstacles, bsd.events, lisd.beatsPerMinute, lisd.shuffle, lisd.shufflePeriod, bsd.customEvents ?? new List <CustomBeatmapSaveData.CustomEventData>(), at(lisd.beatmapCustomDatasByFilename, difficultyFileName) ?? Tree(), lisd.customData ?? Tree()); } else { __result = CustomBeatmapDataLoader.GetBeatmapDataFromBeatmapSaveData(bsd.notes, bsd.obstacles, bsd.events, standardLevelInfoSaveData.beatsPerMinute, standardLevelInfoSaveData.shuffle, standardLevelInfoSaveData.shufflePeriod, bsd.customEvents ?? new List <CustomBeatmapSaveData.CustomEventData>(), Tree(), Tree()); } } return(false); }
public static IEnumerator <BeatmapDetails> CreateBeatmapDetailsFromFilesCoroutine(CustomPreviewBeatmapLevel customLevel) { StandardLevelInfoSaveData infoData = customLevel.standardLevelInfoSaveData; BeatmapDetails beatmapDetails = new BeatmapDetails(); beatmapDetails.LevelID = BeatmapDetailsLoader.GetSimplifiedLevelID(customLevel); beatmapDetails.SongName = customLevel.songName; beatmapDetails.BeatsPerMinute = infoData.beatsPerMinute; // load difficulties beatmapDetails.DifficultyBeatmapSets = new SimplifiedDifficultyBeatmapSet[infoData.difficultyBeatmapSets.Length]; for (int i = 0; i < infoData.difficultyBeatmapSets.Length; ++i) { var currentSimplifiedSet = new SimplifiedDifficultyBeatmapSet(); beatmapDetails.DifficultyBeatmapSets[i] = currentSimplifiedSet; var currentSet = infoData.difficultyBeatmapSets[i]; currentSimplifiedSet.CharacteristicName = currentSet.beatmapCharacteristicName; currentSimplifiedSet.DifficultyBeatmaps = new SimplifiedDifficultyBeatmap[currentSet.difficultyBeatmaps.Length]; for (int j = 0; j < currentSet.difficultyBeatmaps.Length; ++j) { var currentSimplifiedDiff = new SimplifiedDifficultyBeatmap(); currentSimplifiedSet.DifficultyBeatmaps[j] = currentSimplifiedDiff; var currentDiff = currentSet.difficultyBeatmaps[j]; currentDiff.difficulty.BeatmapDifficultyFromSerializedName(out currentSimplifiedDiff.Difficulty); currentSimplifiedDiff.NoteJumpMovementSpeed = currentDiff.noteJumpMovementSpeed; string diffFilePath = Path.Combine(customLevel.customLevelPath, currentDiff.beatmapFilename); string fileContents = null; IEnumerator <string> textLoader = UnityMediaLoader.LoadTextCoroutine(diffFilePath); while (textLoader.MoveNext()) { fileContents = textLoader.Current; if (fileContents == null) { yield return(null); } } if (string.IsNullOrEmpty(fileContents)) { yield break; } BeatmapSaveData beatmapSaveData = null; try { beatmapSaveData = BeatmapSaveData.DeserializeFromJSONString(fileContents); } catch (Exception e) { Logger.log.Warn($"Exception occurred while trying to deserialize difficulty beatmap to BeatmapSaveData for '{customLevel.songName}'"); Logger.log.Debug(e); yield break; } // missing difficulty files if (beatmapSaveData == null) { yield break; } // count notes and bombs currentSimplifiedDiff.NotesCount = 0; currentSimplifiedDiff.BombsCount = 0; foreach (var note in beatmapSaveData.notes) { if (note.type.IsBasicNote()) { ++currentSimplifiedDiff.NotesCount; } else if (note.type == NoteType.Bomb) { ++currentSimplifiedDiff.BombsCount; } } // count rotation events currentSimplifiedDiff.SpawnRotationEventsCount = 0; foreach (var mapEvent in beatmapSaveData.events) { if (mapEvent.type.IsRotationEvent()) { ++currentSimplifiedDiff.SpawnRotationEventsCount; } } currentSimplifiedDiff.ObstaclesCount = beatmapSaveData.obstacles.Count; } } // load audio string audioFilePath = Path.Combine(customLevel.customLevelPath, infoData.songFilename); AudioClip audioClip = null; IEnumerator <AudioClip> audioLoader = UnityMediaLoader.LoadAudioClipCoroutine(audioFilePath); while (audioLoader.MoveNext()) { audioClip = audioLoader.Current; if (audioClip == null) { yield return(null); } } if (audioClip == null) { yield break; } beatmapDetails.SongDuration = audioClip.length; yield return(beatmapDetails); }
/// <summary> /// Loads files associated with a custom beatmap and creates a BeatmapDetails object with the information contained in the files. /// </summary> /// <param name="customLevel">A custom level to create the BeatmapDetails object for.</param> /// <returns>BeatmapDetails object on success, otherwise null.</returns> public static BeatmapDetails CreateBeatmapDetailsFromFiles(CustomPreviewBeatmapLevel customLevel) { StandardLevelInfoSaveData infoData = customLevel.standardLevelInfoSaveData; BeatmapDetails beatmapDetails = new BeatmapDetails(); beatmapDetails.LevelID = BeatmapDetailsLoader.GetSimplifiedLevelID(customLevel); beatmapDetails.SongName = customLevel.songName; beatmapDetails.BeatsPerMinute = infoData.beatsPerMinute; // load difficulties for note info beatmapDetails.DifficultyBeatmapSets = new SimplifiedDifficultyBeatmapSet[infoData.difficultyBeatmapSets.Length]; for (int i = 0; i < infoData.difficultyBeatmapSets.Length; ++i) { var currentSimplifiedSet = new SimplifiedDifficultyBeatmapSet(); beatmapDetails.DifficultyBeatmapSets[i] = currentSimplifiedSet; var currentSet = infoData.difficultyBeatmapSets[i]; currentSimplifiedSet.CharacteristicName = currentSet.beatmapCharacteristicName; currentSimplifiedSet.DifficultyBeatmaps = new SimplifiedDifficultyBeatmap[currentSet.difficultyBeatmaps.Length]; for (int j = 0; j < currentSet.difficultyBeatmaps.Length; ++j) { var currentSimplifiedDiff = new SimplifiedDifficultyBeatmap(); currentSimplifiedSet.DifficultyBeatmaps[j] = currentSimplifiedDiff; var currentDiff = currentSet.difficultyBeatmaps[j]; currentDiff.difficulty.BeatmapDifficultyFromSerializedName(out currentSimplifiedDiff.Difficulty); currentSimplifiedDiff.NoteJumpMovementSpeed = currentDiff.noteJumpMovementSpeed; string diffFilePath = Path.Combine(customLevel.customLevelPath, currentDiff.beatmapFilename); if (!File.Exists(diffFilePath)) { return(null); } BeatmapSaveData beatmapSaveData = null; try { beatmapSaveData = BeatmapSaveData.DeserializeFromJSONString(File.ReadAllText(diffFilePath)); } catch (Exception e) { Logger.log.Debug("Unable to create BeatmapDetails object from files (unexpected exception occurred trying to load BeatmapSaveData from file)"); Logger.log.Debug(e); return(null); } if (beatmapSaveData == null) { Logger.log.Debug("Unable to create BeatmapDetails object from files (could not load BeatmapSaveData from file)"); return(null); } // count notes and bombs currentSimplifiedDiff.NotesCount = 0; currentSimplifiedDiff.BombsCount = 0; foreach (var note in beatmapSaveData.notes) { if (note.type.IsBasicNote()) { ++currentSimplifiedDiff.NotesCount; } else if (note.type == NoteType.Bomb) { ++currentSimplifiedDiff.BombsCount; } } // count rotation events currentSimplifiedDiff.SpawnRotationEventsCount = 0; foreach (var mapEvent in beatmapSaveData.events) { if (mapEvent.type.IsRotationEvent()) { ++currentSimplifiedDiff.SpawnRotationEventsCount; } } currentSimplifiedDiff.ObstaclesCount = beatmapSaveData.obstacles.Count; } } // load audio for map length string audioFilePath = Path.Combine(customLevel.customLevelPath, infoData.songFilename); AudioClip audioClip = UnityMediaLoader.LoadAudioClip(audioFilePath); if (audioClip == null) { return(null); } beatmapDetails.SongDuration = audioClip.length; return(beatmapDetails); }
static bool Prefix(BeatmapDataLoader ____beatmapDataLoader, string customLevelPath, string difficultyFileName, StandardLevelInfoSaveData standardLevelInfoSaveData, ref BeatmapData __result) { //Plugin.logger.Debug("In LoadBeatmapDataBeatmapData"); string path = Path.Combine(customLevelPath, difficultyFileName); //Plugin.logger.Debug("Loading " + standardLevelInfoSaveData.songName + " (" + path + ")"); if (File.Exists(path)) { string json = File.ReadAllText(path); CustomBeatmapSaveData bsd = CustomBeatmapSaveData.DeserializeFromJSONString(json); // NOTE: logic depends on the above call always returning non-null when the vanilla version would! if (bsd == null) { //Plugin.logger.Debug("CustomBeatmapSaveData was null; falling back to BeatmapDataLoader.GetBeatmapDataFromJson"); __result = ____beatmapDataLoader.GetBeatmapDataFromJson(json, standardLevelInfoSaveData.beatsPerMinute, standardLevelInfoSaveData.shuffle, standardLevelInfoSaveData.shufflePeriod); } else if (standardLevelInfoSaveData is CustomLevelInfoSaveData lisd) { //Plugin.logger.Debug("Loaded CustomBeatmapSaveData with CustomLevelInfoSaveData"); __result = CustomBeatmapDataLoader.GetBeatmapDataFromBeatmapSaveData(bsd.notes, bsd.obstacles, bsd.events, lisd.beatsPerMinute, lisd.shuffle, lisd.shufflePeriod, bsd.customEvents ?? new List <CustomBeatmapSaveData.CustomEventData>(), at(lisd.beatmapCustomDatasByFilename, difficultyFileName) ?? Tree(), lisd.customData ?? Tree(), ____beatmapDataLoader); } else { //Plugin.logger.Debug("Loaded CustomBeatmapSaveData with StandardLevelInfoSaveData"); __result = CustomBeatmapDataLoader.GetBeatmapDataFromBeatmapSaveData(bsd.notes, bsd.obstacles, bsd.events, standardLevelInfoSaveData.beatsPerMinute, standardLevelInfoSaveData.shuffle, standardLevelInfoSaveData.shufflePeriod, bsd.customEvents ?? new List <CustomBeatmapSaveData.CustomEventData>(), Tree(), Tree(), ____beatmapDataLoader); } /* * if (__result is CustomBeatmapData beatmapData) * { * foreach (var line in beatmapData.beatmapLinesData) * { * foreach (var obj in line.beatmapObjectsData) * { * if (obj is CustomObstacleData obs) * { * Plugin.logger.Debug("Custom obstacle at " + obs.time); * Plugin.logger.Debug("Data:"); * foreach (var pair in (IDictionary<string, object>)obs.customData) * { * Plugin.logger.Debug(" \"" + pair.Key + "\": " + pair.Value); * } * } * else if (obj is ObstacleData ob) * { * Plugin.logger.Debug("Non-custom obstacle at " + ob.time); * } * if (obj is CustomNoteData n) * { * Plugin.logger.Debug("Custom note at " + n.time); * Plugin.logger.Debug("Data:"); * foreach (var pair in (IDictionary<string, object>)n.customData) * { * Plugin.logger.Debug(" \"" + pair.Key + "\": " + pair.Value); * } * } * else if (obj is NoteData no) * { * Plugin.logger.Debug("Non-custom note at " + no.time); * } * } * } * foreach (var pair in beatmapData.customEventData) * { * Plugin.logger.Debug("Custom event \"" + pair.Key + "\":"); * foreach (var e in pair.Value) * { * Plugin.logger.Debug(" " + e.time + ":"); * foreach (var innerPair in (IDictionary<string, object>)e.data) * { * Plugin.logger.Debug(" \"" + innerPair.Key + "\": " + innerPair.Value); * } * } * } * } */ } return(false); }
public static StandardLevelInfoSaveData DeserializeFromJSONString(string stringData, StandardLevelInfoSaveData standardSaveData) { // StandardLevelInfoSaveData standardSaveData = StandardLevelInfoSaveData.DeserializeFromJSONString(stringData); if (standardSaveData.version != "2.0.0") { return(standardSaveData); } Dictionary <string, dynamic> beatmapsByFilename = new Dictionary <string, dynamic>(); OopsAllCustomDatas customDatas = JsonConvert.DeserializeObject <OopsAllCustomDatas>(stringData, new CustomDataConverter()); DifficultyBeatmapSet[] customBeatmapSets = new DifficultyBeatmapSet[standardSaveData.difficultyBeatmapSets.Length]; for (int i = 0; i < standardSaveData.difficultyBeatmapSets.Length; i++) { var standardBeatmapSet = standardSaveData.difficultyBeatmapSets[i]; DifficultyBeatmap[] customBeatmaps = new DifficultyBeatmap[standardBeatmapSet.difficultyBeatmaps.Length]; for (int j = 0; j < standardBeatmapSet.difficultyBeatmaps.Length; j++) { var standardBeatmap = standardBeatmapSet.difficultyBeatmaps[j]; DifficultyBeatmap customBeatmap = new DifficultyBeatmap(standardBeatmap.difficulty, standardBeatmap.difficultyRank, standardBeatmap.beatmapFilename, standardBeatmap.noteJumpMovementSpeed, standardBeatmap.noteJumpStartBeatOffset, customDatas._difficultyBeatmapSets[i]._difficultyBeatmaps[j]._customData ?? Tree()); customBeatmaps[j] = customBeatmap; beatmapsByFilename[customBeatmap.beatmapFilename] = customBeatmap.customData; } customBeatmapSets[i] = new DifficultyBeatmapSet(standardBeatmapSet.beatmapCharacteristicName, customBeatmaps); } CustomLevelInfoSaveData result = new CustomLevelInfoSaveData(standardSaveData.songName, standardSaveData.songSubName, standardSaveData.songAuthorName, standardSaveData.levelAuthorName, standardSaveData.beatsPerMinute, standardSaveData.songTimeOffset, standardSaveData.shuffle, standardSaveData.shufflePeriod, standardSaveData.previewStartTime, standardSaveData.previewDuration, standardSaveData.songFilename, standardSaveData.coverImageFilename, standardSaveData.environmentName, customBeatmapSets, customDatas._customData ?? Tree(), beatmapsByFilename); return(result); }
// Taken from SongCore public static CustomPreviewBeatmapLevel LoadSong(StandardLevelInfoSaveData saveData, string songPath, out string hash, SongFolderEntry folderEntry = null) { CustomPreviewBeatmapLevel result; bool wip = false; if (songPath.Contains("CustomWIPLevels")) { wip = true; } if (folderEntry != null) { if (folderEntry.Pack == FolderLevelPack.CustomWIPLevels) { wip = true; } else if (folderEntry.WIP) { wip = true; } } hash = Hashing.GetCustomLevelHash(saveData, songPath); try { string folderName = new DirectoryInfo(songPath).Name; string levelID = CustomLevelLoader.kCustomLevelPrefixId + hash; if (wip) { levelID += " WIP"; } if (SongCore.Collections.hashForLevelID(levelID) != "") { levelID += "_" + folderName; } string songName = saveData.songName; string songSubName = saveData.songSubName; string songAuthorName = saveData.songAuthorName; string levelAuthorName = saveData.levelAuthorName; float beatsPerMinute = saveData.beatsPerMinute; float songTimeOffset = saveData.songTimeOffset; float shuffle = saveData.shuffle; float shufflePeriod = saveData.shufflePeriod; float previewStartTime = saveData.previewStartTime; float previewDuration = saveData.previewDuration; EnvironmentInfoSO environmentSceneInfo = _customLevelLoader.LoadEnvironmentInfo(saveData.environmentName, false); EnvironmentInfoSO allDirectionEnvironmentInfo = _customLevelLoader.LoadEnvironmentInfo(saveData.allDirectionsEnvironmentName, true); List <PreviewDifficultyBeatmapSet> list = new List <PreviewDifficultyBeatmapSet>(); foreach (StandardLevelInfoSaveData.DifficultyBeatmapSet difficultyBeatmapSet in saveData.difficultyBeatmapSets) { BeatmapCharacteristicSO beatmapCharacteristicBySerializedName = beatmapCharacteristicCollection.GetBeatmapCharacteristicBySerializedName(difficultyBeatmapSet.beatmapCharacteristicName); BeatmapDifficulty[] array = new BeatmapDifficulty[difficultyBeatmapSet.difficultyBeatmaps.Length]; for (int j = 0; j < difficultyBeatmapSet.difficultyBeatmaps.Length; j++) { BeatmapDifficulty beatmapDifficulty; difficultyBeatmapSet.difficultyBeatmaps[j].difficulty.BeatmapDifficultyFromSerializedName(out beatmapDifficulty); array[j] = beatmapDifficulty; } list.Add(new PreviewDifficultyBeatmapSet(beatmapCharacteristicBySerializedName, array)); } result = new CustomPreviewBeatmapLevel(defaultCoverImage.texture, saveData, songPath, cachedMediaAsyncLoaderSO, cachedMediaAsyncLoaderSO, levelID, songName, songSubName, songAuthorName, levelAuthorName, beatsPerMinute, songTimeOffset, shuffle, shufflePeriod, previewStartTime, previewDuration, environmentSceneInfo, allDirectionEnvironmentInfo, list.ToArray()); } catch { Plugin.log.Error("Failed to Load Song: " + songPath); result = null; } return(result); }
public static StandardLevelInfoSaveData GetStandardLevelInfoSaveData(string path) { var text = File.ReadAllText(path + "/info.dat"); return(StandardLevelInfoSaveData.DeserializeFromJSONString(text)); }
private static void Postfix(BeatmapData __result, StandardLevelInfoSaveData standardLevelInfoSaveData) { if (__result == null) { return; } foreach (BeatmapLineData beatmapLineData in __result.beatmapLinesData) { foreach (BeatmapObjectData beatmapObjectData in beatmapLineData.beatmapObjectsData) { dynamic customData; if (beatmapObjectData is CustomObstacleData || beatmapObjectData is CustomNoteData) { customData = beatmapObjectData; } else { continue; } dynamic dynData = customData.customData; // JANK JANK JANK // TODO: REWRITE CJD SO I DONT HAVE TO DO THIS JANK float bpm = standardLevelInfoSaveData.beatsPerMinute; dynData.bpm = bpm; // VARIABLE FUN FUN TIME YAY SO FUN YAYYYY List <object> varPosition = Trees.at(dynData, VARIABLEPOSITION); if (varPosition != null) { List <PositionData> positionData = new List <PositionData>(); foreach (object n in varPosition) { IDictionary <string, object> dictData = n as IDictionary <string, object>; IEnumerable <float> startpos = ((List <object>)Trees.at(dictData, VARIABLESTARTPOS))?.Select(Convert.ToSingle); IEnumerable <float> endpos = ((List <object>)Trees.at(dictData, VARIABLEENDPOS))?.Select(Convert.ToSingle); float time = GetRealTimeFromBPMTime((float)Trees.at(dictData, VARIABLETIME), bpm); float duration = GetRealTimeFromBPMTime((float)Trees.at(dictData, VARIABLEDURATION), bpm); string easing = (string)Trees.at(dictData, VARIABLEEASING); bool? relative = (bool?)Trees.at(dictData, VARIABLERELATIVE); positionData.Add(new PositionData(time, duration, startpos, endpos, easing, relative)); } dynData.varPosition = positionData; } RotationData.savedRotation = Quaternion.identity; List <object> varRotation = Trees.at(dynData, VARIABLEROTATION); if (varRotation != null) { List <RotationData> rotationData = new List <RotationData>(); foreach (object n in varRotation) { IDictionary <string, object> dictData = n as IDictionary <string, object>; IEnumerable <float> startrot = ((List <object>)Trees.at(dictData, VARIABLESTARTROT))?.Select(Convert.ToSingle); IEnumerable <float> endrot = ((List <object>)Trees.at(dictData, VARIABLEENDROT))?.Select(Convert.ToSingle); float time = GetRealTimeFromBPMTime((float)Trees.at(dictData, VARIABLETIME), bpm); float duration = GetRealTimeFromBPMTime((float)Trees.at(dictData, VARIABLEDURATION), bpm); string easing = (string)Trees.at(dictData, VARIABLEEASING); rotationData.Add(new RotationData(time, duration, startrot, endrot, easing)); } dynData.varRotation = rotationData; } RotationData.savedRotation = Quaternion.identity; List <object> varLocalRotation = Trees.at(dynData, VARIABLELOCALROTATION); if (varLocalRotation != null) { List <RotationData> rotationData = new List <RotationData>(); foreach (object n in varLocalRotation) { IDictionary <string, object> dictData = n as IDictionary <string, object>; IEnumerable <float> startrot = ((List <object>)Trees.at(dictData, VARIABLESTARTROT))?.Select(Convert.ToSingle); IEnumerable <float> endrot = ((List <object>)Trees.at(dictData, VARIABLEENDROT))?.Select(Convert.ToSingle); float time = GetRealTimeFromBPMTime((float)Trees.at(dictData, VARIABLETIME), bpm); float duration = GetRealTimeFromBPMTime((float)Trees.at(dictData, VARIABLEDURATION), bpm); string easing = (string)Trees.at(dictData, VARIABLEEASING); rotationData.Add(new RotationData(time, duration, startrot, endrot, easing)); } dynData.varLocalRotation = rotationData; } } } }
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter private static void Postfix(BeatmapData __result, string difficultyFileName, StandardLevelInfoSaveData standardLevelInfoSaveData) #pragma warning restore SA1313 // Parameter names should begin with lower-case letter { if (__result != null && __result is CustomBeatmapData customBeatmapData) { // heck you beat games for not passing StandardLevelInfoSaveData.DifficultyBeatmap down to this method StandardLevelInfoSaveData.DifficultyBeatmap difficultyBeatmap = null; int iCount = standardLevelInfoSaveData.difficultyBeatmapSets.Length; for (int i = 0; i < iCount; i++) { StandardLevelInfoSaveData.DifficultyBeatmapSet difficultyBeatmapSet = standardLevelInfoSaveData.difficultyBeatmapSets[i]; int jCount = difficultyBeatmapSet.difficultyBeatmaps.Length; for (int j = 0; j < jCount; j++) { StandardLevelInfoSaveData.DifficultyBeatmap difficultyBeatmaps = difficultyBeatmapSet.difficultyBeatmaps[j]; if (difficultyBeatmaps.beatmapFilename == difficultyFileName) { difficultyBeatmap = difficultyBeatmaps; } } } if (difficultyBeatmap != null) { // there is some ambiguity with these variables but who frikkin cares float startHalfJumpDurationInBeats = 4; float maxHalfJumpDistance = 18; float moveDuration = 0.5f; foreach (BeatmapLineData beatmapLineData in __result.beatmapLinesData) { foreach (BeatmapObjectData beatmapObjectData in beatmapLineData.beatmapObjectsData) { dynamic customData; if (beatmapObjectData is CustomObstacleData || beatmapObjectData is CustomNoteData) { customData = beatmapObjectData; } else { return; } dynamic dynData = customData.customData; float noteJumpMovementSpeed = (float?)Trees.at(dynData, NOTEJUMPSPEED) ?? difficultyBeatmap.noteJumpMovementSpeed; float noteJumpStartBeatOffset = (float?)Trees.at(dynData, NOTESPAWNOFFSET) ?? difficultyBeatmap.noteJumpStartBeatOffset; // how do i not repeat this in a reasonable way float num = 60f / (float)Trees.at(dynData, "bpm"); float num2 = startHalfJumpDurationInBeats; while (noteJumpMovementSpeed * num * num2 > maxHalfJumpDistance) { num2 /= 2f; } num2 += noteJumpStartBeatOffset; if (num2 < 1f) { num2 = 1f; } float jumpDuration = num * num2 * 2f; dynData.aheadTime = moveDuration + (jumpDuration * 0.5f); } beatmapLineData.beatmapObjectsData = beatmapLineData.beatmapObjectsData.OrderBy(n => n.time - (float)((dynamic)n).customData.aheadTime).ToArray(); } } } }
private void RetrieveAllSongs(bool fullRefresh) { var stopwatch = new Stopwatch(); if (fullRefresh) { CustomLevels.Clear(); CustomWIPLevels.Clear(); CachedWIPLevels.Clear(); Collections.levelHashDictionary.Clear(); Collections.hashLevelDictionary.Clear(); foreach (var folder in SeperateSongFolders) { folder.Levels.Clear(); } } HashSet <string> foundSongPaths = fullRefresh ? new HashSet <string>() : new HashSet <string>(Hashing.cachedSongHashData.Keys); var baseProjectPath = CustomLevelPathHelper.baseProjectPath; var customLevelsPath = CustomLevelPathHelper.customLevelsDirectoryPath; Action job = delegate { try { var path = CustomLevelPathHelper.baseProjectPath; path = path.Replace('\\', '/'); if (!Directory.Exists(customLevelsPath)) { Directory.CreateDirectory(customLevelsPath); } if (!Directory.Exists(baseProjectPath + "/CustomWIPLevels")) { Directory.CreateDirectory(baseProjectPath + "/CustomWIPLevels"); } if (fullRefresh) { try { var cachePath = path + "/CustomWIPLevels/Cache"; if (!Directory.Exists(cachePath)) { Directory.CreateDirectory(cachePath); } var cache = new DirectoryInfo(cachePath); foreach (var file in cache.GetFiles()) { file.Delete(); } foreach (var folder in cache.GetDirectories()) { folder.Delete(true); } var zips = Directory.GetFiles(path + "/CustomWIPLevels", "*.zip", SearchOption.TopDirectoryOnly); foreach (var zip in zips) { var unzip = new Unzip(zip); try { unzip.ExtractToDirectory(cachePath + "/" + new FileInfo(zip).Name); } catch (Exception ex) { Logging.logger.Warn("Failed to extract zip: " + zip + ": " + ex); } unzip.Dispose(); } var cacheFolders = Directory.GetDirectories(cachePath).ToArray(); foreach (var cachedFolder in cacheFolders) { var results = Directory.GetFiles(cachedFolder, "info.dat", SearchOption.AllDirectories); if (results.Length == 0) { Logging.Log("Folder: '" + cachedFolder + "' is missing info.dat files!", LogSeverity.Notice); continue; } foreach (var result in results) { try { var songPath = Path.GetDirectoryName(result.Replace('\\', '/')); if (!fullRefresh) { if (CachedWIPLevels.ContainsKey(songPath)) { var c = CachedWIPLevels[songPath];//.FirstOrDefault(x => x.customLevelPath == songPath); if (c != null) { continue; } } } StandardLevelInfoSaveData saveData = GetStandardLevelInfoSaveData(songPath); if (saveData == null) { continue; } HMMainThreadDispatcher.instance.Enqueue(delegate { if (_loadingCancelled) { return; } var level = LoadSong(saveData, songPath, out string hash); if (level != null) { CachedWIPLevels[songPath] = level; } }); } catch (Exception ex) { Logging.logger.Notice("Failed to load song from " + cachedFolder + ": " + ex); } } } }
private static void Postfix(ref BeatmapData __result, string difficultyFileName, StandardLevelInfoSaveData standardLevelInfoSaveData) { if (__result != null && __result is CustomBeatmapData customBeatmapData && standardLevelInfoSaveData is CustomLevelInfoSaveData lisd) { __result = new CustomBeatmapData( __result, customBeatmapData.customEventData, customBeatmapData.customData, at(lisd.beatmapCustomDatasByFilename, difficultyFileName) ?? Tree(), lisd.customData ?? Tree()); } }
private void RetrieveAllSongs(bool fullRefresh) { var stopwatch = new Stopwatch(); if (fullRefresh) { CustomLevels.Clear(); CustomWIPLevels.Clear(); } HashSet <string> foundSongPaths = fullRefresh ? new HashSet <string>() : new HashSet <string>(Hashing.cachedSongHashData.Keys); Action job = delegate { try { stopwatch.Start(); var path = CustomLevelPathHelper.baseProjectPath; path = path.Replace('\\', '/'); if (!Directory.Exists(CustomLevelPathHelper.customLevelsDirectoryPath)) { Directory.CreateDirectory(CustomLevelPathHelper.customLevelsDirectoryPath); } if (!Directory.Exists(path + "/CustomWIPLevels")) { Directory.CreateDirectory(path + "/CustomWIPLevels"); } var songFolders = Directory.GetDirectories(path + "/CustomLevels").ToList().Concat(Directory.GetDirectories(path + "/CustomWIPLevels")).ToList(); var loadedData = new List <string>(); float i = 0; foreach (var folder in songFolders) { i++; var results = Directory.GetFiles(folder, "info.dat", SearchOption.TopDirectoryOnly); if (results.Length == 0) { Logging.Log("Folder: '" + folder + "' is missing info.dat files!", LogSeverity.Notice); continue; } foreach (var result in results) { try { var songPath = Path.GetDirectoryName(result.Replace('\\', '/')); if (Directory.GetParent(songPath).Name == "Backups") { continue; } if (!fullRefresh) { if (CustomLevels.ContainsKey(songPath)) { var c = CustomLevels[songPath];//.FirstOrDefault(x => x.customLevelPath == songPath); if (c != null) { loadedData.Add(c.levelID); continue; } } } bool wip = false; if (songPath.Contains("CustomWIPLevels")) { wip = true; } StandardLevelInfoSaveData saveData = GetStandardLevelInfoSaveData(songPath); if (saveData == null) { // Logging.Log("Null save data", LogSeverity.Notice); continue; } // if (loadedData.Any(x => x == saveData.)) // { // Logging.Log("Duplicate song found at " + songPath, LogSeverity.Notice); // continue; // } // loadedData.Add(saveDat); var count = i; HMMainThreadDispatcher.instance.Enqueue(delegate { if (_loadingCancelled) { return; } var level = LoadSong(saveData, songPath, out string hash); if (level != null) { if (!Collections.levelHashDictionary.ContainsKey(level.levelID)) { Collections.levelHashDictionary.Add(level.levelID, hash); if (Collections.hashLevelDictionary.TryGetValue(hash, out var levels)) { levels.Add(level.levelID); } else { levels = new List <string>(); levels.Add(level.levelID); Collections.hashLevelDictionary.Add(hash, levels); } /* * if (Collections.hashLevelDictionary.ContainsKey(hash)) * Collections.hashLevelDictionary[hash].Add(level.levelID); * else * { * var levels = new List<string>(); * levels.Add(level.levelID); * Collections.hashLevelDictionary.Add(hash, levels); * } */ } /* * string hash = Utils.GetCustomLevelHash(level); * if (!Collections._loadedHashes.ContainsKey(hash)) * { * List<CustomPreviewBeatmapLevel> value = new List<CustomPreviewBeatmapLevel>(); * value.Add(level); * Collections._loadedHashes.Add(hash, value); * } * else * Collections._loadedHashes[hash].Add(level); */ if (!wip) { CustomLevels[songPath] = level; } else { CustomWIPLevels[songPath] = level; } foundSongPaths.Add(songPath); } LoadingProgress = count / songFolders.Count; }); } catch (Exception e) { Logging.Log("Failed to load song folder: " + result, LogSeverity.Error); Logging.Log(e.ToString(), LogSeverity.Error); } } }
public SongData(string rawSongData, StandardLevelInfoSaveData saveData) { RawSongData = rawSongData; SaveData = saveData; }