Beispiel #1
0
        private void CreateCustomLevelCollections()
        {
            var originalCollections = Resources.FindObjectsOfTypeAll <LevelCollectionsForGameplayModes>().FirstOrDefault();

            _standardLevelCollection = ScriptableObject.CreateInstance <CustomLevelCollectionSO>();
            _standardLevelCollection.Init(originalCollections.GetLevels(GameplayMode.SoloStandard));

            _oneSaberLevelCollection = ScriptableObject.CreateInstance <CustomLevelCollectionSO>();
            _oneSaberLevelCollection.Init(originalCollections.GetLevels(GameplayMode.SoloOneSaber));

            _noArrowsLevelCollection = ScriptableObject.CreateInstance <CustomLevelCollectionSO>();
            _noArrowsLevelCollection.Init(originalCollections.GetLevels(GameplayMode.SoloNoArrows));

            _partyLevelCollection = ScriptableObject.CreateInstance <CustomLevelCollectionSO>();
            _partyLevelCollection.Init(originalCollections.GetLevels(GameplayMode.PartyStandard));

            _customLevelCollectionsForGameplayModes =
                ScriptableObject.CreateInstance <CustomLevelCollectionsForGameplayModes>();

            var standard = new CustomLevelCollectionForGameplayMode(GameplayMode.SoloStandard, _standardLevelCollection);
            var oneSaber = new CustomLevelCollectionForGameplayMode(GameplayMode.SoloOneSaber, _oneSaberLevelCollection);
            var noArrows = new CustomLevelCollectionForGameplayMode(GameplayMode.SoloNoArrows, _noArrowsLevelCollection);
            var party    = new CustomLevelCollectionForGameplayMode(GameplayMode.PartyStandard, _partyLevelCollection);

            _customLevelCollectionsForGameplayModes.SetCollections(
                new LevelCollectionsForGameplayModes.LevelCollectionForGameplayMode[]
                { standard, oneSaber, noArrows, party });
        }
