private void updateUserPlayingState(int userId, MultiplayerUserState state) { bool wasPlaying = CurrentMatchPlayingUserIds.Contains(userId); bool isPlaying = state >= MultiplayerUserState.WaitingForLoad && state <= MultiplayerUserState.FinishedPlay; if (isPlaying == wasPlaying) { return; } if (isPlaying) { CurrentMatchPlayingUserIds.Add(userId); } else { CurrentMatchPlayingUserIds.Remove(userId); } }
public void ChangeUserState(int userId, MultiplayerUserState newState) { Debug.Assert(Room != null); ((IMultiplayerClient)this).UserStateChanged(userId, newState); Schedule(() => { switch (Room.State) { case MultiplayerRoomState.WaitingForLoad: if (Room.Users.All(u => u.State != MultiplayerUserState.WaitingForLoad)) { foreach (var u in Room.Users.Where(u => u.State == MultiplayerUserState.Loaded)) { ChangeUserState(u.UserID, MultiplayerUserState.Playing); } ((IMultiplayerClient)this).MatchStarted(); ChangeRoomState(MultiplayerRoomState.Playing); } break; case MultiplayerRoomState.Playing: if (Room.Users.All(u => u.State != MultiplayerUserState.Playing)) { foreach (var u in Room.Users.Where(u => u.State == MultiplayerUserState.FinishedPlay)) { ChangeUserState(u.UserID, MultiplayerUserState.Results); } ChangeRoomState(MultiplayerRoomState.Open); ((IMultiplayerClient)this).ResultsReady(); FinishCurrentItem().Wait(); } break; } }); }
private void pressReadyButton(int?playingUserId = null) { // Can't use ClickButtonWhenEnabled<> due to needing to store the state after the button is enabled. AddUntilStep("wait for ready button to be enabled", () => readyButton.Enabled.Value); MultiplayerUserState lastState = MultiplayerUserState.Idle; MultiplayerRoomUser user = null; AddStep("click ready button", () => { user = playingUserId == null ? multiplayerClient.LocalUser : multiplayerClient.Room?.Users.Single(u => u.UserID == playingUserId); lastState = user?.State ?? MultiplayerUserState.Idle; InputManager.MoveMouseTo(readyButton); InputManager.Click(MouseButton.Left); }); AddUntilStep("wait for state change", () => user?.State != lastState); }
Task IMultiplayerClient.UserStateChanged(int userId, MultiplayerUserState state) { Scheduler.Add(() => { var user = Room?.Users.SingleOrDefault(u => u.UserID == userId); // TODO: user should NEVER be null here, see https://github.com/ppy/osu/issues/17713. if (user == null) { return; } user.State = state; updateUserPlayingState(userId, state); RoomUpdated?.Invoke(); }, false); return(Task.CompletedTask); }
public async Task ChangeState(MultiplayerUserState newState) { var room = await getLocalUserRoom(); using (room.LockForUpdate()) { var user = room.Users.Find(u => u.UserID == CurrentContextUserId); if (user == null) { failWithInvalidState("Local user was not found in the expected room"); } if (user.State == newState) { return; } ensureValidStateSwitch(room, user.State, newState); user.State = newState; // handle whether this user should be receiving gameplay messages or not. switch (newState) { case MultiplayerUserState.Idle: await Groups.RemoveFromGroupAsync(Context.ConnectionId, GetGroupId(room.RoomID, true)); break; case MultiplayerUserState.Ready: await Groups.AddToGroupAsync(Context.ConnectionId, GetGroupId(room.RoomID, true)); break; } await Clients.Group(GetGroupId(room.RoomID)).UserStateChanged(CurrentContextUserId, newState); await updateRoomStateIfRequired(room); } }
Task IMultiplayerClient.UserStateChanged(int userId, MultiplayerUserState state) { if (Room == null) { return(Task.CompletedTask); } Scheduler.Add(() => { if (Room == null) { return; } Room.Users.Single(u => u.UserID == userId).State = state; updateUserPlayingState(userId, state); RoomUpdated?.Invoke(); }, false); return(Task.CompletedTask); }
public override Task ChangeState(MultiplayerUserState newState) { ChangeUserState(api.LocalUser.Value.Id, newState); return(Task.CompletedTask); }
public abstract Task ChangeState(MultiplayerUserState newState);
private void ensureValidStateSwitch(MultiplayerRoom room, MultiplayerUserState oldState, MultiplayerUserState newState) { switch (newState) { case MultiplayerUserState.Idle: // any state can return to idle. break; case MultiplayerUserState.Ready: if (oldState != MultiplayerUserState.Idle) { throw new InvalidStateChangeException(oldState, newState); } break; case MultiplayerUserState.WaitingForLoad: // state is managed by the server. throw new InvalidStateChangeException(oldState, newState); case MultiplayerUserState.Loaded: if (oldState != MultiplayerUserState.WaitingForLoad) { throw new InvalidStateChangeException(oldState, newState); } break; case MultiplayerUserState.Playing: // state is managed by the server. throw new InvalidStateChangeException(oldState, newState); case MultiplayerUserState.FinishedPlay: if (oldState != MultiplayerUserState.Playing) { throw new InvalidStateChangeException(oldState, newState); } break; case MultiplayerUserState.Results: // state is managed by the server. throw new InvalidStateChangeException(oldState, newState); case MultiplayerUserState.Spectating: if (oldState != MultiplayerUserState.Idle && oldState != MultiplayerUserState.Ready) { throw new InvalidStateChangeException(oldState, newState); } break; default: throw new ArgumentOutOfRangeException(nameof(newState), newState, null); } }
private Task changeAndBroadcastUserState(MultiplayerRoom room, MultiplayerRoomUser user, MultiplayerUserState state) { user.State = state; return(Clients.Group(GetGroupId(room.RoomID)).UserStateChanged(user.UserID, user.State)); }
public Task ChangeState(MultiplayerUserState newState) => connection.InvokeAsync(nameof(IMultiplayerServer.ChangeState), newState);
public async Task UserCantChangeStateToReservedStates(MultiplayerUserState reservedState) { await hub.JoinRoom(room_id); await Assert.ThrowsAsync <InvalidStateChangeException>(() => hub.ChangeState(reservedState)); }
private void changeUserState(int userId, MultiplayerUserState newState) { multiplayerRoom.Users.Single(u => u.UserID == userId).State = newState; raiseRoomUpdated(); }
private void checkLocalUserState(MultiplayerUserState state) => AddUntilStep($"local user is {state}", () => localUser.State == state);
public InvalidStateChangeException(MultiplayerUserState oldState, MultiplayerUserState newState) : base($"Cannot change from {oldState} to {newState}") { }