mirror of
https://github.com/ppy/osu.git
synced 2025-01-15 09:22:54 +08:00
Merge branch 'master' into gameplay-leaderboard-update
This commit is contained in:
commit
99f2032fdf
@ -2,10 +2,10 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.Catch.Replays;
|
using osu.Game.Rulesets.Catch.Replays;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.UI
|
namespace osu.Game.Rulesets.Catch.UI
|
||||||
@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
{
|
{
|
||||||
private readonly CatchPlayfield playfield;
|
private readonly CatchPlayfield playfield;
|
||||||
|
|
||||||
public CatchReplayRecorder(Replay target, CatchPlayfield playfield)
|
public CatchReplayRecorder(Score target, CatchPlayfield playfield)
|
||||||
: base(target)
|
: base(target)
|
||||||
{
|
{
|
||||||
this.playfield = playfield;
|
this.playfield = playfield;
|
||||||
|
@ -13,6 +13,7 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.UI
|
namespace osu.Game.Rulesets.Catch.UI
|
||||||
{
|
{
|
||||||
@ -31,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay);
|
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay);
|
||||||
|
|
||||||
protected override ReplayRecorder CreateReplayRecorder(Replay replay) => new CatchReplayRecorder(replay, (CatchPlayfield)Playfield);
|
protected override ReplayRecorder CreateReplayRecorder(Score score) => new CatchReplayRecorder(score, (CatchPlayfield)Playfield);
|
||||||
|
|
||||||
protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, CreateDrawableRepresentation);
|
protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, CreateDrawableRepresentation);
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ using osu.Game.Rulesets.Objects;
|
|||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
@ -132,6 +133,6 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay);
|
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay);
|
||||||
|
|
||||||
protected override ReplayRecorder CreateReplayRecorder(Replay replay) => new ManiaReplayRecorder(replay);
|
protected override ReplayRecorder CreateReplayRecorder(Score score) => new ManiaReplayRecorder(score);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,18 +2,18 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.Mania.Replays;
|
using osu.Game.Rulesets.Mania.Replays;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.UI
|
namespace osu.Game.Rulesets.Mania.UI
|
||||||
{
|
{
|
||||||
public class ManiaReplayRecorder : ReplayRecorder<ManiaAction>
|
public class ManiaReplayRecorder : ReplayRecorder<ManiaAction>
|
||||||
{
|
{
|
||||||
public ManiaReplayRecorder(Replay replay)
|
public ManiaReplayRecorder(Score score)
|
||||||
: base(replay)
|
: base(score)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ using osu.Game.Rulesets.Osu.Configuration;
|
|||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Replays;
|
using osu.Game.Rulesets.Osu.Replays;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
|
|
||||||
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new OsuFramedReplayInputHandler(replay);
|
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new OsuFramedReplayInputHandler(replay);
|
||||||
|
|
||||||
protected override ReplayRecorder CreateReplayRecorder(Replay replay) => new OsuReplayRecorder(replay);
|
protected override ReplayRecorder CreateReplayRecorder(Score score) => new OsuReplayRecorder(score);
|
||||||
|
|
||||||
public override double GameplayStartTime
|
public override double GameplayStartTime
|
||||||
{
|
{
|
||||||
|
@ -2,18 +2,18 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.Osu.Replays;
|
using osu.Game.Rulesets.Osu.Replays;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.UI
|
namespace osu.Game.Rulesets.Osu.UI
|
||||||
{
|
{
|
||||||
public class OsuReplayRecorder : ReplayRecorder<OsuAction>
|
public class OsuReplayRecorder : ReplayRecorder<OsuAction>
|
||||||
{
|
{
|
||||||
public OsuReplayRecorder(Replay replay)
|
public OsuReplayRecorder(Score score)
|
||||||
: base(replay)
|
: base(score)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ using osu.Game.Replays;
|
|||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -82,6 +83,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
|
|
||||||
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new TaikoFramedReplayInputHandler(replay);
|
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new TaikoFramedReplayInputHandler(replay);
|
||||||
|
|
||||||
protected override ReplayRecorder CreateReplayRecorder(Replay replay) => new TaikoReplayRecorder(replay);
|
protected override ReplayRecorder CreateReplayRecorder(Score score) => new TaikoReplayRecorder(score);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,18 +2,18 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.Taiko.Replays;
|
using osu.Game.Rulesets.Taiko.Replays;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.UI
|
namespace osu.Game.Rulesets.Taiko.UI
|
||||||
{
|
{
|
||||||
public class TaikoReplayRecorder : ReplayRecorder<TaikoAction>
|
public class TaikoReplayRecorder : ReplayRecorder<TaikoAction>
|
||||||
{
|
{
|
||||||
public TaikoReplayRecorder(Replay replay)
|
public TaikoReplayRecorder(Score score)
|
||||||
: base(replay)
|
: base(score)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ using osu.Game.Replays;
|
|||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Tests.Visual.UserInterface;
|
using osu.Game.Tests.Visual.UserInterface;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -53,7 +54,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
recordingManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
recordingManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||||
{
|
{
|
||||||
Recorder = recorder = new TestReplayRecorder(replay)
|
Recorder = recorder = new TestReplayRecorder(new Score { Replay = replay })
|
||||||
{
|
{
|
||||||
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos),
|
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos),
|
||||||
},
|
},
|
||||||
@ -271,7 +272,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
internal class TestReplayRecorder : ReplayRecorder<TestAction>
|
internal class TestReplayRecorder : ReplayRecorder<TestAction>
|
||||||
{
|
{
|
||||||
public TestReplayRecorder(Replay target)
|
public TestReplayRecorder(Score target)
|
||||||
: base(target)
|
: base(target)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ using osu.Game.Replays;
|
|||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Tests.Visual.UserInterface;
|
using osu.Game.Tests.Visual.UserInterface;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -44,7 +45,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
recordingManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
recordingManager = new TestRulesetInputManager(new TestSceneModSettings.TestRulesetInfo(), 0, SimultaneousBindingMode.Unique)
|
||||||
{
|
{
|
||||||
Recorder = new TestReplayRecorder(replay)
|
Recorder = new TestReplayRecorder(new Score { Replay = replay })
|
||||||
{
|
{
|
||||||
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos)
|
ScreenSpaceToGamefield = pos => recordingManager.ToLocalSpace(pos)
|
||||||
},
|
},
|
||||||
@ -206,7 +207,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
internal class TestReplayRecorder : ReplayRecorder<TestAction>
|
internal class TestReplayRecorder : ReplayRecorder<TestAction>
|
||||||
{
|
{
|
||||||
public TestReplayRecorder(Replay target)
|
public TestReplayRecorder(Score target)
|
||||||
: base(target)
|
: base(target)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ using osu.Game.Replays.Legacy;
|
|||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Replays;
|
using osu.Game.Rulesets.Osu.Replays;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Tests.Beatmaps.IO;
|
using osu.Game.Tests.Beatmaps.IO;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
@ -272,7 +273,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
frames.Add(new LegacyReplayFrame(i * 100, RNG.Next(0, 512), RNG.Next(0, 512), buttonState));
|
frames.Add(new LegacyReplayFrame(i * 100, RNG.Next(0, 512), RNG.Next(0, 512), buttonState));
|
||||||
}
|
}
|
||||||
|
|
||||||
var bundle = new FrameDataBundle(frames);
|
var bundle = new FrameDataBundle(new ScoreInfo(), frames);
|
||||||
((ISpectatorClient)this).UserSentFrames(StreamingUser.Id, bundle);
|
((ISpectatorClient)this).UserSentFrames(StreamingUser.Id, bundle);
|
||||||
|
|
||||||
if (!sentState)
|
if (!sentState)
|
||||||
|
@ -27,6 +27,7 @@ using osu.Game.Rulesets;
|
|||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.Replays.Types;
|
using osu.Game.Rulesets.Replays.Types;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Tests.Visual.UserInterface;
|
using osu.Game.Tests.Visual.UserInterface;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -348,7 +349,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
internal class TestReplayRecorder : ReplayRecorder<TestAction>
|
internal class TestReplayRecorder : ReplayRecorder<TestAction>
|
||||||
{
|
{
|
||||||
public TestReplayRecorder()
|
public TestReplayRecorder()
|
||||||
: base(new Replay())
|
: base(new Score())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,13 +18,20 @@ namespace osu.Game.Online.RealtimeMultiplayer
|
|||||||
|
|
||||||
public int RulesetID { get; set; }
|
public int RulesetID { get; set; }
|
||||||
|
|
||||||
|
public string BeatmapChecksum { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string Name { get; set; } = "Unnamed room";
|
public string Name { get; set; } = "Unnamed room";
|
||||||
|
|
||||||
[NotNull]
|
[NotNull]
|
||||||
public IEnumerable<APIMod> Mods { get; set; } = Enumerable.Empty<APIMod>();
|
public IEnumerable<APIMod> Mods { get; set; } = Enumerable.Empty<APIMod>();
|
||||||
|
|
||||||
public bool Equals(MultiplayerRoomSettings other) => BeatmapID == other.BeatmapID && Mods.SequenceEqual(other.Mods) && RulesetID == other.RulesetID && Name.Equals(other.Name, StringComparison.Ordinal);
|
public bool Equals(MultiplayerRoomSettings other)
|
||||||
|
=> BeatmapID == other.BeatmapID
|
||||||
|
&& BeatmapChecksum == other.BeatmapChecksum
|
||||||
|
&& Mods.SequenceEqual(other.Mods)
|
||||||
|
&& RulesetID == other.RulesetID
|
||||||
|
&& Name.Equals(other.Name, StringComparison.Ordinal);
|
||||||
|
|
||||||
public override string ToString() => $"Name:{Name} Beatmap:{BeatmapID} Mods:{string.Join(',', Mods)} Ruleset:{RulesetID}";
|
public override string ToString() => $"Name:{Name} Beatmap:{BeatmapID} ({BeatmapChecksum}) Mods:{string.Join(',', Mods)} Ruleset:{RulesetID}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,34 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using osu.Game.Replays.Legacy;
|
using osu.Game.Replays.Legacy;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Online.Spectator
|
namespace osu.Game.Online.Spectator
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class FrameDataBundle
|
public class FrameDataBundle
|
||||||
{
|
{
|
||||||
|
public FrameHeader Header { get; set; }
|
||||||
|
|
||||||
public IEnumerable<LegacyReplayFrame> Frames { get; set; }
|
public IEnumerable<LegacyReplayFrame> Frames { get; set; }
|
||||||
|
|
||||||
public FrameDataBundle(IEnumerable<LegacyReplayFrame> frames)
|
public FrameDataBundle(ScoreInfo score, IEnumerable<LegacyReplayFrame> frames)
|
||||||
{
|
{
|
||||||
Frames = frames;
|
Frames = frames;
|
||||||
|
Header = new FrameHeader(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public FrameDataBundle(FrameHeader header, IEnumerable<LegacyReplayFrame> frames)
|
||||||
|
{
|
||||||
|
Header = header;
|
||||||
|
Frames = frames;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
59
osu.Game/Online/Spectator/FrameHeader.cs
Normal file
59
osu.Game/Online/Spectator/FrameHeader.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.Spectator
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class FrameHeader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The current combo of the score.
|
||||||
|
/// </summary>
|
||||||
|
public int Combo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum combo achieved up to the current point in time.
|
||||||
|
/// </summary>
|
||||||
|
public int MaxCombo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cumulative hit statistics.
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<HitResult, int> Statistics { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The time at which this frame was received by the server.
|
||||||
|
/// </summary>
|
||||||
|
public DateTimeOffset ReceivedTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Construct header summary information from a point-in-time reference to a score which is actively being played.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="score">The score for reference.</param>
|
||||||
|
public FrameHeader(ScoreInfo score)
|
||||||
|
{
|
||||||
|
Combo = score.Combo;
|
||||||
|
MaxCombo = score.MaxCombo;
|
||||||
|
|
||||||
|
// copy for safety
|
||||||
|
Statistics = new Dictionary<HitResult, int>(score.Statistics);
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public FrameHeader(int combo, int maxCombo, Dictionary<HitResult, int> statistics, DateTimeOffset receivedTime)
|
||||||
|
{
|
||||||
|
Combo = combo;
|
||||||
|
MaxCombo = maxCombo;
|
||||||
|
Statistics = statistics;
|
||||||
|
ReceivedTime = receivedTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ using osu.Game.Rulesets;
|
|||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.Replays.Types;
|
using osu.Game.Rulesets.Replays.Types;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Game.Online.Spectator
|
namespace osu.Game.Online.Spectator
|
||||||
@ -52,6 +53,9 @@ namespace osu.Game.Online.Spectator
|
|||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private IBeatmap currentBeatmap;
|
private IBeatmap currentBeatmap;
|
||||||
|
|
||||||
|
[CanBeNull]
|
||||||
|
private Score currentScore;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IBindable<RulesetInfo> currentRuleset { get; set; }
|
private IBindable<RulesetInfo> currentRuleset { get; set; }
|
||||||
|
|
||||||
@ -203,7 +207,7 @@ namespace osu.Game.Online.Spectator
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeginPlaying(GameplayBeatmap beatmap)
|
public void BeginPlaying(GameplayBeatmap beatmap, Score score)
|
||||||
{
|
{
|
||||||
if (isPlaying)
|
if (isPlaying)
|
||||||
throw new InvalidOperationException($"Cannot invoke {nameof(BeginPlaying)} when already playing");
|
throw new InvalidOperationException($"Cannot invoke {nameof(BeginPlaying)} when already playing");
|
||||||
@ -216,6 +220,8 @@ namespace osu.Game.Online.Spectator
|
|||||||
currentState.Mods = currentMods.Value.Select(m => new APIMod(m));
|
currentState.Mods = currentMods.Value.Select(m => new APIMod(m));
|
||||||
|
|
||||||
currentBeatmap = beatmap.PlayableBeatmap;
|
currentBeatmap = beatmap.PlayableBeatmap;
|
||||||
|
currentScore = score;
|
||||||
|
|
||||||
beginPlaying();
|
beginPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +314,9 @@ namespace osu.Game.Online.Spectator
|
|||||||
|
|
||||||
pendingFrames.Clear();
|
pendingFrames.Clear();
|
||||||
|
|
||||||
SendFrames(new FrameDataBundle(frames));
|
Debug.Assert(currentScore != null);
|
||||||
|
|
||||||
|
SendFrames(new FrameDataBundle(currentScore.ScoreInfo, frames));
|
||||||
|
|
||||||
lastSendTime = Time.Current;
|
lastSendTime = Time.Current;
|
||||||
}
|
}
|
||||||
|
@ -268,12 +268,12 @@ namespace osu.Game.Rulesets.UI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetRecordTarget(Replay recordingReplay)
|
public sealed override void SetRecordTarget(Score score)
|
||||||
{
|
{
|
||||||
if (!(KeyBindingInputManager is IHasRecordingHandler recordingInputManager))
|
if (!(KeyBindingInputManager is IHasRecordingHandler recordingInputManager))
|
||||||
throw new InvalidOperationException($"A {nameof(KeyBindingInputManager)} which supports recording is not available");
|
throw new InvalidOperationException($"A {nameof(KeyBindingInputManager)} which supports recording is not available");
|
||||||
|
|
||||||
var recorder = CreateReplayRecorder(recordingReplay);
|
var recorder = CreateReplayRecorder(score);
|
||||||
|
|
||||||
if (recorder == null)
|
if (recorder == null)
|
||||||
return;
|
return;
|
||||||
@ -327,7 +327,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
protected virtual ReplayInputHandler CreateReplayInputHandler(Replay replay) => null;
|
protected virtual ReplayInputHandler CreateReplayInputHandler(Replay replay) => null;
|
||||||
|
|
||||||
protected virtual ReplayRecorder CreateReplayRecorder(Replay replay) => null;
|
protected virtual ReplayRecorder CreateReplayRecorder(Score score) => null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a Playfield.
|
/// Creates a Playfield.
|
||||||
@ -516,8 +516,8 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets a replay to be used to record gameplay.
|
/// Sets a replay to be used to record gameplay.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="recordingReplay">The target to be recorded to.</param>
|
/// <param name="score">The target to be recorded to.</param>
|
||||||
public abstract void SetRecordTarget(Replay recordingReplay);
|
public abstract void SetRecordTarget(Score score);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when the interactive user requests resuming from a paused state.
|
/// Invoked when the interactive user requests resuming from a paused state.
|
||||||
|
@ -10,8 +10,8 @@ using osu.Framework.Input;
|
|||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Online.Spectator;
|
using osu.Game.Online.Spectator;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
public abstract class ReplayRecorder<T> : ReplayRecorder, IKeyBindingHandler<T>
|
public abstract class ReplayRecorder<T> : ReplayRecorder, IKeyBindingHandler<T>
|
||||||
where T : struct
|
where T : struct
|
||||||
{
|
{
|
||||||
private readonly Replay target;
|
private readonly Score target;
|
||||||
|
|
||||||
private readonly List<T> pressedActions = new List<T>();
|
private readonly List<T> pressedActions = new List<T>();
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private GameplayBeatmap gameplayBeatmap { get; set; }
|
private GameplayBeatmap gameplayBeatmap { get; set; }
|
||||||
|
|
||||||
protected ReplayRecorder(Replay target)
|
protected ReplayRecorder(Score target)
|
||||||
{
|
{
|
||||||
this.target = target;
|
this.target = target;
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
inputManager = GetContainingInputManager();
|
inputManager = GetContainingInputManager();
|
||||||
|
|
||||||
spectatorStreaming?.BeginPlaying(gameplayBeatmap);
|
spectatorStreaming?.BeginPlaying(gameplayBeatmap, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
private void recordFrame(bool important)
|
private void recordFrame(bool important)
|
||||||
{
|
{
|
||||||
var last = target.Frames.LastOrDefault();
|
var last = target.Replay.Frames.LastOrDefault();
|
||||||
|
|
||||||
if (!important && last != null && Time.Current - last.Time < (1000d / RecordFrameRate))
|
if (!important && last != null && Time.Current - last.Time < (1000d / RecordFrameRate))
|
||||||
return;
|
return;
|
||||||
@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
if (frame != null)
|
if (frame != null)
|
||||||
{
|
{
|
||||||
target.Frames.Add(frame);
|
target.Replay.Frames.Add(frame);
|
||||||
|
|
||||||
spectatorStreaming?.HandleFrame(frame);
|
spectatorStreaming?.HandleFrame(frame);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
@ -21,7 +22,6 @@ using osu.Game.Graphics.Containers;
|
|||||||
using osu.Game.IO.Archives;
|
using osu.Game.IO.Archives;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Replays;
|
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -157,14 +157,17 @@ namespace osu.Game.Screens.Play
|
|||||||
PrepareReplay();
|
PrepareReplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Replay recordingReplay;
|
[CanBeNull]
|
||||||
|
private Score recordingScore;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Run any recording / playback setup for replays.
|
/// Run any recording / playback setup for replays.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void PrepareReplay()
|
protected virtual void PrepareReplay()
|
||||||
{
|
{
|
||||||
DrawableRuleset.SetRecordTarget(recordingReplay = new Replay());
|
DrawableRuleset.SetRecordTarget(recordingScore = new Score());
|
||||||
|
|
||||||
|
ScoreProcessor.NewJudgement += result => ScoreProcessor.PopulateScore(recordingScore.ScoreInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
@ -758,9 +761,9 @@ namespace osu.Game.Screens.Play
|
|||||||
|
|
||||||
var score = new Score { ScoreInfo = CreateScore() };
|
var score = new Score { ScoreInfo = CreateScore() };
|
||||||
|
|
||||||
if (recordingReplay?.Frames.Count > 0)
|
if (recordingScore?.Replay.Frames.Count > 0)
|
||||||
{
|
{
|
||||||
score.Replay = recordingReplay;
|
score.Replay = recordingScore.Replay;
|
||||||
|
|
||||||
using (var stream = new MemoryStream())
|
using (var stream = new MemoryStream())
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user