diff --git a/HttpSiraStatus/Enums/EventEnum.cs b/HttpSiraStatus/Enums/EventEnum.cs index 2d0029c..7e18831 100644 --- a/HttpSiraStatus/Enums/EventEnum.cs +++ b/HttpSiraStatus/Enums/EventEnum.cs @@ -102,8 +102,10 @@ public enum V3BeatmapEventType Unknown, BPM, ColorBoost, + FloatFx, LightColor, LightRotation, + LightTranslation, SpawnRotation } } diff --git a/HttpSiraStatus/Extentions/SaberMovementDataExtentions.cs b/HttpSiraStatus/Extentions/SaberMovementDataExtentions.cs index fde872d..1ddbde8 100644 --- a/HttpSiraStatus/Extentions/SaberMovementDataExtentions.cs +++ b/HttpSiraStatus/Extentions/SaberMovementDataExtentions.cs @@ -4,12 +4,17 @@ namespace HttpSiraStatus.Extentions { public static class SaberMovementDataExtentions { + public static float ComputeSwingRatingEx(this ISaberMovementData data) + { + return data.ComputeSwingRatingEx(false, 0); + } + /// /// BeatLeaderのパッチ除け /// /// /// - public static float ComputeSwingRatingEx(this ISaberMovementData data) + public static float ComputeSwingRatingEx(this ISaberMovementData data, bool overrideSegmenAngle, float overrideValue) { if (data is SaberMovementData saberMovementData) { if (saberMovementData._validCount < 2) { @@ -24,7 +29,7 @@ public static float ComputeSwingRatingEx(this ISaberMovementData data) var num3 = time; var num4 = 0f; var segmentNormal = saberMovementData._data[num2].segmentNormal; - var angleDiff = saberMovementData._data[num2].segmentAngle; + var angleDiff = overrideSegmenAngle ? overrideValue : saberMovementData._data[num2].segmentAngle; var num5 = 2; num4 += SaberSwingRating.BeforeCutStepRating(angleDiff, 0f); while (time - num3 < 0.4f && num5 < saberMovementData._validCount) { diff --git a/HttpSiraStatus/HttpSiraStatus.csproj b/HttpSiraStatus/HttpSiraStatus.csproj index 0bb245c..4219ab0 100644 --- a/HttpSiraStatus/HttpSiraStatus.csproj +++ b/HttpSiraStatus/HttpSiraStatus.csproj @@ -15,7 +15,7 @@ ..\Refs $(LocalRefsDir) prompt - 11.0.0 + 12.0.0 4 $(ReferencePath) @@ -59,6 +59,17 @@ False False + + $(BeatSaberDir)\Beat Saber_Data\Managed\BGNetCore.dll + False + False + + + $(BeatSaberDir)\Beat Saber_Data\Managed\DataModels.dll + False + False + True + $(BeatSaberDir)\Libs\Hive.Versioning.dll diff --git a/HttpSiraStatus/Interfaces/IGameStatus.cs b/HttpSiraStatus/Interfaces/IGameStatus.cs index d737434..dd9dbf8 100644 --- a/HttpSiraStatus/Interfaces/IGameStatus.cs +++ b/HttpSiraStatus/Interfaces/IGameStatus.cs @@ -36,6 +36,8 @@ public interface IGameStatus bool leftHanded { get; } long length { get; } string levelAuthorName { get; } + string[] levelAuthorNamesArray { get; } + string[] lighterNamesArray { get; } string levelId { get; } int maxCombo { get; } string maxRank { get; } diff --git a/HttpSiraStatus/Models/GamePlayDataManager.cs b/HttpSiraStatus/Models/GamePlayDataManager.cs index 83cfaf1..7065d17 100644 --- a/HttpSiraStatus/Models/GamePlayDataManager.cs +++ b/HttpSiraStatus/Models/GamePlayDataManager.cs @@ -1,4 +1,5 @@ -using HttpSiraStatus.Configuration; +using HarmonyLib; +using HttpSiraStatus.Configuration; using HttpSiraStatus.Enums; using HttpSiraStatus.Extentions; using HttpSiraStatus.Interfaces; @@ -380,6 +381,8 @@ public void DespawnScoringElement(ScoringElement scoringElement) private NoteDataEntity.Pool _notePool; private SliderDataEntity.Pool _sliderPool; private GameplayCoreSceneSetupData _gameplayCoreSceneSetupData; + private BeatmapLevel _beatmapLevel; + private BeatmapKey _beatmapKey; private PauseController _pauseController; private IScoreController _scoreController; private IComboController _comboController; @@ -449,6 +452,8 @@ private void Constractor( SliderDataEntity.Pool sliderDataEntityPool, CutScoreInfoEntity.Pool cutScoreInfoEntityPool, GameplayCoreSceneSetupData gameplayCoreSceneSetupData, + BeatmapLevel beatmapLevel, + BeatmapKey beatmapKey, IScoreController score, IComboController comboController, GameplayModifiers gameplayModifiers, @@ -471,6 +476,8 @@ private void Constractor( this._notePool = noteDataEntityPool; this._sliderPool = sliderDataEntityPool; this._gameplayCoreSceneSetupData = gameplayCoreSceneSetupData; + this._beatmapLevel = beatmapLevel; + this._beatmapKey = beatmapKey; this._scoreController = score; this._gameplayModifiers = gameplayModifiers; this._audioTimeSource = audioTimeSource; @@ -607,8 +614,9 @@ public async Task InitializeAsync(CancellationToken token) this._levelEndActions.levelFinishedEvent += this.OnLevelFinished; this._levelEndActions.levelFailedEvent += this.OnLevelFailed; } - var diff = this._gameplayCoreSceneSetupData.difficultyBeatmap; - var level = diff.level; + //var diff = this._gameplayCoreSceneSetupData..difficultyBeatmap; + var level = this._beatmapLevel; + var beatmapData = level.GetDifficultyBeatmapData(this._beatmapKey.beatmapCharacteristic, this._beatmapKey.difficulty); this._gameplayModifiers = this._gameplayCoreSceneSetupData.gameplayModifiers; var playerSettings = this._gameplayCoreSceneSetupData.playerSpecificSettings; @@ -621,29 +629,31 @@ public async Task InitializeAsync(CancellationToken token) this._gameStatus.songName = level.songName; this._gameStatus.songSubName = level.songSubName; this._gameStatus.songAuthorName = level.songAuthorName; - this._gameStatus.levelAuthorName = level.levelAuthorName; + this._gameStatus.levelAuthorName = string.Join(",", level.allMappers); + this._gameStatus.levelAuthorNamesArray = level.allMappers; + this._gameStatus.lighterNamesArray = level.allLighters; this._gameStatus.songBPM = level.beatsPerMinute; - this._gameStatus.noteJumpSpeed = diff.noteJumpMovementSpeed; - this._gameStatus.noteJumpStartBeatOffset = diff.noteJumpStartBeatOffset; + this._gameStatus.noteJumpSpeed = beatmapData.noteJumpMovementSpeed; + this._gameStatus.noteJumpStartBeatOffset = beatmapData.noteJumpStartBeatOffset; // 13 is "custom_level_" and 40 is the magic number for the length of the SHA-1 hash this._gameStatus.songHash = Regex.IsMatch(level.levelID, "^custom_level_[0-9A-F]{40}", RegexOptions.IgnoreCase) && !level.levelID.EndsWith(" WIP") ? level.levelID.Substring(13, 40) : null; this._gameStatus.levelId = level.levelID; this._gameStatus.songTimeOffset = (long)(level.songTimeOffset * 1000f / songSpeedMul); - this._gameStatus.length = (long)(level.beatmapLevelData.audioClip.length * 1000f / songSpeedMul); + this._gameStatus.length = (long)(_gameplayCoreSceneSetupData.songAudioClip.length * 1000f / songSpeedMul); this._gameStatus.start = Utility.GetCurrentTime() - (long)(this._audioTimeSource.songTime * 1000f / songSpeedMul); if (practiceSettings != null) { this._gameStatus.start -= (long)(practiceSettings.startSongTime * 1000f / songSpeedMul); } this._gameStatus.paused = 0; - this._gameStatus.difficulty = diff.difficulty.Name(); - this._gameStatus.difficultyEnum = Enum.GetName(typeof(BeatmapDifficulty), diff.difficulty); - this._gameStatus.characteristic = diff.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName; - var beatmapData = await diff.GetBeatmapDataBasicInfoAsync().ConfigureAwait(true); - this._gameStatus.notesCount = beatmapData.cuttableNotesCount; + this._gameStatus.difficulty = this._beatmapKey.difficulty.Name(); + this._gameStatus.difficultyEnum = Enum.GetName(typeof(BeatmapDifficulty), this._beatmapKey.difficulty); + this._gameStatus.characteristic = _beatmapKey.beatmapCharacteristic.serializedName; + //var beatmapData = await beatmapData.GetBeatmapDataBasicInfoAsync().ConfigureAwait(true); + this._gameStatus.notesCount = beatmapData.notesCount; this._gameStatus.bombsCount = beatmapData.bombsCount; this._gameStatus.obstaclesCount = beatmapData.obstaclesCount; - this._gameStatus.environmentName = level.environmentInfo.sceneInfo.sceneName; + this._gameStatus.environmentName = beatmapData.environmentName.ToString(); var colorScheme = this._gameplayCoreSceneSetupData.colorScheme ?? new ColorScheme(this._gameplayCoreSceneSetupData.environmentInfo.colorScheme); this._gameStatus.colorSaberA = colorScheme.saberAColor; this._gameStatus.colorSaberB = colorScheme.saberBColor; @@ -661,8 +671,7 @@ public async Task InitializeAsync(CancellationToken token) // From https://support.unity3d.com/hc/en-us/articles/206486626-How-can-I-get-pixels-from-unreadable-textures- // Modified to correctly handle texture atlases. Fixes #82. var active = RenderTexture.active; - - var sprite = await level.GetCoverImageAsync(CancellationToken.None); + var sprite = await level.previewMediaData.GetCoverSpriteAsync(token); var texture = sprite.texture; var temporary = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear); @@ -712,7 +721,7 @@ public async Task InitializeAsync(CancellationToken token) this._gameStatus.modProMode = this._gameplayModifiers.proMode; this._gameStatus.modZenMode = this._gameplayModifiers.zenMode; - this._gameStatus.staticLights = (diff.difficulty == BeatmapDifficulty.ExpertPlus ? playerSettings.environmentEffectsFilterExpertPlusPreset : playerSettings.environmentEffectsFilterDefaultPreset) != EnvironmentEffectsFilterPreset.AllEffects; + this._gameStatus.staticLights = (this._beatmapKey.difficulty == BeatmapDifficulty.ExpertPlus ? playerSettings.environmentEffectsFilterExpertPlusPreset : playerSettings.environmentEffectsFilterDefaultPreset) != EnvironmentEffectsFilterPreset.AllEffects; this._gameStatus.leftHanded = playerSettings.leftHanded; this._gameStatus.playerHeight = playerSettings.playerHeight; this._gameStatus.sfxVolume = playerSettings.sfxVolume; @@ -721,7 +730,7 @@ public async Task InitializeAsync(CancellationToken token) this._gameStatus.advancedHUD = playerSettings.advancedHud; this._gameStatus.autoRestart = playerSettings.autoRestart; this._gameStatus.saberTrailIntensity = playerSettings.saberTrailIntensity; - this._gameStatus.environmentEffects = (diff.difficulty == BeatmapDifficulty.ExpertPlus ? playerSettings.environmentEffectsFilterExpertPlusPreset : playerSettings.environmentEffectsFilterDefaultPreset).ToString(); + this._gameStatus.environmentEffects = (this._beatmapKey.difficulty == BeatmapDifficulty.ExpertPlus ? playerSettings.environmentEffectsFilterExpertPlusPreset : playerSettings.environmentEffectsFilterDefaultPreset).ToString(); this._gameStatus.hideNoteSpawningEffect = playerSettings.hideNoteSpawnEffect; // Generate NoteData to id mappings for backwards compatiblity with <1.12.1 this._noteToIdMapping.Clear(); @@ -765,8 +774,10 @@ void __SetupMapping() break; case BPMChangeBeatmapEventData bpm: case ColorBoostBeatmapEventData color: + case FloatFxBeatmapEventData floatFx: case LightColorBeatmapEventData lightColor: case LightRotationBeatmapEventData lightRotation: + case LightTranslationBeatmapEventData lightTranslation: case SpawnRotationBeatmapEventData spawn: default: info = new V3BeatmapEventInfomation(); diff --git a/HttpSiraStatus/Models/GameStatus.cs b/HttpSiraStatus/Models/GameStatus.cs index 1d5c13c..9cfbd13 100644 --- a/HttpSiraStatus/Models/GameStatus.cs +++ b/HttpSiraStatus/Models/GameStatus.cs @@ -1,5 +1,6 @@ using HttpSiraStatus.Enums; using HttpSiraStatus.Interfaces; +using System; using UnityEngine; namespace HttpSiraStatus.Models @@ -17,6 +18,8 @@ internal class GameStatus : IGameStatus public string songSubName { get; internal set; } = null; public string songAuthorName { get; internal set; } = null; public string levelAuthorName { get; internal set; } = null; + public string[] levelAuthorNamesArray { get; internal set; } = Array.Empty(); + public string[] lighterNamesArray { get; internal set; } = Array.Empty(); public string songCover { get; internal set; } = null; public string songHash { get; internal set; } = null; public string levelId { get; internal set; } = null; @@ -99,12 +102,15 @@ internal class GameStatus : IGameStatus public float saberTrailIntensity { get; internal set; } = 0.5f; public string environmentEffects { get; internal set; } = EnvironmentEffectsFilterPreset.AllEffects.ToString(); public bool hideNoteSpawningEffect { get; internal set; } = false; + + public void ResetMapInfo() { this.songName = null; this.songSubName = null; this.songAuthorName = null; this.levelAuthorName = null; + this.levelAuthorNamesArray = Array.Empty(); this.songCover = null; this.songHash = null; this.levelId = null; diff --git a/HttpSiraStatus/Models/StatusManager.cs b/HttpSiraStatus/Models/StatusManager.cs index ecb30de..3e85954 100644 --- a/HttpSiraStatus/Models/StatusManager.cs +++ b/HttpSiraStatus/Models/StatusManager.cs @@ -155,7 +155,17 @@ private void UpdateBeatmapJSON() beatmapJSON["songName"] = this.StringOrNull(this._gameStatus.songName); beatmapJSON["songSubName"] = this.StringOrNull(this._gameStatus.songSubName); beatmapJSON["songAuthorName"] = this.StringOrNull(this._gameStatus.songAuthorName); - beatmapJSON["levelAuthorName"] = this.StringOrNull(this._gameStatus.levelAuthorName); + beatmapJSON["levelAuthorName"] = this._gameStatus.levelAuthorName; + var mappers = new JSONArray(); + foreach (var name in this._gameStatus.levelAuthorNamesArray) { + mappers.Add(name); + } + beatmapJSON["levelAuthorNamesArray"] = mappers; + var lighters = new JSONArray(); + foreach (var name in this._gameStatus.lighterNamesArray) { + lighters.Add(name); + } + beatmapJSON["lighterNamesArray"] = lighters; beatmapJSON["songCover"] = string.IsNullOrEmpty(this._gameStatus.songCover) ? JSONNull.CreateOrGet() : new JSONString(this._gameStatus.songCover); beatmapJSON["songHash"] = this.StringOrNull(this._gameStatus.songHash); beatmapJSON["levelId"] = this.StringOrNull(this._gameStatus.levelId); diff --git a/HttpSiraStatus/Models/V3BeatmapEventInfomation.cs b/HttpSiraStatus/Models/V3BeatmapEventInfomation.cs index a2a8165..ec9742e 100644 --- a/HttpSiraStatus/Models/V3BeatmapEventInfomation.cs +++ b/HttpSiraStatus/Models/V3BeatmapEventInfomation.cs @@ -24,6 +24,10 @@ internal class V3BeatmapEventInfomation : IBeatmapEventInformation public bool BoostColorsAreOn { get; private set; } #endregion + #region FlaotFx + public float Value { get; private set; } + #endregion + #region LightCommon public int GroupId { get; private set; } = -1; public int ElementId { get; private set; } = -1; @@ -31,14 +35,19 @@ internal class V3BeatmapEventInfomation : IBeatmapEventInformation #region LightColor public BeatmapEventTransitionType TransitionType { get; private set; } + public EaseType EaseType { get; private set; } public EnvironmentColorType ColorType { get; private set; } public float Brightness { get; private set; } public int StrobeBeatFrequency { get; private set; } #endregion + #region LightTransaction + public float Translation { get; private set; } + public float Distribution { get; private set; } + #endregion + #region LightRotation public bool UsePreviousEventValue { get; private set; } - public EaseType EaseType { get; private set; } public LightAxis Axis { get; private set; } public int LoopCount { get; private set; } public LightRotationDirection RotationDirection { get; private set; } @@ -66,11 +75,16 @@ public void Init(BeatmapEventData eventData, bool isChild) this.BeatmapEventType = V3BeatmapEventType.ColorBoost; this.BoostColorsAreOn = color.boostColorsAreOn; break; + case FloatFxBeatmapEventData floatFxBeatmapEventData: + this.BeatmapEventType = V3BeatmapEventType.FloatFx; + this.Value = floatFxBeatmapEventData.value; + this.EaseType = floatFxBeatmapEventData.easeType; + break; case LightColorBeatmapEventData lightColor: this.BeatmapEventType = V3BeatmapEventType.LightColor; this.GroupId = lightColor.groupId; this.ElementId = lightColor.elementId; - this.TransitionType = lightColor.transitionType; + this.EaseType = lightColor.easeType; this.ColorType = lightColor.colorType; this.Brightness = lightColor.brightness; this.StrobeBeatFrequency = lightColor.strobeBeatFrequency; @@ -86,6 +100,16 @@ public void Init(BeatmapEventData eventData, bool isChild) this.RotationDirection = lightRotation.rotationDirection; this.Rotation = lightRotation.rotation; break; + case LightTranslationBeatmapEventData lightTranslation: + this.BeatmapEventType = V3BeatmapEventType.LightTranslation; + this.GroupId = lightTranslation.groupId; + this.ElementId = lightTranslation.elementId; + this.UsePreviousEventValue = lightTranslation.usePreviousEventValue; + this.EaseType = lightTranslation.easeType; + this.Axis = lightTranslation.axis; + this.Translation = lightTranslation.translation; + this.Distribution = lightTranslation.distribution; + break; case SpawnRotationBeatmapEventData spawn: this.BeatmapEventType = V3BeatmapEventType.SpawnRotation; this.Rotation = spawn.rotation; @@ -122,6 +146,9 @@ public void Reset() this.previousSameTypeEventData = null; this.nextSameTypeEventData?.Reset(); this.nextSameTypeEventData = null; + this.Value = 0; + this.Translation = 0; + this.Distribution = 0; this.ApplyValuesToJson(false); } @@ -140,6 +167,10 @@ private void ApplyValuesToJson(bool isChild) case V3BeatmapEventType.ColorBoost: result["boostColorsAreOn"] = this.BoostColorsAreOn; break; + case V3BeatmapEventType.FloatFx: + result["value"] = this.Value; + result["easeType"] = $"{this.EaseType}"; + break; case V3BeatmapEventType.LightColor: result["groupId"] = this.GroupId; result["elementId"] = this.ElementId; @@ -158,6 +189,15 @@ private void ApplyValuesToJson(bool isChild) result["rotationDirection"] = $"{this.RotationDirection}"; result["rotation"] = this.Rotation; break; + case V3BeatmapEventType.LightTranslation: + result["groupId"] = this.GroupId; + result["elementId"] = this.ElementId; + result["usePreviousEventValue"] = this.UsePreviousEventValue; + result["easeType"] = $"{this.EaseType}"; + result["axis"] = $"{this.Axis}"; + result["translation"] = $"{this.Translation}"; + result["distribution"] = $"{this.Distribution}"; + break; case V3BeatmapEventType.SpawnRotation: result["rotation"] = this.Rotation; break; diff --git a/HttpSiraStatus/manifest.json b/HttpSiraStatus/manifest.json index 97a2673..48b6562 100644 --- a/HttpSiraStatus/manifest.json +++ b/HttpSiraStatus/manifest.json @@ -2,10 +2,10 @@ "$schema": "https://raw.githubusercontent.com/bsmg/BSIPA-MetadataFileSchema/master/Schema.json", "author": "denpadokei", "description": "This plugin exposes information about the current game status, live over a WebSocket and over HTTP.", - "gameVersion": "1.34.0", + "gameVersion": "1.35.0", "id": "HttpSiraStatus", "name": "HttpSiraStatus", - "version": "11.0.0", + "version": "12.0.0", "dependsOn": { "BSIPA": "^4.3.2", "SiraUtil": "^3.1.6" diff --git a/protocol.md b/protocol.md index 0c226e6..6bd6cb7 100644 --- a/protocol.md +++ b/protocol.md @@ -53,6 +53,8 @@ Use this path to connect to the WebSocket. The WebSocket will send the [hello ev "songSubName": String, // Song sub name "songAuthorName": String, // Song author name "levelAuthorName": String, // Beatmap author name + "levelAuthorNamesArray": String[], // Beatmap author names + "lighterNamesArray": String[], // Beatmap lighter names "songCover": null | String, // Base64 encoded PNG image of the song cover "songHash": String, // Unique beatmap identifier. Same for all difficulties. Is extracted from the levelId and will return null for OST and WIP songs. "levelId": String, // Raw levelId for a song. Same for all difficulties. @@ -254,9 +256,11 @@ public enum V3BeatmapEventType Unknown = 0, BPM = 1, ColorBoost = 2, - LightColor = 3, - LightRotation = 4, - SpawnRotation = 5 + FloatFx = 3, + LightColor = 4, + LightRotation = 5, + LightTranslation = 6, + SpawnRotation = 7 } ``` @@ -384,4 +388,4 @@ Contains only the `performance` property of [Status object](#status-object). Fired when a beatmap event is triggered. Beatmap events include changing light colors, light rotation speed and moving the square rings. -Contains only a `beatmapEvent` property as described in [Beatmap event object](#beatmap-event-object). \ No newline at end of file +Contains only a `beatmapEvent` property as described in [Beatmap event object](#beatmap-event-object).