public async Task NewUserConnectsAndStreamsData()
        {
            Mock <IHubCallerClients <ISpectatorClient> > mockClients = new Mock <IHubCallerClients <ISpectatorClient> >();
            Mock <ISpectatorClient> mockReceiver = new Mock <ISpectatorClient>();

            mockClients.Setup(clients => clients.All).Returns(mockReceiver.Object);
            mockClients.Setup(clients => clients.Group(SpectatorHub.GetGroupId(streamer_id))).Returns(mockReceiver.Object);

            Mock <HubCallerContext> mockContext = new Mock <HubCallerContext>();

            mockContext.Setup(context => context.UserIdentifier).Returns(streamer_id.ToString());
            hub.Context = mockContext.Object;
            hub.Clients = mockClients.Object;

            await hub.BeginPlaySession(new SpectatorState(88));

            // check all other users were informed that streaming began
            mockClients.Verify(clients => clients.All, Times.Once);
            mockReceiver.Verify(clients => clients.UserBeganPlaying(streamer_id, It.Is <SpectatorState>(m => m.Equals(state))), Times.Once());

            // check state data was added
            var cacheState = await cache.GetStringAsync(SpectatorHub.GetStateId(streamer_id));

            Assert.Equal(state, JsonConvert.DeserializeObject <SpectatorState>(cacheState));

            var data = new FrameDataBundle(new[] { new LegacyReplayFrame(1234, 0, 0, ReplayButtonState.None) });

            // check streaming data is propagating to watchers
            await hub.SendFrameData(data);

            mockReceiver.Verify(clients => clients.UserSentFrames(streamer_id, data));
        }
Beispiel #2
0
        private void userSentFrames(int userId, FrameDataBundle data)
        {
            if (userId != targetUser.Id)
            {
                return;
            }

            // this should never happen as the server sends the user's state on watching,
            // but is here as a safety measure.
            if (replay == null)
            {
                return;
            }

            foreach (var frame in data.Frames)
            {
                IConvertibleReplayFrame convertibleFrame = rulesetInstance.CreateConvertibleReplayFrame();
                convertibleFrame.FromLegacy(frame, beatmap.Value.Beatmap);

                var convertedFrame = (ReplayFrame)convertibleFrame;
                convertedFrame.Time = frame.Time;

                replay.Frames.Add(convertedFrame);
            }
        }
Beispiel #3
0
        private void userSentFrames(int userId, FrameDataBundle bundle)
        {
            lock (stateLock)
            {
                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);
                }
            }
        }
Beispiel #4
0
        private void userSentFrames(int userId, FrameDataBundle data)
        {
            // this is not scheduled as it handles propagation of frames even when in a child screen (at which point we are not alive).
            // probably not the safest way to handle this.

            if (userId != targetUser.Id)
            {
                return;
            }

            lock (scoreLock)
            {
                // this should never happen as the server sends the user's state on watching,
                // but is here as a safety measure.
                if (score == null)
                {
                    return;
                }

                // rulesetInstance should be guaranteed to be in sync with the score via scoreLock.
                Debug.Assert(rulesetInstance != null && rulesetInstance.RulesetInfo.Equals(score.ScoreInfo.Ruleset));

                foreach (var frame in data.Frames)
                {
                    IConvertibleReplayFrame convertibleFrame = rulesetInstance.CreateConvertibleReplayFrame();
                    convertibleFrame.FromLegacy(frame, beatmap.Value.Beatmap);

                    var convertedFrame = (ReplayFrame)convertibleFrame;
                    convertedFrame.Time = frame.Time;

                    score.Replay.Frames.Add(convertedFrame);
                }
            }
        }
Beispiel #5
0
        private void userSentFrames(int userId, FrameDataBundle bundle)
        {
            if (userId != score.ScoreInfo.User.Id)
            {
                return;
            }

            if (!LoadedBeatmapSuccessfully)
            {
                return;
            }

            if (!this.IsCurrentScreen())
            {
                return;
            }

            bool isFirstBundle = score.Replay.Frames.Count == 0;

            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);
            }

            if (isFirstBundle && score.Replay.Frames.Count > 0)
            {
                NonFrameStableSeek(score.Replay.Frames[0].Time);
            }
        }
Beispiel #6
0
 private void handleIncomingFrames(int userId, FrameDataBundle bundle)
 {
     if (userScores.TryGetValue(userId, out var trackedData))
     {
         trackedData.LastHeader = bundle.Header;
         trackedData.UpdateScore(scoreProcessor, scoringMode.Value);
     }
 }
        private void onNewFrames(int userId, FrameDataBundle frames)
        {
            Logger.Log($"Received {frames.Frames.Count()} new frames ({string.Join(',', frames.Frames.Select(f => ((int)f.Time).ToString()))})");

            foreach (var legacyFrame in frames.Frames)
            {
                var frame = new TestReplayFrame();
                frame.FromLegacy(legacyFrame, null, null);
                replay.Frames.Add(frame);
            }
        }
