mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 03:33:22 +08:00
Add object counts to IBeatmapDifficultyInfo
This commit is contained in:
parent
a553387c3d
commit
767d5c8018
@ -21,6 +21,7 @@ using osu.Game.Rulesets;
|
|||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Scoring.Legacy;
|
using osu.Game.Scoring.Legacy;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
using Realms;
|
||||||
|
|
||||||
namespace osu.Game
|
namespace osu.Game
|
||||||
{
|
{
|
||||||
@ -68,6 +69,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
checkForOutdatedStarRatings();
|
checkForOutdatedStarRatings();
|
||||||
processBeatmapSetsWithMissingMetrics();
|
processBeatmapSetsWithMissingMetrics();
|
||||||
|
processBeatmapsWithMissingObjectCounts();
|
||||||
processScoresWithMissingStatistics();
|
processScoresWithMissingStatistics();
|
||||||
convertLegacyTotalScoreToStandardised();
|
convertLegacyTotalScoreToStandardised();
|
||||||
}, TaskCreationOptions.LongRunning).ContinueWith(t =>
|
}, TaskCreationOptions.LongRunning).ContinueWith(t =>
|
||||||
@ -178,6 +180,42 @@ namespace osu.Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void processBeatmapsWithMissingObjectCounts()
|
||||||
|
{
|
||||||
|
Logger.Log("Querying for beatmaps with missing hitobject counts to reprocess...");
|
||||||
|
|
||||||
|
HashSet<Guid> beatmapIds = realmAccess.Run(r => new HashSet<Guid>(r.All<BeatmapInfo>()
|
||||||
|
.Filter($"{nameof(BeatmapInfo.Difficulty)}.{nameof(BeatmapDifficulty.TotalObjectCount)} == 0")
|
||||||
|
.AsEnumerable().Select(b => b.ID)));
|
||||||
|
|
||||||
|
Logger.Log($"Found {beatmapIds.Count} beatmaps which require reprocessing.");
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
foreach (var id in beatmapIds)
|
||||||
|
{
|
||||||
|
sleepIfRequired();
|
||||||
|
|
||||||
|
realmAccess.Run(r =>
|
||||||
|
{
|
||||||
|
var beatmap = r.Find<BeatmapInfo>(id);
|
||||||
|
|
||||||
|
if (beatmap != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Logger.Log($"Background processing {beatmap} ({++i} / {beatmapIds.Count})");
|
||||||
|
beatmapUpdater.ProcessObjectCounts(beatmap);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.Log($"Background processing failed on {beatmap}: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void processScoresWithMissingStatistics()
|
private void processScoresWithMissingStatistics()
|
||||||
{
|
{
|
||||||
HashSet<Guid> scoreIds = new HashSet<Guid>();
|
HashSet<Guid> scoreIds = new HashSet<Guid>();
|
||||||
|
@ -21,6 +21,9 @@ namespace osu.Game.Beatmaps
|
|||||||
public double SliderMultiplier { get; set; } = 1.4;
|
public double SliderMultiplier { get; set; } = 1.4;
|
||||||
public double SliderTickRate { get; set; } = 1;
|
public double SliderTickRate { get; set; } = 1;
|
||||||
|
|
||||||
|
public int EndTimeObjectCount { get; set; }
|
||||||
|
public int TotalObjectCount { get; set; }
|
||||||
|
|
||||||
public BeatmapDifficulty()
|
public BeatmapDifficulty()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -44,6 +47,9 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
difficulty.SliderMultiplier = SliderMultiplier;
|
difficulty.SliderMultiplier = SliderMultiplier;
|
||||||
difficulty.SliderTickRate = SliderTickRate;
|
difficulty.SliderTickRate = SliderTickRate;
|
||||||
|
|
||||||
|
difficulty.EndTimeObjectCount = EndTimeObjectCount;
|
||||||
|
difficulty.TotalObjectCount = TotalObjectCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void CopyFrom(IBeatmapDifficultyInfo other)
|
public virtual void CopyFrom(IBeatmapDifficultyInfo other)
|
||||||
@ -55,6 +61,9 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
SliderMultiplier = other.SliderMultiplier;
|
SliderMultiplier = other.SliderMultiplier;
|
||||||
SliderTickRate = other.SliderTickRate;
|
SliderTickRate = other.SliderTickRate;
|
||||||
|
|
||||||
|
EndTimeObjectCount = other.EndTimeObjectCount;
|
||||||
|
TotalObjectCount = other.TotalObjectCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ using osu.Game.IO;
|
|||||||
using osu.Game.IO.Archives;
|
using osu.Game.IO.Archives;
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using Realms;
|
using Realms;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps
|
namespace osu.Game.Beatmaps
|
||||||
@ -388,6 +389,8 @@ namespace osu.Game.Beatmaps
|
|||||||
ApproachRate = decodedDifficulty.ApproachRate,
|
ApproachRate = decodedDifficulty.ApproachRate,
|
||||||
SliderMultiplier = decodedDifficulty.SliderMultiplier,
|
SliderMultiplier = decodedDifficulty.SliderMultiplier,
|
||||||
SliderTickRate = decodedDifficulty.SliderTickRate,
|
SliderTickRate = decodedDifficulty.SliderTickRate,
|
||||||
|
EndTimeObjectCount = decoded.HitObjects.Count(h => h is IHasDuration),
|
||||||
|
TotalObjectCount = decoded.HitObjects.Count
|
||||||
};
|
};
|
||||||
|
|
||||||
var metadata = new BeatmapMetadata
|
var metadata = new BeatmapMetadata
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Extensions.ObjectExtensions;
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
@ -10,6 +11,7 @@ using osu.Framework.Platform;
|
|||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
|
||||||
namespace osu.Game.Beatmaps
|
namespace osu.Game.Beatmaps
|
||||||
{
|
{
|
||||||
@ -44,7 +46,8 @@ namespace osu.Game.Beatmaps
|
|||||||
public void Queue(Live<BeatmapSetInfo> beatmapSet, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst)
|
public void Queue(Live<BeatmapSetInfo> beatmapSet, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst)
|
||||||
{
|
{
|
||||||
Logger.Log($"Queueing change for local beatmap {beatmapSet}");
|
Logger.Log($"Queueing change for local beatmap {beatmapSet}");
|
||||||
Task.Factory.StartNew(() => beatmapSet.PerformRead(b => Process(b, lookupScope)), default, TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler);
|
Task.Factory.StartNew(() => beatmapSet.PerformRead(b => Process(b, lookupScope)), default, TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously,
|
||||||
|
updateScheduler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -80,6 +83,21 @@ namespace osu.Game.Beatmaps
|
|||||||
workingBeatmapCache.Invalidate(beatmapSet);
|
workingBeatmapCache.Invalidate(beatmapSet);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
public void ProcessObjectCounts(BeatmapInfo beatmapInfo, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst) => beatmapInfo.Realm!.Write(_ =>
|
||||||
|
{
|
||||||
|
// Before we use below, we want to invalidate.
|
||||||
|
workingBeatmapCache.Invalidate(beatmapInfo);
|
||||||
|
|
||||||
|
var working = workingBeatmapCache.GetWorkingBeatmap(beatmapInfo);
|
||||||
|
var beatmap = working.Beatmap;
|
||||||
|
|
||||||
|
beatmapInfo.Difficulty.EndTimeObjectCount = beatmap.HitObjects.Count(h => h is IHasDuration);
|
||||||
|
beatmapInfo.Difficulty.TotalObjectCount = beatmap.HitObjects.Count;
|
||||||
|
|
||||||
|
// And invalidate again afterwards as re-fetching the most up-to-date database metadata will be required.
|
||||||
|
workingBeatmapCache.Invalidate(beatmapInfo);
|
||||||
|
});
|
||||||
|
|
||||||
#region Implementation of IDisposable
|
#region Implementation of IDisposable
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@ -44,6 +44,19 @@ namespace osu.Game.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
double SliderTickRate { get; }
|
double SliderTickRate { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of hitobjects in the beatmap with a distinct end time.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Canonically, these are hitobjects are either sliders or spinners.
|
||||||
|
/// </remarks>
|
||||||
|
int EndTimeObjectCount { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total number of hitobjects in the beatmap.
|
||||||
|
/// </summary>
|
||||||
|
int TotalObjectCount { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maps a difficulty value [0, 10] to a two-piece linear range of values.
|
/// Maps a difficulty value [0, 10] to a two-piece linear range of values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -88,8 +88,9 @@ namespace osu.Game.Database
|
|||||||
/// 34 2023-08-21 Add BackgroundReprocessingFailed flag to ScoreInfo to track upgrade failures.
|
/// 34 2023-08-21 Add BackgroundReprocessingFailed flag to ScoreInfo to track upgrade failures.
|
||||||
/// 35 2023-10-16 Clear key combinations of keybindings that are assigned to more than one action in a given settings section.
|
/// 35 2023-10-16 Clear key combinations of keybindings that are assigned to more than one action in a given settings section.
|
||||||
/// 36 2023-10-26 Add LegacyOnlineID to ScoreInfo. Move osu_scores_*_high IDs stored in OnlineID to LegacyOnlineID. Reset anomalous OnlineIDs.
|
/// 36 2023-10-26 Add LegacyOnlineID to ScoreInfo. Move osu_scores_*_high IDs stored in OnlineID to LegacyOnlineID. Reset anomalous OnlineIDs.
|
||||||
|
/// 37 2023-12-10 Add EndTimeObjectCount and TotalObjectCount to BeatmapDifficulty.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const int schema_version = 36;
|
private const int schema_version = 37;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock object which is held during <see cref="BlockAllOperations"/> sections, blocking realm retrieval during blocking periods.
|
/// Lock object which is held during <see cref="BlockAllOperations"/> sections, blocking realm retrieval during blocking periods.
|
||||||
|
@ -109,6 +109,8 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
CircleSize = CircleSize,
|
CircleSize = CircleSize,
|
||||||
ApproachRate = ApproachRate,
|
ApproachRate = ApproachRate,
|
||||||
OverallDifficulty = OverallDifficulty,
|
OverallDifficulty = OverallDifficulty,
|
||||||
|
EndTimeObjectCount = SliderCount + SpinnerCount,
|
||||||
|
TotalObjectCount = CircleCount + SliderCount + SpinnerCount
|
||||||
};
|
};
|
||||||
|
|
||||||
IBeatmapSetInfo? IBeatmapInfo.BeatmapSet => BeatmapSet;
|
IBeatmapSetInfo? IBeatmapInfo.BeatmapSet => BeatmapSet;
|
||||||
|
@ -45,6 +45,7 @@ namespace osu.Game.Rulesets.Scoring.Legacy
|
|||||||
float IBeatmapDifficultyInfo.ApproachRate => 0;
|
float IBeatmapDifficultyInfo.ApproachRate => 0;
|
||||||
double IBeatmapDifficultyInfo.SliderMultiplier => 0;
|
double IBeatmapDifficultyInfo.SliderMultiplier => 0;
|
||||||
double IBeatmapDifficultyInfo.SliderTickRate => 0;
|
double IBeatmapDifficultyInfo.SliderTickRate => 0;
|
||||||
|
int IBeatmapDifficultyInfo.EndTimeObjectCount => TotalObjectCount - CircleCount;
|
||||||
|
|
||||||
public static LegacyBeatmapConversionDifficultyInfo FromAPIBeatmap(APIBeatmap apiBeatmap) => new LegacyBeatmapConversionDifficultyInfo
|
public static LegacyBeatmapConversionDifficultyInfo FromAPIBeatmap(APIBeatmap apiBeatmap) => new LegacyBeatmapConversionDifficultyInfo
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user