Пример #1
0
        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);
        }
Пример #2
0
        /// <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));
        }
Пример #3
0
        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);
             *              }
             *          }
             *      }
             *  }
             * }
             */
        }
Пример #4
0
        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);
        }
Пример #7
0
        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);
        }
Пример #9
0
        // 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);
        }
Пример #10
0
        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();
                    }
                }
            }
        }
Пример #13
0
        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);
                                    }
                                }
                            }
                        }
Пример #14
0
 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());
     }
 }
Пример #15
0
        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);
                            }
                        }
                    }
Пример #16
0
 public SongData(string rawSongData, StandardLevelInfoSaveData saveData)
 {
     RawSongData = rawSongData;
     SaveData    = saveData;
 }