mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 16:02:55 +08:00
Detach and reattach scores to make work
This commit is contained in:
parent
60d2de8a3b
commit
2b8706b6ce
@ -10,6 +10,7 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Models;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
using Realms;
|
||||
|
||||
#nullable enable
|
||||
@ -27,6 +28,7 @@ namespace osu.Game.Database
|
||||
c.CreateMap<BeatmapMetadata, BeatmapMetadata>();
|
||||
c.CreateMap<BeatmapDifficulty, BeatmapDifficulty>();
|
||||
c.CreateMap<RulesetInfo, RulesetInfo>();
|
||||
c.CreateMap<ScoreInfo, ScoreInfo>();
|
||||
c.CreateMap<RealmUser, RealmUser>();
|
||||
c.CreateMap<RealmFile, RealmFile>();
|
||||
c.CreateMap<RealmNamedFileUsage, RealmNamedFileUsage>();
|
||||
|
@ -502,6 +502,8 @@ namespace osu.Game
|
||||
return;
|
||||
}
|
||||
|
||||
databasedScoreInfo = databasedScoreInfo.Detach();
|
||||
|
||||
var databasedScore = ScoreManager.GetScore(databasedScoreInfo);
|
||||
|
||||
if (databasedScore.Replay == null)
|
||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Scoring.Legacy
|
||||
this.beatmaps = beatmaps;
|
||||
}
|
||||
|
||||
protected override Ruleset GetRuleset(int rulesetId) => rulesets.GetRuleset(rulesetId).CreateInstance();
|
||||
protected override WorkingBeatmap GetBeatmap(string md5Hash) => beatmaps.GetWorkingBeatmap(beatmaps.QueryBeatmap(b => !b.BeatmapSet.DeletePending && b.MD5Hash == md5Hash));
|
||||
protected override Ruleset GetRuleset(int rulesetId) => rulesets.GetRuleset(rulesetId)?.CreateInstance();
|
||||
protected override WorkingBeatmap GetBeatmap(string md5Hash) => beatmaps.GetWorkingBeatmap(beatmaps.QueryBeatmap(b => b.MD5Hash == md5Hash));
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AutoMapper;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Testing;
|
||||
@ -112,9 +113,16 @@ namespace osu.Game.Scoring
|
||||
[MapTo(nameof(Rank))]
|
||||
public int RankInt { get; set; }
|
||||
|
||||
[IgnoreMap]
|
||||
IRulesetInfo IScoreInfo.Ruleset => Ruleset;
|
||||
|
||||
[IgnoreMap]
|
||||
IBeatmapInfo IScoreInfo.Beatmap => Beatmap;
|
||||
|
||||
[IgnoreMap]
|
||||
IUser IScoreInfo.User => User;
|
||||
|
||||
[IgnoreMap]
|
||||
IEnumerable<INamedFileUsage> IHasNamedFiles.Files => Files;
|
||||
|
||||
#region Properties required to make things work with existing usages
|
||||
|
@ -55,6 +55,15 @@ namespace osu.Game.Scoring
|
||||
public Score GetScore(ScoreInfo score) => new LegacyDatabasedScore(score, rulesets, beatmaps(), Files.Store);
|
||||
|
||||
protected override Task Populate(ScoreInfo model, ArchiveReader? archive, Realm realm, CancellationToken cancellationToken = default)
|
||||
=> Task.CompletedTask;
|
||||
{
|
||||
// Ensure the beatmap is not detached.
|
||||
if (!model.Beatmap.IsManaged)
|
||||
model.Beatmap = realm.Find<BeatmapInfo>(model.Beatmap.ID);
|
||||
|
||||
if (!model.Ruleset.IsManaged)
|
||||
model.Ruleset = realm.Find<RulesetInfo>(model.Ruleset.ShortName);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1038,19 +1038,17 @@ namespace osu.Game.Screens.Play
|
||||
replayReader = new LegacyByteArrayReader(stream.ToArray(), "replay.osr");
|
||||
}
|
||||
|
||||
// the import process will re-attach managed beatmap/rulesets to this score. we don't want this for now, so create a temporary copy to import.
|
||||
var importableScore = score.ScoreInfo.DeepClone();
|
||||
|
||||
// For the time being, online ID responses are not really useful for anything.
|
||||
// In addition, the IDs provided via new (lazer) endpoints are based on a different autoincrement from legacy (stable) scores.
|
||||
//
|
||||
// Until we better define the server-side logic behind this, let's not store the online ID to avoid potential unique constraint
|
||||
// conflicts across various systems (ie. solo and multiplayer).
|
||||
long onlineScoreId = score.ScoreInfo.OnlineID;
|
||||
importableScore.OnlineID = -1;
|
||||
|
||||
score.ScoreInfo.OnlineID = -1;
|
||||
|
||||
await scoreManager.Import(score.ScoreInfo, replayReader).ConfigureAwait(false);
|
||||
|
||||
// ... And restore the online ID for other processes to handle correctly (e.g. de-duplication for the results screen).
|
||||
score.ScoreInfo.OnlineID = onlineScoreId;
|
||||
await scoreManager.Import(importableScore, replayReader).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -149,7 +149,10 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
{
|
||||
using (var realm = realmFactory.CreateContext())
|
||||
{
|
||||
var scores = realm.All<ScoreInfo>().Where(s => !s.DeletePending && s.BeatmapInfo.ID == fetchBeatmapInfo.ID && s.Ruleset.OnlineID == ruleset.Value.ID);
|
||||
var scores = realm.All<ScoreInfo>()
|
||||
.AsEnumerable()
|
||||
// TODO: update to use a realm filter directly (or at least figure out the beatmap part to reduce scope).
|
||||
.Where(s => !s.DeletePending && s.BeatmapInfo.ID == fetchBeatmapInfo.ID && s.Ruleset.OnlineID == ruleset.Value.ID);
|
||||
|
||||
if (filterMods && !mods.Value.Any())
|
||||
{
|
||||
@ -164,6 +167,8 @@ namespace osu.Game.Screens.Select.Leaderboards
|
||||
scores = scores.Where(s => s.Mods.Any(m => selectedMods.Contains(m.Acronym)));
|
||||
}
|
||||
|
||||
scores = scores.Detach();
|
||||
|
||||
scoreManager.OrderByTotalScoreAsync(scores.ToArray(), cancellationToken)
|
||||
.ContinueWith(ordered => scoresCallback?.Invoke(ordered.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user