Skip to content

Commit

Permalink
Core features 1.36.0 fix
Browse files Browse the repository at this point in the history
  • Loading branch information
qe201020335 committed Apr 24, 2024
1 parent 4f57c7f commit 8ab3e85
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 35 deletions.
4 changes: 2 additions & 2 deletions SongPlayHistory/Model/LevelMapKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ internal LevelMapKey(string levelId, string characteristicName, BeatmapDifficult
Difficulty = difficulty;
}

public LevelMapKey(IDifficultyBeatmap beatmap)
: this(beatmap.level.levelID, beatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName, beatmap.difficulty)
public LevelMapKey(BeatmapKey beatmap)
: this(beatmap.levelId, beatmap.beatmapCharacteristic.serializedName, beatmap.difficulty)
{
}

Expand Down
2 changes: 1 addition & 1 deletion SongPlayHistory/SongPlayData/IRecordManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace SongPlayHistory.SongPlayData;

public interface IRecordManager
{
public IList<ISongPlayRecord> GetRecords(IDifficultyBeatmap beatmap);
public IList<ISongPlayRecord> GetRecords(BeatmapKey beatmap);

public IList<ISongPlayRecord> GetRecords(LevelMapKey key);

Expand Down
2 changes: 1 addition & 1 deletion SongPlayHistory/SongPlayData/IScoringCacheManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ namespace SongPlayHistory.SongPlayData;

public interface IScoringCacheManager
{
public Task<LevelScoringCache> GetScoringInfo(IDifficultyBeatmap beatmap, CancellationToken cancellationToken = new());
public Task<LevelScoringCache> GetScoringInfo(BeatmapKey beatmapKey, BeatmapLevel? beatmapLevel = null, CancellationToken cancellationToken = new());
}
10 changes: 5 additions & 5 deletions SongPlayHistory/SongPlayData/RecordsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ private void OnLevelFinished(object scene, LevelFinishedEventArgs eventArgs)

if (eventArgs.LevelType == LevelType.Multiplayer)
{
var beatmap = ((MultiplayerLevelScenesTransitionSetupDataSO)scene).difficultyBeatmap;
var beatmap = ((MultiplayerLevelScenesTransitionSetupDataSO)scene).beatmapKey;
SaveRecord(beatmap, result, true, energyDidReach0, failRecord);
}
else
Expand All @@ -136,12 +136,12 @@ private void OnLevelFinished(object scene, LevelFinishedEventArgs eventArgs)
Log.Info("It was in practice or party mode, ignored.");
return;
}
var beatmap = ((StandardLevelScenesTransitionSetupDataSO)scene).difficultyBeatmap;
var beatmap = ((StandardLevelScenesTransitionSetupDataSO)scene).beatmapKey;
SaveRecord(beatmap, result, false, energyDidReach0, failRecord);
}
}

public IList<ISongPlayRecord> GetRecords(IDifficultyBeatmap beatmap)
public IList<ISongPlayRecord> GetRecords(BeatmapKey beatmap)
{
var key = new LevelMapKey(beatmap);
return GetRecords(key);
Expand All @@ -160,7 +160,7 @@ public IList<ISongPlayRecord> GetRecords(LevelMapKey key)
return new List<ISongPlayRecord>();
}

