mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 17:23:22 +08:00
Ensure online IDs are validated for imports that don't have an associated archive too
This commit is contained in:
parent
e3fb781a5a
commit
68614f1512
@ -89,34 +89,46 @@ namespace osu.Game.Beatmaps
|
|||||||
this.audioManager = audioManager;
|
this.audioManager = audioManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Populate(BeatmapSetInfo model, ArchiveReader archive)
|
protected override void Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive)
|
||||||
{
|
{
|
||||||
if (archive != null)
|
if (archive != null)
|
||||||
model.Beatmaps = createBeatmapDifficulties(archive);
|
beatmapSet.Beatmaps = createBeatmapDifficulties(archive);
|
||||||
|
|
||||||
foreach (BeatmapInfo b in model.Beatmaps)
|
foreach (BeatmapInfo b in beatmapSet.Beatmaps)
|
||||||
{
|
{
|
||||||
// remove metadata from difficulties where it matches the set
|
// remove metadata from difficulties where it matches the set
|
||||||
if (model.Metadata.Equals(b.Metadata))
|
if (beatmapSet.Metadata.Equals(b.Metadata))
|
||||||
b.Metadata = null;
|
b.Metadata = null;
|
||||||
|
|
||||||
// by setting the model here, we can update the noline set id below.
|
b.BeatmapSet = beatmapSet;
|
||||||
b.BeatmapSet = model;
|
|
||||||
|
|
||||||
fetchAndPopulateOnlineIDs(b, model.Beatmaps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if a set already exists with the same online id, delete if it does.
|
// check if a set already exists with the same online id, delete if it does.
|
||||||
if (model.OnlineBeatmapSetID != null)
|
if (beatmapSet.OnlineBeatmapSetID != null)
|
||||||
{
|
{
|
||||||
var existingOnlineId = beatmaps.ConsumableItems.FirstOrDefault(b => b.OnlineBeatmapSetID == model.OnlineBeatmapSetID);
|
var existingOnlineId = beatmaps.ConsumableItems.FirstOrDefault(b => b.OnlineBeatmapSetID == beatmapSet.OnlineBeatmapSetID);
|
||||||
if (existingOnlineId != null)
|
if (existingOnlineId != null)
|
||||||
{
|
{
|
||||||
Delete(existingOnlineId);
|
Delete(existingOnlineId);
|
||||||
beatmaps.PurgeDeletable(s => s.ID == existingOnlineId.ID);
|
beatmaps.PurgeDeletable(s => s.ID == existingOnlineId.ID);
|
||||||
Logger.Log($"Found existing beatmap set with same OnlineBeatmapSetID ({model.OnlineBeatmapSetID}). It has been purged.", LoggingTarget.Database);
|
Logger.Log($"Found existing beatmap set with same OnlineBeatmapSetID ({beatmapSet.OnlineBeatmapSetID}). It has been purged.", LoggingTarget.Database);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validateOnlineIds(beatmapSet.Beatmaps);
|
||||||
|
|
||||||
|
foreach (BeatmapInfo b in beatmapSet.Beatmaps)
|
||||||
|
fetchAndPopulateOnlineIDs(b, beatmapSet.Beatmaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateOnlineIds(List<BeatmapInfo> beatmaps)
|
||||||
|
{
|
||||||
|
var beatmapIds = beatmaps.Where(b => b.OnlineBeatmapID.HasValue).Select(b => b.OnlineBeatmapID);
|
||||||
|
|
||||||
|
// ensure all IDs are unique in this set and none match existing IDs in the local beatmap store.
|
||||||
|
if (beatmapIds.GroupBy(b => b).Any(g => g.Count() > 1) || QueryBeatmaps(b => beatmapIds.Contains(b.OnlineBeatmapID)).Any())
|
||||||
|
// remove all online IDs if any problems were found.
|
||||||
|
beatmaps.ForEach(b => b.OnlineBeatmapID = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override BeatmapSetInfo CheckForExisting(BeatmapSetInfo model)
|
protected override BeatmapSetInfo CheckForExisting(BeatmapSetInfo model)
|
||||||
@ -297,7 +309,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="query">The query.</param>
|
/// <param name="query">The query.</param>
|
||||||
/// <returns>Results from the provided query.</returns>
|
/// <returns>Results from the provided query.</returns>
|
||||||
public IEnumerable<BeatmapInfo> QueryBeatmaps(Expression<Func<BeatmapInfo, bool>> query) => beatmaps.Beatmaps.AsNoTracking().Where(query);
|
public IQueryable<BeatmapInfo> QueryBeatmaps(Expression<Func<BeatmapInfo, bool>> query) => beatmaps.Beatmaps.AsNoTracking().Where(query);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Denotes whether an osu-stable installation is present to perform automated imports from.
|
/// Denotes whether an osu-stable installation is present to perform automated imports from.
|
||||||
@ -360,8 +372,6 @@ namespace osu.Game.Beatmaps
|
|||||||
{
|
{
|
||||||
var beatmapInfos = new List<BeatmapInfo>();
|
var beatmapInfos = new List<BeatmapInfo>();
|
||||||
|
|
||||||
bool invalidateOnlineIDs = false;
|
|
||||||
|
|
||||||
foreach (var name in reader.Filenames.Where(f => f.EndsWith(".osu")))
|
foreach (var name in reader.Filenames.Where(f => f.EndsWith(".osu")))
|
||||||
{
|
{
|
||||||
using (var raw = reader.GetStream(name))
|
using (var raw = reader.GetStream(name))
|
||||||
@ -378,38 +388,15 @@ namespace osu.Game.Beatmaps
|
|||||||
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
|
beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash();
|
||||||
beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();
|
beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash();
|
||||||
|
|
||||||
if (beatmap.BeatmapInfo.OnlineBeatmapID.HasValue)
|
var ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
||||||
{
|
|
||||||
var ourId = beatmap.BeatmapInfo.OnlineBeatmapID;
|
|
||||||
|
|
||||||
// check that no existing beatmap in database exists that is imported with the same online beatmap ID. if so, give it precedence.
|
|
||||||
if (QueryBeatmap(b => b.OnlineBeatmapID.Value == ourId) != null)
|
|
||||||
beatmap.BeatmapInfo.OnlineBeatmapID = null;
|
|
||||||
|
|
||||||
// check that no other beatmap in this imported set has a conflicting online beatmap ID. If so, presume *all* are incorrect.
|
|
||||||
if (beatmapInfos.Any(b => b.OnlineBeatmapID == ourId))
|
|
||||||
invalidateOnlineIDs = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RulesetInfo ruleset = rulesets.GetRuleset(beatmap.BeatmapInfo.RulesetID);
|
|
||||||
|
|
||||||
beatmap.BeatmapInfo.Ruleset = ruleset;
|
beatmap.BeatmapInfo.Ruleset = ruleset;
|
||||||
|
// TODO: this should be done in a better place once we actually need to dynamically update it.
|
||||||
if (ruleset != null)
|
beatmap.BeatmapInfo.StarDifficulty = ruleset?.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating ?? 0;
|
||||||
{
|
|
||||||
// TODO: this should be done in a better place once we actually need to dynamically update it.
|
|
||||||
beatmap.BeatmapInfo.StarDifficulty = ruleset.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
beatmap.BeatmapInfo.StarDifficulty = 0;
|
|
||||||
|
|
||||||
beatmapInfos.Add(beatmap.BeatmapInfo);
|
beatmapInfos.Add(beatmap.BeatmapInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invalidateOnlineIDs)
|
|
||||||
beatmapInfos.ForEach(b => b.OnlineBeatmapID = null);
|
|
||||||
|
|
||||||
return beatmapInfos;
|
return beatmapInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,12 +409,12 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <returns>True if population was successful.</returns>
|
/// <returns>True if population was successful.</returns>
|
||||||
private bool fetchAndPopulateOnlineIDs(BeatmapInfo beatmap, IEnumerable<BeatmapInfo> otherBeatmaps, bool force = false)
|
private bool fetchAndPopulateOnlineIDs(BeatmapInfo beatmap, IEnumerable<BeatmapInfo> otherBeatmaps, bool force = false)
|
||||||
{
|
{
|
||||||
|
if (api?.State != APIState.Online)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!force && beatmap.OnlineBeatmapID != null && beatmap.BeatmapSet.OnlineBeatmapSetID != null)
|
if (!force && beatmap.OnlineBeatmapID != null && beatmap.BeatmapSet.OnlineBeatmapSetID != null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (api.State != APIState.Online)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Logger.Log("Attempting online lookup for IDs...", LoggingTarget.Database);
|
Logger.Log("Attempting online lookup for IDs...", LoggingTarget.Database);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
Loading…
Reference in New Issue
Block a user