1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 17:43:05 +08:00

Implement replay downloading with ArchiveDownloadModelManager

This commit is contained in:
naoey 2019-06-12 01:31:57 +05:30
parent e8ea0594b4
commit ab0bb8b678
No known key found for this signature in database
GPG Key ID: 670DA9BE3DF7EE60
7 changed files with 103 additions and 6 deletions

View File

@ -0,0 +1,13 @@
using osu.Game.Scoring;
namespace osu.Game.Online.API.Requests
{
public class DownloadReplayRequest : ArchiveDownloadModelRequest<ScoreInfo>
{
public DownloadReplayRequest(ScoreInfo score)
: base(score)
{
}
protected override string Target => $@"scores/{Info.Ruleset.ShortName}/{Info.OnlineScoreID}/download";
}
}

View File

@ -32,12 +32,15 @@ namespace osu.Game.Online.API.Requests.Responses
set => User = value;
}
[JsonProperty(@"score_id")]
[JsonProperty(@"id")]
private long onlineScoreID
{
set => OnlineScoreID = value;
}
[JsonProperty(@"replay")]
public bool Replay { get; set; }
[JsonProperty(@"created_at")]
private DateTimeOffset date
{

View File

@ -170,7 +170,7 @@ namespace osu.Game
dependencies.Cache(FileStore = new FileStore(contextFactory, Host.Storage));
// ordering is important here to ensure foreign keys rules are not broken in ModelStore.Cleanup()
dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, () => BeatmapManager, Host.Storage, contextFactory, Host));
dependencies.Cache(ScoreManager = new ScoreManager(RulesetStore, () => BeatmapManager, Host.Storage, API, contextFactory, Host));
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, contextFactory, RulesetStore, API, Audio, Host, defaultBeatmap));
// this should likely be moved to ArchiveModelManager when another case appers where it is necessary

View File

@ -16,7 +16,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Scoring
{
public class ScoreInfo : IHasFiles<ScoreFileInfo>, IHasPrimaryKey, ISoftDelete
public class ScoreInfo : IHasFiles<ScoreFileInfo>, IHasPrimaryKey, ISoftDelete, IEquatable<ScoreInfo>
{
public int ID { get; set; }
@ -182,5 +182,7 @@ namespace osu.Game.Scoring
}
public override string ToString() => $"{User} playing {Beatmap}";
public bool Equals(ScoreInfo other) => other?.OnlineScoreID == OnlineScoreID;
}
}

View File

@ -11,12 +11,14 @@ using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.IO.Archives;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Rulesets;
using osu.Game.Scoring.Legacy;
namespace osu.Game.Scoring
{
public class ScoreManager : ArchiveModelManager<ScoreInfo, ScoreFileInfo>
public class ScoreManager : ArchiveDownloadModelManager<ScoreInfo, ScoreFileInfo>
{
public override string[] HandledExtensions => new[] { ".osr" };
@ -27,8 +29,8 @@ namespace osu.Game.Scoring
private readonly RulesetStore rulesets;
private readonly Func<BeatmapManager> beatmaps;
public ScoreManager(RulesetStore rulesets, Func<BeatmapManager> beatmaps, Storage storage, IDatabaseContextFactory contextFactory, IIpcHost importHost = null)
: base(storage, contextFactory, new ScoreStore(contextFactory, storage), importHost)
public ScoreManager(RulesetStore rulesets, Func<BeatmapManager> beatmaps, Storage storage, IAPIProvider api, IDatabaseContextFactory contextFactory, IIpcHost importHost = null)
: base(storage, contextFactory, api, new ScoreStore(contextFactory, storage), importHost)
{
this.rulesets = rulesets;
this.beatmaps = beatmaps;
@ -60,5 +62,7 @@ namespace osu.Game.Scoring
public IEnumerable<ScoreInfo> QueryScores(Expression<Func<ScoreInfo, bool>> query) => ModelStore.ConsumableItems.AsNoTracking().Where(query);
public ScoreInfo Query(Expression<Func<ScoreInfo, bool>> query) => ModelStore.ConsumableItems.AsNoTracking().FirstOrDefault(query);
protected override ArchiveDownloadModelRequest<ScoreInfo> CreateDownloadRequest(ScoreInfo score, object[] options) => new DownloadReplayRequest(score);
}
}

View File

@ -0,0 +1,53 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online;
using osu.Game.Scoring;
namespace osu.Game.Screens.Play
{
public class ReplayDownloadButton : DownloadTrackingComposite<ScoreInfo, ScoreManager>
{
[Resolved]
private OsuGame game { get; set; }
[Resolved]
private ScoreManager scores { get; set; }
public ReplayDownloadButton(ScoreInfo score)
: base(score)
{
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
AddInternal(new TwoLayerButton
{
BackgroundColour = colours.Yellow,
Icon = FontAwesome.Solid.PlayCircle,
Text = @"Replay",
HoverColour = colours.YellowDark,
Action = onReplay,
});
}
private void onReplay()
{
if (scores.IsAvailableLocally(ModelInfo.Value))
{
game.PresentScore(ModelInfo.Value);
return;
}
scores.Download(ModelInfo.Value);
scores.ItemAdded += (score, _) =>
{
if (score.Equals(ModelInfo.Value))
game.PresentScore(ModelInfo.Value);
};
}
}
}

View File

@ -2,6 +2,8 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Scoring;
using osu.Game.Screens.Ranking;
using osu.Game.Screens.Ranking.Types;
@ -10,11 +12,31 @@ namespace osu.Game.Screens.Play
{
public class SoloResults : Results
{
[Resolved]
ScoreManager scores { get; set; }
public SoloResults(ScoreInfo score)
: base(score)
{
}
[BackgroundDependencyLoader]
private void load()
{
if (scores.IsAvailableLocally(Score) || hasOnlineReplay)
{
AddInternal(new ReplayDownloadButton(Score)
{
Anchor = Framework.Graphics.Anchor.BottomRight,
Origin = Framework.Graphics.Anchor.BottomRight,
Height = 80,
Width = 100,
});
}
}
private bool hasOnlineReplay => Score is APILegacyScoreInfo apiScore && apiScore.OnlineScoreID != null && apiScore.Replay;
protected override IEnumerable<IResultPageInfo> CreateResultPages() => new IResultPageInfo[]
{
new ScoreOverviewPageInfo(Score, Beatmap.Value),