1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 10:52:53 +08:00

Fix spectator crashing when converting mania replay frames

This commit is contained in:
smoogipoo 2021-05-31 19:24:22 +09:00
parent d2d0896298
commit 7f24518004
2 changed files with 37 additions and 29 deletions

View File

@ -9,6 +9,8 @@ using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Online.Spectator; using osu.Game.Online.Spectator;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Screens.Ranking; using osu.Game.Screens.Ranking;
@ -43,6 +45,36 @@ namespace osu.Game.Screens.Play
}); });
} }
protected override void LoadComplete()
{
base.LoadComplete();
spectatorClient.OnNewFrames += userSentFrames;
}
private void userSentFrames(int userId, FrameDataBundle bundle)
{
if (userId != score.ScoreInfo.User.Id)
return;
if (!LoadedBeatmapSuccessfully)
return;
if (!this.IsCurrentScreen())
return;
foreach (var frame in bundle.Frames)
{
IConvertibleReplayFrame convertibleFrame = GameplayRuleset.CreateConvertibleReplayFrame();
convertibleFrame.FromLegacy(frame, GameplayBeatmap.PlayableBeatmap);
var convertedFrame = (ReplayFrame)convertibleFrame;
convertedFrame.Time = frame.Time;
score.Replay.Frames.Add(convertedFrame);
}
}
protected override ResultsScreen CreateResults(ScoreInfo score) protected override ResultsScreen CreateResults(ScoreInfo score)
{ {
return new SpectatorResultsScreen(score); return new SpectatorResultsScreen(score);
@ -67,6 +99,8 @@ namespace osu.Game.Screens.Play
public override bool OnExiting(IScreen next) public override bool OnExiting(IScreen next)
{ {
spectatorClient.OnUserBeganPlaying -= userBeganPlaying; spectatorClient.OnUserBeganPlaying -= userBeganPlaying;
spectatorClient.OnNewFrames -= userSentFrames;
return base.OnExiting(next); return base.OnExiting(next);
} }
@ -85,7 +119,10 @@ namespace osu.Game.Screens.Play
base.Dispose(isDisposing); base.Dispose(isDisposing);
if (spectatorClient != null) if (spectatorClient != null)
{
spectatorClient.OnUserBeganPlaying -= userBeganPlaying; spectatorClient.OnUserBeganPlaying -= userBeganPlaying;
spectatorClient.OnNewFrames -= userSentFrames;
}
} }
} }
} }

View File

@ -15,8 +15,6 @@ using osu.Game.Database;
using osu.Game.Online.Spectator; using osu.Game.Online.Spectator;
using osu.Game.Replays; using osu.Game.Replays;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Scoring; using osu.Game.Scoring;
using osu.Game.Users; using osu.Game.Users;
@ -71,8 +69,6 @@ namespace osu.Game.Screens.Spectate
playingUserStates.BindTo(spectatorClient.PlayingUserStates); playingUserStates.BindTo(spectatorClient.PlayingUserStates);
playingUserStates.BindCollectionChanged(onPlayingUserStatesChanged, true); playingUserStates.BindCollectionChanged(onPlayingUserStatesChanged, true);
spectatorClient.OnNewFrames += userSentFrames;
managerUpdated = beatmaps.ItemUpdated.GetBoundCopy(); managerUpdated = beatmaps.ItemUpdated.GetBoundCopy();
managerUpdated.BindValueChanged(beatmapUpdated); managerUpdated.BindValueChanged(beatmapUpdated);
@ -197,29 +193,6 @@ namespace osu.Game.Screens.Spectate
Schedule(() => StartGameplay(userId, gameplayState)); Schedule(() => StartGameplay(userId, gameplayState));
} }
private void userSentFrames(int userId, FrameDataBundle bundle)
{
if (!userMap.ContainsKey(userId))
return;
if (!gameplayStates.TryGetValue(userId, out var gameplayState))
return;
// The ruleset instance should be guaranteed to be in sync with the score via ScoreLock.
Debug.Assert(gameplayState.Ruleset != null && gameplayState.Ruleset.RulesetInfo.Equals(gameplayState.Score.ScoreInfo.Ruleset));
foreach (var frame in bundle.Frames)
{
IConvertibleReplayFrame convertibleFrame = gameplayState.Ruleset.CreateConvertibleReplayFrame();
convertibleFrame.FromLegacy(frame, gameplayState.Beatmap.Beatmap);
var convertedFrame = (ReplayFrame)convertibleFrame;
convertedFrame.Time = frame.Time;
gameplayState.Score.Replay.Frames.Add(convertedFrame);
}
}
/// <summary> /// <summary>
/// Invoked when a spectated user's state has changed. /// Invoked when a spectated user's state has changed.
/// </summary> /// </summary>
@ -260,8 +233,6 @@ namespace osu.Game.Screens.Spectate
if (spectatorClient != null) if (spectatorClient != null)
{ {
spectatorClient.OnNewFrames -= userSentFrames;
foreach (var (userId, _) in userMap) foreach (var (userId, _) in userMap)
spectatorClient.StopWatchingUser(userId); spectatorClient.StopWatchingUser(userId);
} }