mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 21:52: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.Input.Bindings;
|
||||||
using osu.Game.Models;
|
using osu.Game.Models;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using Realms;
|
using Realms;
|
||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
@ -27,6 +28,7 @@ namespace osu.Game.Database
|
|||||||
c.CreateMap<BeatmapMetadata, BeatmapMetadata>();
|
c.CreateMap<BeatmapMetadata, BeatmapMetadata>();
|
||||||
c.CreateMap<BeatmapDifficulty, BeatmapDifficulty>();
|
c.CreateMap<BeatmapDifficulty, BeatmapDifficulty>();
|
||||||
c.CreateMap<RulesetInfo, RulesetInfo>();
|
c.CreateMap<RulesetInfo, RulesetInfo>();
|
||||||
|
c.CreateMap<ScoreInfo, ScoreInfo>();
|
||||||
c.CreateMap<RealmUser, RealmUser>();
|
c.CreateMap<RealmUser, RealmUser>();
|
||||||
c.CreateMap<RealmFile, RealmFile>();
|
c.CreateMap<RealmFile, RealmFile>();
|
||||||
c.CreateMap<RealmNamedFileUsage, RealmNamedFileUsage>();
|
c.CreateMap<RealmNamedFileUsage, RealmNamedFileUsage>();
|
||||||
|
@ -502,6 +502,8 @@ namespace osu.Game
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
databasedScoreInfo = databasedScoreInfo.Detach();
|
||||||
|
|
||||||
var databasedScore = ScoreManager.GetScore(databasedScoreInfo);
|
var databasedScore = ScoreManager.GetScore(databasedScoreInfo);
|
||||||
|
|
||||||
if (databasedScore.Replay == null)
|
if (databasedScore.Replay == null)
|
||||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Scoring.Legacy
|
|||||||
this.beatmaps = beatmaps;
|
this.beatmaps = beatmaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Ruleset GetRuleset(int rulesetId) => rulesets.GetRuleset(rulesetId).CreateInstance();
|
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 WorkingBeatmap GetBeatmap(string md5Hash) => beatmaps.GetWorkingBeatmap(beatmaps.QueryBeatmap(b => b.MD5Hash == md5Hash));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using AutoMapper;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
@ -112,9 +113,16 @@ namespace osu.Game.Scoring
|
|||||||
[MapTo(nameof(Rank))]
|
[MapTo(nameof(Rank))]
|
||||||
public int RankInt { get; set; }
|
public int RankInt { get; set; }
|
||||||
|
|
||||||
|
[IgnoreMap]
|
||||||
IRulesetInfo IScoreInfo.Ruleset => Ruleset;
|
IRulesetInfo IScoreInfo.Ruleset => Ruleset;
|
||||||
|
|
||||||
|
[IgnoreMap]
|
||||||
IBeatmapInfo IScoreInfo.Beatmap => Beatmap;
|
IBeatmapInfo IScoreInfo.Beatmap => Beatmap;
|
||||||
|
|
||||||
|
[IgnoreMap]
|
||||||
IUser IScoreInfo.User => User;
|
IUser IScoreInfo.User => User;
|
||||||
|
|
||||||
|
[IgnoreMap]
|
||||||
IEnumerable<INamedFileUsage> IHasNamedFiles.Files => Files;
|
IEnumerable<INamedFileUsage> IHasNamedFiles.Files => Files;
|
||||||
|
|
||||||
#region Properties required to make things work with existing usages
|
#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);
|
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)
|
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");
|
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.
|
// 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.
|
// 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
|
// 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).
|
// conflicts across various systems (ie. solo and multiplayer).
|
||||||
long onlineScoreId = score.ScoreInfo.OnlineID;
|
importableScore.OnlineID = -1;
|
||||||
|
|
||||||
score.ScoreInfo.OnlineID = -1;
|
await scoreManager.Import(importableScore, replayReader).ConfigureAwait(false);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -149,7 +149,10 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
{
|
{
|
||||||
using (var realm = realmFactory.CreateContext())
|
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())
|
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.Where(s => s.Mods.Any(m => selectedMods.Contains(m.Acronym)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scores = scores.Detach();
|
||||||
|
|
||||||
scoreManager.OrderByTotalScoreAsync(scores.ToArray(), cancellationToken)
|
scoreManager.OrderByTotalScoreAsync(scores.ToArray(), cancellationToken)
|
||||||
.ContinueWith(ordered => scoresCallback?.Invoke(ordered.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
|
.ContinueWith(ordered => scoresCallback?.Invoke(ordered.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user