private static void Postfix(ref IDifficultyBeatmap ____selectedDifficultyBeatmap, ref PlayerData ____playerData, ref UnityEngine.UI.Button ____actionButton, ref UnityEngine.UI.Button ____practiceButton) { /* ColorSchemesSettings playerSelScheme = ____playerData.colorSchemesSettings; * * bool isOverRidden = playerSelScheme.overrideDefaultColors; * int curColorID = playerSelScheme.GetSelectedColorSchemeIdx(); * playerSelScheme.GetOverrideColorScheme(); * * ColorScheme curColorScheme = playerSelScheme.GetColorSchemeForIdx(curColorID); * * Color saberA = curColorScheme.saberAColor; * Color saberB = curColorScheme.saberBColor; * Color envColor1 = curColorScheme.environmentColor0; * Color envColor2 = curColorScheme.environmentColor1; * * VideoMenu.selectedCubeColorLeft = saberA; * VideoMenu.selectedCubeColorRight = curColorScheme.saberBColor; * VideoMenu.selectedEnvColorLeft = curColorScheme.environmentColor0; * VideoMenu.selectedEnvColorRight = curColorScheme.environmentColor1; * */ // ColorSchemeView selSchemeView => playerSelScheme.GetOverrideColorScheme(); // ColorSchemeView override colorScheme = playerSelScheme.GetColorSchemeForId(playerSelScheme); // Plugin.Logger.Debug("isOverRidden ? " + isOverRidden); // Plugin.Logger.Debug("Current ID = " + curColorID); // since the user could change the color settings after selecting a beatmap, a different approach was used // to capture the current ColorScheme, that method is in ScreenColorUtils.cs // still have not figured how to find the game's default environment color list. var level = ____selectedDifficultyBeatmap.level is CustomBeatmapLevel ? ____selectedDifficultyBeatmap.level as CustomPreviewBeatmapLevel : null; if (level == null) { Plugin.Logger.Debug("hey, level == null!"); return; } var songData = Collections.RetrieveExtraSongData(SongCore.Utilities.Hashing.GetCustomLevelHash(level), level.customLevelPath); if (songData == null) { Plugin.Logger.Debug("hey, songData == null!"); return; } IDifficultyBeatmap selectedDiff = ____selectedDifficultyBeatmap; SongCore.Data.ExtraSongData.DifficultyData diffData = Collections.RetrieveDifficultyData(selectedDiff); if (diffData == null) { Plugin.Logger.Debug("hey, diffData == null!"); return; } // maps are out there with only left or right color data ... if (diffData._envColorLeft == null) // shows it is null unless initialized in the maps info.dat file. { VideoMenu.mapHasEnvLeftColor = false; // Plugin.Logger.Debug("map data had no colors"); } else { VideoMenu.mapEnvColorLeft = SongCore.Utilities.Utils.ColorFromMapColor(diffData._envColorLeft); VideoMenu.mapHasEnvLeftColor = true; // Plugin.Logger.Debug("This map has env color data"); } if (diffData._envColorRight == null) { VideoMenu.mapHasEnvRightColor = false; } else { VideoMenu.mapEnvColorRight = SongCore.Utilities.Utils.ColorFromMapColor(diffData._envColorRight); VideoMenu.mapHasEnvRightColor = true; } if (diffData._colorLeft == null) { VideoMenu.mapHasCubeLeftColor = false; } else { VideoMenu.mapCubeColorLeft = SongCore.Utilities.Utils.ColorFromMapColor(diffData._colorLeft); VideoMenu.mapHasCubeLeftColor = true; } if (diffData._colorRight == null) { VideoMenu.mapHasCubeRightColor = false; } else { VideoMenu.mapCubeColorRight = SongCore.Utilities.Utils.ColorFromMapColor(diffData._colorRight); VideoMenu.mapHasCubeRightColor = true; } }
public async void HandleSongStart() { GameStatus gameStatus = statusManager.gameStatus; // Check for multiplayer early to abort if needed: gameplay controllers don't exist in multiplayer until later multiplayerSessionManager = FindFirstOrDefaultOptional <MultiplayerSessionManager>(); multiplayerController = FindFirstOrDefaultOptional <MultiplayerController>(); if (multiplayerSessionManager && multiplayerController) { Plugin.log.Debug("Multiplayer Level loaded"); // public event Action<DisconnectedReason> MultiplayerSessionManager#disconnectedEvent; multiplayerSessionManager.disconnectedEvent += OnMultiplayerDisconnected; // public event Action<State> MultiplayerController#stateChangedEvent; multiplayerController.stateChangedEvent += OnMultiplayerStateChanged; // Do nothing until the next state change to Gameplay. if (multiplayerController.state != MultiplayerController.State.Gameplay) { return; } multiplayerLocalActivePlayerFacade = FindFirstOrDefaultOptional <MultiplayerLocalActivePlayerFacade>(); if (multiplayerLocalActivePlayerFacade != null) { multiplayerLocalActivePlayerFacade.playerDidFinishEvent += OnMultiplayerLevelFinished; } } else if (!doDelayedSongStart) { doDelayedSongStart = true; return; } // `wants_to_play_next_level` is set for players who don't want to play the song aka want to spectate aka are not "active". `isSpectating` is apparently not spectating. gameStatus.scene = multiplayerSessionManager.isSpectating || !multiplayerSessionManager.LocalPlayerHasState(NetworkConstants.wantsToPlayNextLevel) ? "Spectator" : "Song"; gameStatus.multiplayer = multiplayerSessionManager.isConnectingOrConnected; pauseController = FindFirstOrDefaultOptional <PauseController>(); scoreController = FindFirstOrDefault <ScoreController>(); gameplayManager = FindFirstOrDefaultOptional <StandardLevelGameplayManager>() as MonoBehaviour ?? FindFirstOrDefaultOptional <MissionLevelGameplayManager>(); beatmapObjectCallbackController = FindFirstOrDefault <BeatmapObjectCallbackController>(); gameplayModifiersSO = FindFirstOrDefault <GameplayModifiersModelSO>(); audioTimeSyncController = FindFirstOrDefault <AudioTimeSyncController>(); playerHeadAndObstacleInteraction = (PlayerHeadAndObstacleInteraction)scoreControllerHeadAndObstacleInteractionField.GetValue(scoreController); gameSongController = FindFirstOrDefault <GameSongController>(); gameEnergyCounter = FindFirstOrDefault <GameEnergyCounter>(); if (multiplayerController) { // NOOP } else if (gameplayManager is StandardLevelGameplayManager) { Plugin.log.Debug("Standard Level loaded"); } else if (gameplayManager is MissionLevelGameplayManager) { Plugin.log.Debug("Mission Level loaded"); } gameplayCoreSceneSetupData = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData; // Register event listeners // PauseController doesn't exist in multiplayer if (pauseController != null) { // public event Action PauseController#didPauseEvent; pauseController.didPauseEvent += OnGamePause; // public event Action PauseController#didResumeEvent; pauseController.didResumeEvent += OnGameResume; } // public ScoreController#noteWasCutEvent<NoteData, NoteCutInfo, int multiplier> // called after CutScoreBuffer is created scoreController.noteWasCutEvent += OnNoteWasCut; // public ScoreController#noteWasMissedEvent<NoteData, int multiplier> scoreController.noteWasMissedEvent += OnNoteWasMissed; // public ScoreController#scoreDidChangeEvent<int, int> // score scoreController.scoreDidChangeEvent += OnScoreDidChange; // public ScoreController#comboDidChangeEvent<int> // combo scoreController.comboDidChangeEvent += OnComboDidChange; // public ScoreController#multiplierDidChangeEvent<int, float> // multiplier, progress [0..1] scoreController.multiplierDidChangeEvent += OnMultiplierDidChange; // public event Action<BeatmapEventData> BeatmapObjectCallbackController#beatmapEventDidTriggerEvent beatmapObjectCallbackController.beatmapEventDidTriggerEvent += OnBeatmapEventDidTrigger; // public event Action GameSongController#songDidFinishEvent; gameSongController.songDidFinishEvent += OnLevelFinished; // public event Action GameEnergyCounter#gameEnergyDidReach0Event; gameEnergyCounter.gameEnergyDidReach0Event += OnEnergyDidReach0Event; if (gameplayManager is ILevelEndActions levelEndActions) { // event Action levelFailedEvent; levelEndActions.levelFailedEvent += OnLevelFailed; } IDifficultyBeatmap diff = gameplayCoreSceneSetupData.difficultyBeatmap; IBeatmapLevel level = diff.level; SongCore.Data.ExtraSongData.DifficultyData songData = SongCore.Collections.RetrieveDifficultyData(diff); gameStatus.colorLeft = songData._colorLeft; gameStatus.colorRight = songData._colorRight; gameStatus.partyMode = Gamemode.IsPartyActive; gameStatus.mode = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName; gameplayModifiers = gameplayCoreSceneSetupData.gameplayModifiers; gameplayModiferParamsList = gameplayModifiersSO.CreateModifierParamsList(gameplayModifiers); PlayerSpecificSettings playerSettings = gameplayCoreSceneSetupData.playerSpecificSettings; PracticeSettings practiceSettings = gameplayCoreSceneSetupData.practiceSettings; float songSpeedMul = gameplayModifiers.songSpeedMul; if (practiceSettings != null) { songSpeedMul = practiceSettings.songSpeedMul; } // Generate NoteData to id mappings for backwards compatiblity with <1.12.1 noteToIdMapping = new NoteData[diff.beatmapData.cuttableNotesType + diff.beatmapData.bombsCount]; lastNoteId = 0; int beatmapObjectId = 0; var beatmapObjectsData = diff.beatmapData.beatmapObjectsData; foreach (BeatmapObjectData beatmapObjectData in beatmapObjectsData) { if (beatmapObjectData is NoteData noteData) { noteToIdMapping[beatmapObjectId++] = noteData; } } gameStatus.songName = level.songName; gameStatus.songSubName = level.songSubName; gameStatus.songAuthorName = level.songAuthorName; gameStatus.levelAuthorName = level.levelAuthorName; gameStatus.songBPM = level.beatsPerMinute; gameStatus.noteJumpSpeed = diff.noteJumpMovementSpeed; // 13 is "custom_level_" and 40 is the magic number for the length of the SHA-1 hash gameStatus.songHash = level.levelID.StartsWith("custom_level_") && !level.levelID.EndsWith(" WIP") ? level.levelID.Substring(13, 40) : null; gameStatus.levelId = level.levelID; gameStatus.songTimeOffset = (long)(level.songTimeOffset * 1000f / songSpeedMul); gameStatus.length = (long)(level.beatmapLevelData.audioClip.length * 1000f / songSpeedMul); gameStatus.start = GetCurrentTime() - (long)(audioTimeSyncController.songTime * 1000f / songSpeedMul); if (practiceSettings != null) { gameStatus.start -= (long)(practiceSettings.startSongTime * 1000f / songSpeedMul); } gameStatus.paused = 0; gameStatus.difficulty = diff.difficulty.Name(); gameStatus.notesCount = diff.beatmapData.cuttableNotesType; gameStatus.bombsCount = diff.beatmapData.bombsCount; gameStatus.obstaclesCount = diff.beatmapData.obstaclesCount; gameStatus.environmentName = level.environmentInfo.sceneInfo.sceneName; try { // From https://support.unity3d.com/hc/en-us/articles/206486626-How-can-I-get-pixels-from-unreadable-textures- var texture = (await level.GetCoverImageAsync(CancellationToken.None)).texture; var active = RenderTexture.active; var temporary = RenderTexture.GetTemporary( texture.width, texture.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear ); Graphics.Blit(texture, temporary); RenderTexture.active = temporary; var cover = new Texture2D(texture.width, texture.height); cover.ReadPixels(new Rect(0, 0, temporary.width, temporary.height), 0, 0); cover.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); gameStatus.songCover = System.Convert.ToBase64String( ImageConversion.EncodeToPNG(cover) ); } catch { gameStatus.songCover = null; } gameStatus.ResetPerformance(); UpdateModMultiplier(); gameStatus.songSpeedMultiplier = songSpeedMul; gameStatus.batteryLives = gameEnergyCounter.batteryLives; gameStatus.modObstacles = gameplayModifiers.enabledObstacleType.ToString(); gameStatus.modInstaFail = gameplayModifiers.instaFail; gameStatus.modNoFail = gameplayModifiers.noFailOn0Energy; gameStatus.modBatteryEnergy = gameplayModifiers.energyType == GameplayModifiers.EnergyType.Battery; gameStatus.modDisappearingArrows = gameplayModifiers.disappearingArrows; gameStatus.modNoBombs = gameplayModifiers.noBombs; gameStatus.modSongSpeed = gameplayModifiers.songSpeed.ToString(); gameStatus.modNoArrows = gameplayModifiers.noArrows; gameStatus.modGhostNotes = gameplayModifiers.ghostNotes; gameStatus.modFailOnSaberClash = gameplayModifiers.failOnSaberClash; gameStatus.modStrictAngles = gameplayModifiers.strictAngles; gameStatus.modFastNotes = gameplayModifiers.fastNotes; gameStatus.modSmallNotes = gameplayModifiers.smallCubes; gameStatus.modProMode = gameplayModifiers.proMode; gameStatus.modZenMode = gameplayModifiers.zenMode; var environmentEffectsFilterPreset = diff.difficulty == BeatmapDifficulty.ExpertPlus ? playerSettings.environmentEffectsFilterExpertPlusPreset : playerSettings.environmentEffectsFilterDefaultPreset; // Backwards compatibility for <1.13.4 gameStatus.staticLights = environmentEffectsFilterPreset != EnvironmentEffectsFilterPreset.AllEffects; gameStatus.leftHanded = playerSettings.leftHanded; gameStatus.playerHeight = playerSettings.playerHeight; gameStatus.sfxVolume = playerSettings.sfxVolume; gameStatus.reduceDebris = playerSettings.reduceDebris; gameStatus.noHUD = playerSettings.noTextsAndHuds; gameStatus.advancedHUD = playerSettings.advancedHud; gameStatus.autoRestart = playerSettings.autoRestart; gameStatus.saberTrailIntensity = playerSettings.saberTrailIntensity; gameStatus.environmentEffects = environmentEffectsFilterPreset.ToString(); gameStatus.hideNoteSpawningEffect = playerSettings.hideNoteSpawnEffect; statusManager.EmitStatusUpdate(ChangedProperties.AllButNoteCut, "songStart"); }