Beispiel #2
0
        public static IBeatmapLevelPack GetLevelPackWithLevels(BeatmapLevelSO[] levels, string packName = null, Sprite packCover = null)
        {
            CustomLevelCollectionSO levelCollection = ScriptableObject.CreateInstance <CustomLevelCollectionSO>();

            levelCollection.SetPrivateField("_levelList", levels.ToList());
            levelCollection.SetPrivateField("_beatmapLevels", levels);

            CustomBeatmapLevelPackSO pack = CustomBeatmapLevelPackSO.GetPack(levelCollection);

            pack.SetPrivateField("_packName", string.IsNullOrEmpty(packName) ? "Custom Songs" : packName);
            pack.SetPrivateField("_coverImage", packCover ?? Sprites.BeastSaberLogo);
            pack.SetPrivateField("_isPackAlwaysOwned", true);

            return(pack);
        }
        public void UpdateDataFromPlaylist()
        {
            _packName          = _playlist.playlistTitle;
            _coverImage        = _playlist.icon;
            _packID            = $"Playlist_{playlist.playlistTitle}_{playlist.playlistAuthor}";
            _isPackAlwaysOwned = false;

            PlaylistsCollection.MatchSongsForPlaylist(playlist);

            IPreviewBeatmapLevel[] levels = playlist.songs.Where(x => x.level != null).Select(x => x.level).ToArray();

            CustomLevelCollectionSO levelCollection = ScriptableObject.CreateInstance <CustomLevelCollectionSO>();

            levelCollection.SetPrivateField("_levelList", levels.Where(x => x is BeatmapLevelSO).Cast <BeatmapLevelSO>().ToList());
            levelCollection.SetPrivateField("_beatmapLevels", levels);

            _beatmapLevelCollection = levelCollection;
        }
        public void RemoveSong(CustomLevel customLevel)
        {
            if (customLevel == null)
            {
                return;
            }

            CustomLevelCollectionSO.RemoveLevel(customLevel);

            foreach (var difficultyBeatmap in customLevel.difficultyBeatmaps)
            {
                var customDifficulty = difficultyBeatmap as CustomLevel.CustomDifficultyBeatmap;
                if (customDifficulty == null)
                {
                    continue;
                }
                _beatmapDataPool.Return(customDifficulty.BeatmapDataSO);
            }

            _customLevelPool.Return(customLevel);
        }
        private void ReloadCurrentSong()
        {
            if (!_standardLevelSceneSetupData.gameplayCoreSetupData.gameplayModifiers.noFail)
            {
                return;
            }
            var reloadedLevel = LoadSong(GetCustomSongInfo(CurrentLevelPlaying.customLevel.customSongInfo.path));

            if (reloadedLevel == null)
            {
                return;
            }

            reloadedLevel.FixBPMAndGetNoteJumpMovementSpeed();
            reloadedLevel.SetAudioClip(CurrentLevelPlaying.customLevel.audioClip);

            RemoveSong(CurrentLevelPlaying.customLevel);
            CustomLevels.Add(reloadedLevel);

            CustomLevelCollectionSO.AddCustomLevel(reloadedLevel);

            var orderedList = CustomLevels.OrderBy(x => x.songName);

            CustomLevels = orderedList.ToList();

            _standardLevelSceneSetupData.__WillBeUsedInTransition();
            _standardLevelSceneSetupData.Init(
                reloadedLevel.GetDifficultyBeatmap(_standardLevelSceneSetupData.difficultyBeatmap.difficulty),
                _standardLevelSceneSetupData.gameplayCoreSetupData);

            var restartController = Resources.FindObjectsOfTypeAll <StandardLevelRestartController>().FirstOrDefault();

            if (restartController == null)
            {
                Console.WriteLine("No restart controller!");
                return;
            }

            restartController.RestartLevel();
        }
        public void RefreshSongs(bool fullRefresh = true)
        {
            if (SceneManager.GetActiveScene().name != MenuSceneName)
            {
                return;
            }
            if (AreSongsLoading)
            {
                return;
            }

            Log(fullRefresh ? "Starting full song refresh" : "Starting song refresh");
            AreSongsLoaded    = false;
            AreSongsLoading   = true;
            LoadingProgress   = 0;
            _loadingCancelled = false;

            if (LoadingStartedEvent != null)
            {
                try
                {
                    LoadingStartedEvent(this);
                }
                catch (Exception e)
                {
                    Log("Some plugin is throwing exception from the LoadingStartedEvent!", LogSeverity.Error);
                    Log(e.ToString(), LogSeverity.Error);
                }
            }

            foreach (var customLevel in CustomLevels)
            {
                CustomLevelCollectionSO.RemoveLevel(customLevel);
            }

            RetrieveAllSongs(fullRefresh);
        }
        private void RetrieveAllSongs(bool fullRefresh)
        {
            var stopwatch = new Stopwatch();
            var levelList = new List <CustomLevel>();

            if (fullRefresh)
            {
                _customLevelPool.ReturnAll();
                _beatmapDataPool.ReturnAll();
                CustomLevels.Clear();
            }

            Action job = delegate
            {
                try
                {
                    stopwatch.Start();
                    var path = Environment.CurrentDirectory;
                    path = path.Replace('\\', '/');

                    var currentHashes = new List <string>();
                    var cachedHashes  = new List <string>();
                    var cachedSongs   = new string[0];

                    if (Directory.Exists(path + "/CustomSongs/.cache"))
                    {
                        cachedSongs = Directory.GetDirectories(path + "/CustomSongs/.cache");
                    }
                    else
                    {
                        Directory.CreateDirectory(path + "/CustomSongs/.cache");
                    }


                    var songZips = Directory.GetFiles(path + "/CustomSongs")
                                   .Where(x => x.ToLower().EndsWith(".zip") || x.ToLower().EndsWith(".beat") || x.ToLower().EndsWith(".bmap")).ToArray();
                    foreach (var songZip in songZips)
                    {
                        //Check cache if zip already is extracted
                        string hash;
                        string trimmedZip = songZip;
                        trimmedZip = Utils.TrimEnd(trimmedZip, ".zip");
                        trimmedZip = Utils.TrimEnd(trimmedZip, ".beat");
                        trimmedZip = Utils.TrimEnd(trimmedZip, ".bmap");
                        if (Utils.CreateMD5FromFile(songZip, out hash))
                        {
                            using (var unzip = new Unzip(songZip))
                            {
                                try
                                {
                                    if (Directory.Exists(trimmedZip))
                                    {
                                        Log("Directory for Zip already exists, Extracting Zip to Cache instead.");
                                        cachedHashes.Add(hash);
                                        if (cachedSongs.Any(x => x.Contains(hash)))
                                        {
                                            continue;
                                        }
                                        unzip.ExtractToDirectory(path + "/CustomSongs/.cache/" + hash);
                                    }
                                    else
                                    {
                                        unzip.ExtractToDirectory(path + "/CustomSongs/" + trimmedZip.Replace(path + "/CustomSongs\\", ""));
                                        //Add hash if successfully extracted
                                        currentHashes.Add(hash);
                                    }
                                }
                                catch (Exception e)
                                {
                                    Log("Error extracting zip " + songZip + "\n" + e, LogSeverity.Warn);
                                }
                            }
                        }
                        else
                        {
                            Log("Error reading zip " + songZip, LogSeverity.Warn);
                        }
                    }


                    var songFolders = Directory.GetDirectories(path + "/CustomSongs").ToList();
                    var songCaches  = Directory.GetDirectories(path + "/CustomSongs/.cache");

                    foreach (var songZip in songZips)
                    {
                        //Delete zip if successfully extracted
                        string hash;
                        if (Utils.CreateMD5FromFile(songZip, out hash))
                        {
                            if (currentHashes.Contains(hash))
                            {
                                Log("Zip Successfully Extracted, deleting zip.");
                                File.SetAttributes(songZip, FileAttributes.Normal);
                                File.Delete(songZip);
                            }
                        }
                    }

                    foreach (var song in songCaches)
                    {
                        var hash = Path.GetFileName(song);
                        if (!cachedHashes.Contains(hash))
                        {
                            //Old cache
                            Directory.Delete(song, true);
                        }
                    }



                    var loadedIDs = new List <string>();

                    float i = 0;
                    foreach (var song in songFolders)
                    {
                        i++;
                        var results = Directory.GetFiles(song, "info.json", SearchOption.AllDirectories);
                        if (results.Length == 0)
                        {
                            Log("Custom song folder '" + song + "' is missing info.json files!", LogSeverity.Warn);
                            continue;
                        }


                        foreach (var result in results)
                        {
                            try
                            {
                                var songPath = Path.GetDirectoryName(result).Replace('\\', '/');
                                if (!fullRefresh)
                                {
                                    if (CustomLevels.Any(x => x.customSongInfo.path == songPath))
                                    {
                                        continue;
                                    }
                                }

                                var customSongInfo = GetCustomSongInfo(songPath);

                                if (customSongInfo == null)
                                {
                                    continue;
                                }
                                var id = customSongInfo.GetIdentifier();
                                if (loadedIDs.Any(x => x == id))
                                {
                                    Log("Duplicate song found at " + customSongInfo.path, LogSeverity.Warn);
                                    continue;
                                }

                                loadedIDs.Add(id);

                                if (CustomPlatformsPresent && customSongPlatforms)
                                {
                                    if (customSongInfo.customEnvironment != null)
                                    {
                                        if (findCustomEnvironment(customSongInfo.customEnvironment) == -1)
                                        {
                                            Console.WriteLine("CustomPlatform not found: " + customSongInfo.customEnvironment);
                                            if (customSongInfo.customEnvironmentHash != null)
                                            {
                                                Console.WriteLine("Downloading with hash: " + customSongInfo.customEnvironmentHash);
                                                StartCoroutine(downloadCustomPlatform(customSongInfo.customEnvironmentHash, customSongInfo.customEnvironment));
                                            }
                                        }
                                    }
                                }

                                var i1 = i;
                                HMMainThreadDispatcher.instance.Enqueue(delegate
                                {
                                    if (_loadingCancelled)
                                    {
                                        return;
                                    }
                                    var level = LoadSong(customSongInfo);
                                    if (level != null)
                                    {
                                        levelList.Add(level);
                                    }

                                    LoadingProgress = i1 / songFolders.Count;
                                });
                            }
                            catch (Exception e)
                            {
                                Log("Failed to load song folder: " + result, LogSeverity.Warn);
                                Log(e.ToString(), LogSeverity.Warn);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Log("RetrieveAllSongs failed:", LogSeverity.Error);
                    Log(e.ToString(), LogSeverity.Error);
                }
            };

            Action finish = delegate
            {
                stopwatch.Stop();
                Log("Loaded " + levelList.Count + " new songs in " + stopwatch.Elapsed.Seconds + " seconds");

                CustomLevels.AddRange(levelList);
                var orderedList = CustomLevels.OrderBy(x => x.songName);
                CustomLevels = orderedList.ToList();

                foreach (var customLevel in CustomLevels)
                {
                    CustomLevelCollectionSO.AddCustomLevel(customLevel);
                }

                AreSongsLoaded  = true;
                AreSongsLoading = false;
                LoadingProgress = 1;

                _loadingTask = null;

                if (SongsLoadedEvent != null)
                {
                    SongsLoadedEvent(this, CustomLevels);
                }
            };

            _loadingTask = new HMTask(job, finish);
            _loadingTask.Run();
        }
        private void OnSceneTransitioned(Scene activeScene)
        {
            GameObject.Destroy(GameObject.Find("SongLoader Color Setter"));
            customSongColors    = IllusionPlugin.ModPrefs.GetBool("Songloader", "customSongColors", true, true);
            customSongPlatforms = IllusionPlugin.ModPrefs.GetBool("Songloader", "customSongPlatforms", true, true);
            if (AreSongsLoading)
            {
                //Scene changing while songs are loading. Since we are using a separate thread while loading, this is bad and could cause a crash.
                //So we have to stop loading.
                if (_loadingTask != null)
                {
                    _loadingTask.Cancel();
                    _loadingCancelled = true;
                    AreSongsLoading   = false;
                    LoadingProgress   = 0;
                    StopAllCoroutines();
                    _progressBar.ShowMessage("Loading cancelled\n<size=80%>Press Ctrl+R to refresh</size>");
                    Log("Loading was cancelled by player since they loaded another scene.");
                }
            }

            StartCoroutine(WaitRemoveScores());

            if (activeScene.name == MenuSceneName)
            {
                CurrentLevelPlaying = null;

                if (CustomLevelCollectionSO == null)
                {
                    var levelCollectionSO = Resources.FindObjectsOfTypeAll <LevelCollectionSO>().FirstOrDefault();
                    CustomLevelCollectionSO = CustomLevelCollectionSO.ReplaceOriginal(levelCollectionSO);
                }
                else
                {
                    CustomLevelCollectionSO.ReplaceReferences();
                }
                if (_standardLevelDetailViewController == null)
                {
                    _standardLevelDetailViewController = Resources.FindObjectsOfTypeAll <StandardLevelDetailViewController>().FirstOrDefault();
                    if (_standardLevelDetailViewController == null)
                    {
                        return;
                    }
                    _standardLevelDetailViewController.didPressPlayButtonEvent += StandardLevelDetailControllerOnDidPressPlayButtonEvent;
                }

                if (_LevelListViewController == null)
                {
                    _LevelListViewController = Resources.FindObjectsOfTypeAll <LevelListViewController>().FirstOrDefault();
                    if (_LevelListViewController == null)
                    {
                        return;
                    }

                    _LevelListViewController.didSelectLevelEvent += StandardLevelListViewControllerOnDidSelectLevelEvent;
                }



                if (_characteristicViewController == null)
                {
                    _characteristicViewController = Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSelectionViewController>().FirstOrDefault();
                    if (_characteristicViewController == null)
                    {
                        return;
                    }

                    _characteristicViewController.didSelectBeatmapCharacteristicEvent += OnDidSelectBeatmapCharacteristicEvent;
                }

                if (CustomPlatformsPresent)
                {
                    CheckForPreviousPlatform();
                }
            }
            else if (activeScene.name == GameSceneName)
            {
                _standardLevelSceneSetupData = Resources.FindObjectsOfTypeAll <StandardLevelSceneSetupDataSO>().FirstOrDefault();
                if (_standardLevelSceneSetupData == null)
                {
                    return;
                }
                var level   = _standardLevelSceneSetupData.difficultyBeatmap;
                var beatmap = level as CustomLevel.CustomDifficultyBeatmap;
                if (beatmap != null)
                {
                    CurrentLevelPlaying = beatmap;

                    //The note jump movement speed now gets set in the Start method, so we're too early here. We have to wait a bit before overriding.
                    Invoke(nameof(DelayedNoteJumpMovementSpeedFix), 0.1f);
                }

                if (NoteHitVolumeChanger.PrefabFound)
                {
                    return;
                }
                var song = CustomLevels.FirstOrDefault(x => x.levelID == level.level.levelID);
                if (song == null)
                {
                    return;
                }
                NoteHitVolumeChanger.SetVolume(song.customSongInfo.noteHitVolume, song.customSongInfo.noteMissVolume);

                //Set environment if the song has customEnvironment
                if (CustomPlatformsPresent)
                {
                    CheckCustomSongEnvironment(song);
                }
                //Set enviroment colors for the song if it has song specific colors
                if (customSongColors)
                {
                    song.SetSongColors(CurrentLevelPlaying.colorLeft, CurrentLevelPlaying.colorRight, CurrentLevelPlaying.hasCustomColors);
                }
            }
        }