Skip to content

Commit

Permalink
Fix for 1.36.0
Browse files Browse the repository at this point in the history
also bump dependency versions to force not loading on older game versions
  • Loading branch information
qe201020335 committed May 5, 2024
1 parent 0086eaf commit 65c7ffc
Show file tree
Hide file tree
Showing 15 changed files with 119 additions and 65 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
7 changes: 3 additions & 4 deletions SongPlayHistory/Patches/DiTailsVotePatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,18 @@ private static bool Prepare()
}

[HarmonyPrefix]
public static void Prefix(bool upvote, IDifficultyBeatmap? ____activeBeatmap)
public static void Prefix(bool upvote, BeatmapLevel? ____activeBeatmap) //TODO: update when DiTails Update
{
if (____activeBeatmap == null) return;
var vote = upvote ? VoteType.Upvote : VoteType.Downvote;
Plugin.Log.Debug($"DiTails voted {vote} to {____activeBeatmap.level.levelID}");
Plugin.Log.Debug($"DiTails voted {vote} to {____activeBeatmap.levelID}");
if (InMenuVoteTrackingHelper.Instance == null)
{
Plugin.Log.Warn("InMenuVoteTrackingHelper is null");
return;
}

InMenuVoteTrackingHelper.Instance.Vote(____activeBeatmap.level, vote);

InMenuVoteTrackingHelper.Instance.Vote(____activeBeatmap, vote);
}
}
}
2 changes: 1 addition & 1 deletion SongPlayHistory/Patches/HarmonyPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static bool Prepare()
}

[HarmonyAfter("com.kyle1413.BeatSaber.SongCore")]
public static void Postfix(LevelListTableCell __instance, IPreviewBeatmapLevel? level, bool isFavorite,
public static void Postfix(LevelListTableCell __instance, BeatmapLevel? level, bool isFavorite,
Image ____favoritesBadgeImage, TextMeshProUGUI? ____songBpmText)
{
if (!PluginConfig.Instance.ShowVotes) return;
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 @@ -128,7 +128,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 @@ -139,12 +139,12 @@ private void OnLevelFinished(object scene, LevelFinishedEventArgs eventArgs)
_logger.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 @@ -163,7 +163,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 @@ -238,7 +238,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
56 changes: 50 additions & 6 deletions SongPlayHistory/SongPlayData/ScoringCacheManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,25 @@ 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 cacheKey = new LevelMapKey(beatmap);
var cacheKey = new LevelMapKey(beatmapKey);

lock (_cache)
{
Expand All @@ -34,14 +43,49 @@ internal class ScoringCacheManager: IScoringCacheManager
}

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,
null,
null,
null,
false);

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 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" Publicize="true" />
<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" />
<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" />
<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();
}
}
}
4 changes: 2 additions & 2 deletions SongPlayHistory/Utils/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ internal static bool IsInReplay()
}
#endregion

internal static string GetLowerCaseCustomLevelHash(CustomPreviewBeatmapLevel level)
internal static string? GetLowerCaseCustomLevelHash(BeatmapLevel level)
{
return Hashing.GetCustomLevelHash(level).ToLower();
return level.levelID.StartsWith("custom_level_") ? Hashing.GetCustomLevelHash(level).ToLower() : null;
}

internal static IList<ISongPlayRecord> Copy(this IEnumerable<Record> records)
Expand Down
23 changes: 16 additions & 7 deletions SongPlayHistory/VoteTracker/BeatSaverVotingTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,25 @@ internal class BeatSaverVotingTracker: IVoteTracker

[Inject]
private readonly SiraLog _logger = null!;
public void Vote(IPreviewBeatmapLevel level, VoteType voteType)

public void Vote(BeatmapLevel level, VoteType voteType)
{
if (!(level is CustomPreviewBeatmapLevel customLevel)) return;
try
{
_logger.Debug($"Voting for {level.songName}, {level.levelID}, {voteType}");
var hash = Utils.Utils.GetLowerCaseCustomLevelHash(level);
if (hash == null)
{
_logger.Debug("Not custom level");
return;
}

if (BSVPlugin.votedSongs == null)
{
_logger.Debug("BeatSaverVoting dictionary is null");
return;
}

var hash = Utils.Utils.GetLowerCaseCustomLevelHash(customLevel);
var bsvType = voteType == VoteType.Upvote ? BSVType.Upvote : BSVType.Downvote;
if (BSVPlugin.votedSongs.TryGetValue(hash, out var songVote) && songVote.voteType == bsvType) return;

Expand All @@ -39,14 +44,18 @@ public void Vote(IPreviewBeatmapLevel level, VoteType voteType)
}
}

public bool TryGetVote(IPreviewBeatmapLevel level, out VoteType voteType)
public bool TryGetVote(BeatmapLevel level, out VoteType voteType)
{
voteType = VoteType.Downvote;
if (!(level is CustomPreviewBeatmapLevel customLevel)) return false;
try
{
_logger.Debug($"Getting vote data for {level.songName}, {level.levelID}");
var hash = Utils.Utils.GetLowerCaseCustomLevelHash(customLevel);
var hash = Utils.Utils.GetLowerCaseCustomLevelHash(level);
if (hash == null)
{
_logger.Debug("Not custom level");
return false;
}

var voteStatus = BSVPlugin.CurrentVoteStatus(hash);
if (voteStatus == null)
Expand Down
4 changes: 2 additions & 2 deletions SongPlayHistory/VoteTracker/IVoteTracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ namespace SongPlayHistory.VoteTracker
{
public interface IVoteTracker
{
public bool TryGetVote(IPreviewBeatmapLevel level, out VoteType voteType);
public bool TryGetVote(BeatmapLevel level, out VoteType voteType);

public void Vote(IPreviewBeatmapLevel level, VoteType voteType);
public void Vote(BeatmapLevel level, VoteType voteType);

}
}
4 changes: 2 additions & 2 deletions SongPlayHistory/VoteTracker/InMenuVoteTrackingHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ private void OnPlayResultDismiss(ResultsViewController _)
_tableView.RefreshCellsContent();
}

internal void Vote(IPreviewBeatmapLevel level, VoteType voteType)
internal void Vote(BeatmapLevel level, VoteType voteType)
{
_voteTracker.Vote(level, voteType);
_logger.Debug("Refreshing cells content");
_tableView.RefreshCellsContent();
}

internal bool TryGetVote(IPreviewBeatmapLevel level, out VoteType voteType)
internal bool TryGetVote(BeatmapLevel level, out VoteType voteType)
{
return _voteTracker.TryGetVote(level, out voteType);
}
Expand Down
Loading

0 comments on commit 65c7ffc

Please sign in to comment.