Beispiel #8
0
        public void TestFinalFrameInBundleHasHeader()
        {
            FrameDataBundle lastBundle = null;

            AddStep("bind to client", () => spectatorClient.OnNewFrames += (_, bundle) => lastBundle = bundle);

            start(-1234);
            sendFrames();
            finish();

            AddUntilStep("bundle received", () => lastBundle != null);
            AddAssert("first frame does not have header", () => lastBundle.Frames[0].Header == null);
            AddAssert("last frame has header", () => lastBundle.Frames[^ 1].Header != null);
Beispiel #9
0
        public void SendFrames(int userId, int index, int count)
        {
            var frames = new List <LegacyReplayFrame>();

            for (int i = index; i < index + count; i++)
            {
                var buttonState = i == index + count - 1 ? ReplayButtonState.None : ReplayButtonState.Left1;

                frames.Add(new LegacyReplayFrame(i * 100, RNG.Next(0, 512), RNG.Next(0, 512), buttonState));
            }

            var bundle = new FrameDataBundle(new ScoreInfo {
                Combo = index + count
            }, frames);

            ((ISpectatorClient)this).UserSentFrames(userId, bundle);
        }
Beispiel #10
0
            public void SendFrames(int index, int count)
            {
                var frames = new List <LegacyReplayFrame>();

                for (int i = index; i < index + count; i++)
                {
                    var buttonState = i == index + count - 1 ? ReplayButtonState.None : ReplayButtonState.Left1;

                    frames.Add(new LegacyReplayFrame(i * 100, RNG.Next(0, 512), RNG.Next(0, 512), buttonState));
                }

                var bundle = new FrameDataBundle(new ScoreInfo(), frames);

                ((ISpectatorClient)this).UserSentFrames(StreamingUser.Id, bundle);

                if (!sentState)
                {
                    sendState(beatmapId);
                }
            }
Beispiel #11
0
        public void SendFrames(int userId, int count)
        {
            var frames = new List <LegacyReplayFrame>();

            int currentFrameIndex = userNextFrameDictionary[userId];
            int lastFrameIndex    = currentFrameIndex + count - 1;

            for (; currentFrameIndex <= lastFrameIndex; currentFrameIndex++)
            {
                // This is done in the next frame so that currentFrameIndex is updated to the correct value.
                if (frames.Count == FRAME_BUNDLE_SIZE)
                {
                    flush();
                }

                var buttonState = currentFrameIndex == lastFrameIndex ? ReplayButtonState.None : ReplayButtonState.Left1;
                frames.Add(new LegacyReplayFrame(currentFrameIndex * 100, RNG.Next(0, 512), RNG.Next(0, 512), buttonState));
            }

            flush();

            userNextFrameDictionary[userId] = currentFrameIndex;

            void flush()
            {
                if (frames.Count == 0)
                {
                    return;
                }

                var bundle = new FrameDataBundle(new ScoreInfo {
                    Combo = currentFrameIndex
                }, frames.ToArray());

                ((ISpectatorClient)this).UserSentFrames(userId, bundle);

                frames.Clear();
            }
        }
Beispiel #12
0
 private void handleIncomingFrames(int userId, FrameDataBundle bundle) => Schedule(() =>
 {
     if (!UserScores.TryGetValue(userId, out var trackedData))
Beispiel #13
0
 public Task SendFrames(FrameDataBundle data) => connection.SendAsync(nameof(ISpectatorServer.SendFrameData), data);
 public async Task SendFrameData(FrameDataBundle data)
 {
     Console.WriteLine($"Receiving frame data ({data.Frames.First()})..");
     await Clients.Group(GetGroupId(currentContextUserId)).UserSentFrames(currentContextUserId, data);
 }
Beispiel #15
0
 protected override Task SendFramesInternal(FrameDataBundle data) => ((ISpectatorClient)this).UserSentFrames(api.LocalUser.Value.Id, data);
Beispiel #16
0
 public async Task SendFrameData(FrameDataBundle data)
 {
     await Clients.Group(GetGroupId(CurrentContextUserId)).UserSentFrames(CurrentContextUserId, data);
 }
Beispiel #17
0
 Task ISpectatorClient.UserSentFrames(int userId, FrameDataBundle data)
 {
     Console.WriteLine($"{connection.ConnectionId} Received frames from {userId}: {data.Frames.First()}");
     return(Task.CompletedTask);
 }