private void SaveRecord(IDifficultyBeatmap? beatmap, LevelCompletionResults? result, bool isMultiplayer, bool energyDidReach0, ScoreRecord? failRecord)
private void SaveRecord(BeatmapKey? beatmap, LevelCompletionResults? result, bool isMultiplayer, bool energyDidReach0, ScoreRecord? failRecord)
{
if (beatmap == null || result == null)
{
Expand Down Expand Up @@ -235,7 +235,7 @@ private void SaveRecord(IDifficultyBeatmap? beatmap, LevelCompletionResults? res

_logger.Info($"Saving result. Record: {record}");

var key = new LevelMapKey(beatmap).ToOldKey();
var key = new LevelMapKey(beatmap.Value).ToOldKey();

if (!Records.ContainsKey(key))
{
Expand Down
60 changes: 52 additions & 8 deletions SongPlayHistory/SongPlayData/ScoringCacheManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,78 @@ internal class ScoringCacheManager: IScoringCacheManager
[Inject]
private readonly PlayerDataModel _playerDataModel = null!;

[Inject]
private readonly BeatmapLevelsModel _beatmapLevelsModel = null!;

[Inject]
private readonly BeatmapDataLoader _beatmapDataLoader = null!;

[Inject]
private readonly EnvironmentsListModel _environmentListModel = null!;

[Inject]
private readonly SiraLog _logger = null!;

//TODO use persistent storage cache if needed
private readonly Dictionary<LevelMapKey, LevelScoringCache> _cache = new Dictionary<LevelMapKey, LevelScoringCache>();

public async Task<LevelScoringCache> GetScoringInfo(IDifficultyBeatmap beatmap, CancellationToken cancellationToken = new())
public async Task<LevelScoringCache> GetScoringInfo(BeatmapKey beatmapKey, BeatmapLevel? beatmapLevel = null, CancellationToken cancellationToken = new())
{
_logger.Debug($"Get scoring cache from Thread {Environment.CurrentManagedThreadId}");
var key = new LevelMapKey(beatmap);
var cacheKey = new LevelMapKey(beatmapKey);

lock (_cache)
{
if (_cache.TryGetValue(key, out var cache))
if (_cache.TryGetValue(cacheKey, out var cache))
{
return cache;
}
}

cancellationToken.ThrowIfCancellationRequested();
// await Task.Delay(15000, cancellationToken); // simulate am extreme loading time
// await Task.Delay(15000, cancellationToken); // simulate an extreme loading time

if (beatmapLevel == null)
{
_logger.Warn("BeatmapLevel is null, getting from BeatmapLevelsModel.");
beatmapLevel = _beatmapLevelsModel.GetBeatmapLevel(beatmapKey.levelId);
if (beatmapLevel == null)
{
_logger.Error("Failed to get BeatmapLevel.");
throw new Exception("Failed to get BeatmapLevel.");
}
}

_logger.Debug("Loading beat map level data from BeatmapLevelsModel.");
var loadResult = await _beatmapLevelsModel.LoadBeatmapLevelDataAsync(beatmapKey.levelId, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
if (loadResult.isError)
{
_logger.Error("Failed to get BeatmapLevelData.");
throw new Exception("Failed to load beat map level data.");
}

var beatmapLevelData = loadResult.beatmapLevelData!;

var beatmapData = await beatmap.GetBeatmapDataAsync(beatmap.GetEnvironmentInfo(), _playerDataModel.playerData.playerSpecificSettings);
var basicBeatmapData = beatmapLevel.GetDifficultyBeatmapData(beatmapKey.beatmapCharacteristic, beatmapKey.difficulty);
var envName = basicBeatmapData.environmentName;
var envInfo = _environmentListModel.GetEnvironmentInfoBySerializedNameSafe(envName);
var beatmapData = await _beatmapDataLoader.LoadBeatmapDataAsync(
beatmapLevelData,
beatmapKey,
beatmapLevel.beatsPerMinute,
false, //environmentName == this.environmentInfo.serializedName,
envInfo, // do we need to consider player env override?
_playerDataModel.playerData.gameplayModifiers,
_playerDataModel.playerData.playerSpecificSettings,
true);

cancellationToken.ThrowIfCancellationRequested();
var notesCount = beatmapData.cuttableNotesCount;

var notesCount = basicBeatmapData.notesCount;
var fullMaxScore = ScoreModel.ComputeMaxMultipliedScoreForBeatmap(beatmapData);
// we can use the original v2 scoring method to calculate the adjusted max score if there is no slider or burst
var isV2Score = !beatmapData.GetBeatmapDataItems<SliderData>(0).Any();
var isV2Score = !beatmapData!.GetBeatmapDataItems<SliderData>(0).Any();
cancellationToken.ThrowIfCancellationRequested();

var newCache = new LevelScoringCache
Expand All @@ -54,7 +98,7 @@ internal class ScoringCacheManager: IScoringCacheManager
lock (_cache)
{
// write cache
_cache[key] = newCache;
_cache[cacheKey] = newCache;
}
cancellationToken.ThrowIfCancellationRequested();

Expand Down
5 changes: 4 additions & 1 deletion SongPlayHistory/SongPlayHistory.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
<Reference Include="0Harmony" HintPath="$(BeatSaberDir)\Libs\0Harmony.dll" />
<Reference Include="BeatmapCore" HintPath="$(BeatSaberDir)\Beat Saber_Data\Managed\BeatmapCore.dll" />
<Reference Include="BeatSaverVoting" HintPath="$(BeatSaberDir)\Plugins\BeatSaverVoting.dll" />
<Reference Include="BGLib.AppFlow" HintPath="$(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.AppFlow.dll" />
<Reference Include="BGLib.Polyglot" HintPath="$(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.Polyglot.dll" />
<Reference Include="BGLib.UnityExtension" HintPath="$(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.UnityExtension.dll" />
<Reference Include="DataModels" HintPath="$(BeatSaberDir)\Beat Saber_Data\Managed\DataModels.dll" />
<Reference Include="Hive.Versioning" HintPath="$(BeatSaberDir)\Libs\Hive.Versioning.dll" />
<Reference Include="Main" HintPath="$(BeatSaberDir)\Beat Saber_Data\Managed\Main.dll" Publicize="true" />
<Reference Include="Newtonsoft.Json" HintPath="$(BeatSaberDir)\Libs\Newtonsoft.Json.dll" />
Expand All @@ -26,7 +30,6 @@
<Reference Include="HMUI" HintPath="$(BeatSaberDir)\Beat Saber_Data\Managed\HMUI.dll" Publicize="true" />
<Reference Include="HMLib" HintPath="$(BeatSaberDir)\Beat Saber_Data\Managed\HMLib.dll" />
<Reference Include="IPA.Loader" HintPath="$(BeatSaberDir)\Beat Saber_Data\Managed\IPA.Loader.dll" />
<Reference Include="Polyglot" HintPath="$(BeatSaberDir)\Beat Saber_Data\Managed\Polyglot.dll" />
<Reference Include="SiraUtil" HintPath="$(BeatSaberDir)\Plugins\SiraUtil.dll" />
<Reference Include="SongCore" HintPath="$(BeatSaberDir)\Plugins\SongCore.dll" />
<Reference Include="Unity.TextMeshPro" HintPath="$(BeatSaberDir)\Beat Saber_Data\Managed\Unity.TextMeshPro.dll" />
Expand Down
36 changes: 19 additions & 17 deletions SongPlayHistory/UI/SPHUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System.Threading.Tasks;
using HMUI;
using IPA.Utilities;
using Polyglot;
using BGLib.Polyglot;
using SiraUtil.Logging;
using SongPlayHistory.Configuration;
using SongPlayHistory.Model;
Expand Down Expand Up @@ -136,31 +136,31 @@ public void Dispose()
_cts = null;
}

private void OnDifficultyChanged(StandardLevelDetailViewController _, IDifficultyBeatmap beatmap)
private void OnDifficultyChanged(StandardLevelDetailViewController controller)
{
UpdateUI(beatmap);
UpdateUI(controller.beatmapKey, controller.beatmapLevel);
}

private void OnContentChanged(StandardLevelDetailViewController _, StandardLevelDetailViewController.ContentType contentType)
private void OnContentChanged(StandardLevelDetailViewController controller, StandardLevelDetailViewController.ContentType contentType)
{
if (contentType == StandardLevelDetailViewController.ContentType.OwnedAndReady)
{
UpdateUI(_levelDetailViewController.selectedDifficultyBeatmap);
UpdateUI(controller.beatmapKey, controller.beatmapLevel);
}
}

private void OnPlayResultDismiss(ResultsViewController _)
{
UpdateUI(_levelDetailViewController.selectedDifficultyBeatmap);
UpdateUI(_levelDetailViewController.beatmapKey, _levelDetailViewController.beatmapLevel);
}

private void UpdateUI(IDifficultyBeatmap? beatmap)
private void UpdateUI(BeatmapKey beatmapKey, BeatmapLevel? beatmap)
{
if (beatmap == null) return;
_logger.Info("Updating SPH UI");
_logger.Debug($"{beatmap.level.songName} {beatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName} {beatmap.difficulty}");
_logger.Debug($"{beatmap.songName} {beatmapKey.beatmapCharacteristic.serializedName} {beatmapKey.difficulty}");

SetStats(beatmap);
SetStats(beatmapKey);

_cts?.Cancel();
_cts?.Dispose();
Expand All @@ -170,11 +170,11 @@ private void UpdateUI(IDifficultyBeatmap? beatmap)
{
try
{
await SetRecords(beatmap, token);
await SetRecords(beatmapKey, beatmap, token);
}
catch (OperationCanceledException e) when (e.CancellationToken == token)
{
_logger.Debug($"Update cancelled: {beatmap.level.songName}");
_logger.Debug($"Update cancelled: {beatmap.songName}");
}
catch (Exception ex)
{
Expand All @@ -184,14 +184,14 @@ private void UpdateUI(IDifficultyBeatmap? beatmap)
}, token);
}

private async Task SetRecords(IDifficultyBeatmap beatmap, CancellationToken cancellationToken)
private async Task SetRecords(BeatmapKey beatmapKey, BeatmapLevel beatmap, CancellationToken cancellationToken)
{
_logger.Debug($"Setting records from Thread {Environment.CurrentManagedThreadId}");

var task = _scoringCacheManager.GetScoringInfo(beatmap, cancellationToken); // let it run in the background first
var task = _scoringCacheManager.GetScoringInfo(beatmapKey, beatmap, cancellationToken); // let it run in the background first

var config = PluginConfig.Instance;
var key = new LevelMapKey(beatmap);
var key = new LevelMapKey(beatmapKey);
var records =
from record in _recordsManager.GetRecords(key)
where config.ShowFailed || record.LevelEnd == LevelEndType.Cleared
Expand Down Expand Up @@ -295,10 +295,12 @@ from record in _recordsManager.GetRecords(key)
_hoverHint.text = builder.ToString();
}

private void SetStats(IDifficultyBeatmap beatmap)
private void SetStats(BeatmapKey beatmap)
{
var stats = _playerDataModel.playerData.GetPlayerLevelStatsData(beatmap.level.levelID, beatmap.difficulty, beatmap.parentDifficultyBeatmapSet.beatmapCharacteristic);
_playCount.text = stats.playCount.ToString();
var playCount = _playerDataModel.playerData.levelsStatsData.TryGetValue(beatmap, out var data)
? data.playCount
: 0;
_playCount.text = playCount.ToString();
}
}
}

0 comments on commit 8ab3e85

Please sign in to comment.