/// <summary> /// Zamyka Lobby i wysyła informację do graczy o zamknięciu /// </summary> public void Close() { // Wysyłanie sygnału o zamknięciu Lobby var communicate = new StandardCommunicateSerializer(); var serializer = new LobbySignalsSerializer(); serializer.Signal = LobbySignalsSerializer.SIGNAL_CLOSED; serializer.Message = "Lobby has been closed"; communicate.CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL; communicate.Data = serializer.GetApiObject(); Broadcast(communicate.GetApiObject()); foreach (var client in ConnectedClients) { try { MainConfig.SERVER_SOCKET.DisconnectClient(client); } catch (ArgumentException) { Console.WriteLine("Client " + client.ToString() + " not connected, cannot disconnect."); } } Closed?.Invoke(this, null); Console.WriteLine("Lobby zamknięte: " + this.ToString()); Dispose(); }
protected override BaseSerializer PerformAction(ClientConnection conn, BaseSerializer requestData) { RequestSerializer data = (RequestSerializer)requestData; ResponseSerializer resp = (ResponseSerializer)InitializeResponseSerializer(); resp.Status = "OK"; Lobby lobby = (Lobby)conn.Session.Get("joined-lobby"); string username = (string)conn.Session.Get("username"); var signal = new ChatMessageSerializer() { Signal = ChatMessageSerializer.SIGNAL_CHAT_MESSAGE, Username = username, Message = username + ": " + data.Message }; Console.WriteLine("New message > {0}", username + ": " + data.Message); var result = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = signal.GetApiObject() }; lobby.Broadcast(result.GetApiObject()); return(resp); }
/// <summary> /// Treść komunikatu przy odłączeniu klienta od serwera przez zbyt długi czas autoryzacji /// </summary> /// <returns>Obiekt JSON do przekazania do klienta</returns> protected virtual JObject GetAuthorizationTimeoutSignal() { var resp = new StandardResponseSerializer() { Status = "AUTHORIZATION_TIMEOUT", Message = "Authorization failed - timeout" }; var result = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_AUTHORIZATION, Data = resp.GetApiObject() }; return(result.GetApiObject()); }
/// <summary> /// Treść komunikatu przy odłączeniu klienta od serwera /// </summary> /// <returns>Obiekt JSON do przekazania do klienta</returns> protected virtual JObject GetDisconnectedSignal() { var resp = new StandardResponseSerializer() { Status = "DISCONNECTED", Message = "You have been disconnected" }; var result = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_SERVER_SIGNAL, Data = resp.GetApiObject() }; return(result.GetApiObject()); }
public void Join(ClientConnection newConnection) { if (newConnection.Session.Has("joined-lobby")) { var lobby = newConnection.Session.Get("joined-lobby"); if (lobby != null) { throw new LobbyException("Cannot join two lobbies at once"); } } if (ConnectedClients.Contains(newConnection)) { throw new LobbyException("Already joined this lobby"); } if (LobbyOwner == null) { LobbyOwner = newConnection; } string username = newConnection.Session.Get <string>("username"); if (UsernameAlreadyJoined(username)) { throw new UsernameTakenException("Username taken"); } Console.WriteLine("Player " + username + " joined the lobby!"); newConnection.Session.Set("joined-lobby", this); newConnection.BeforeDispose += OnClientConnectionDisposed; // Broadcast o dołączeniu nowego gracza do Lobby var signal = new LobbySignalUserJoinedSerializer() { Signal = LobbySignalUserJoinedSerializer.SIGNAL_USER_JOINED, Message = "User " + username + " joined the lobby", Username = username }; var result = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = signal.GetApiObject() }; Broadcast(result.GetApiObject()); ConnectedClients.Add(newConnection); }
protected override BaseSerializer PerformAction(ClientConnection conn, BaseSerializer requestData) { RequestSerializer data = (RequestSerializer)requestData; ResponseSerializer resp = (ResponseSerializer)InitializeResponseSerializer(); resp.Status = "OK"; Lobby lobby = (Lobby)conn.Session.Get("joined-lobby"); Match game = lobby.Game; if (lobby.LobbyState != LobbyState.IDLE) { data.AddError(null, "INVALID_LOBBY_STATE", "Nie można usiąść w tym momencie gry"); data.ThrowException(); } try { var player = new Player((PlayerTag)data.PlaceTag, (string)conn.Session.Get("username")); game.AddPlayer(player); conn.Session.Set("player", player); Console.WriteLine("Player sat at " + data.PlaceTag + ": " + conn.Session.Get("username")); var broadcastData = new LobbySignalUserSatSerializer() { Signal = LobbySignalUserSatSerializer.SIGNAL_USER_SAT, PlaceTag = data.PlaceTag, Username = player.Name }; var broadcastWrapper = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = broadcastData.GetApiObject() }; lobby.Broadcast(broadcastWrapper.GetApiObject()); } catch (SeatTakenException) { data.AddError("PlaceTag", "SEAT_TAKEN", "Miejsce jest już zajęte"); data.ThrowException(); } catch (DuplicatedPlayerNameException) { data.AddError(null, "ALREADY_SEATED", "Użytkownik zajął już miejsce"); data.ThrowException(); } catch (WrongGameStateException) { data.AddError(null, "WRONG_GAME_STATE", "Nieprawidłowy stan gry dla tej operacji"); data.ThrowException(); } return(resp); }
protected override BaseSerializer PerformAction(ClientConnection conn, BaseSerializer requestData) { RequestSerializer data = (RequestSerializer)requestData; ResponseSerializer resp = (ResponseSerializer)InitializeResponseSerializer(); resp.Status = "OK"; Lobby lobby = (Lobby)conn.Session.Get("joined-lobby"); Match game = lobby.Game; Player player = new Player((PlayerTag)data.PlaceTag, (string)conn.Session.Get("username")); if (player != null) { try { game.RemovePlayer(player); conn.Session.Remove("player"); lobby.SetLobbyState(LobbyState.IDLE); var username = conn.Session.Get <string>("username"); var signal = new LobbySignalUserSittedOutSerializer() { Signal = LobbySignalUserSittedOutSerializer.SIGNAL_USER_SITTED_OUT, Message = "User " + username + " joined the lobby", Username = username, PlaceTag = (int)player.Tag }; var result = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = signal.GetApiObject() }; lobby.Broadcast(result.GetApiObject()); Console.WriteLine("Player left at " + data.PlaceTag + ": " + conn.Session.Get("username")); } catch (WrongPlayerException) { data.AddError("PlaceTag", "NOT_SEATEN_HERE", "Gracz nie siedzi na tym miejscu"); data.ThrowException(); } } return(resp); }
/// <summary> /// Zmienia stan lobby jeśli jest inny niż podany w argumencie "newState" /// </summary> /// <param name="newState">Nowy stan do ustawienia</param> /// <param name="sendBroadcast">Określa czy należy wysłać broadcast do graczy o zmianie stanu lobby (jeżeli nastąpi zmiana stanu)</param> public void SetLobbyState(LobbyState newState, bool sendBroadcast = true) { if (newState != LobbyState) { LobbyState = newState; if (sendBroadcast) { // Broadcast do graczy var broadcastData = new LobbySignalLobbyStateChangedSerializer() { Signal = LobbySignalLobbyStateChangedSerializer.SIGNAL_LOBBY_STATE_CHANGED, LobbyState = (int)LobbyState }; var broadcastWrapper = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = broadcastData.GetApiObject() }; Broadcast(broadcastWrapper.GetApiObject()); } } }
protected override BaseSerializer PerformAction(ClientConnection conn, BaseSerializer requestData) { RequestSerializer data = (RequestSerializer)requestData; ResponseSerializer resp = (ResponseSerializer)InitializeResponseSerializer(); resp.Status = "OK"; resp.Color = data.Color; resp.Height = data.Height; resp.X = data.X; resp.XX = data.XX; Lobby lobby = (Lobby)conn.Session.Get("joined-lobby"); Match game = lobby.Game; if (lobby.LobbyState != LobbyState.IN_GAME) { data.AddError(null, "INVALID_LOBBY_STATE", "Nie można licytować w tym stanie lobby"); data.ThrowException(); } string username = (string)conn.Session.Get("username"); int playerIndex = game.PlayerList.FindIndex(x => { return(username == x.Name); }); // gdy nie ma takiego gracza przy stole => wywal wyjątek if (playerIndex == -1) { data.AddError("PlayerUsername", "INVALID_PLAYER", "Nie ma takiego gracza"); data.ThrowException(); } var player = game.PlayerList[playerIndex]; var contract = new Contract((ContractHeight)data.Height, (ContractColor)data.Color, player.Tag, data.X, data.XX); if (!game.CheckAddBid(contract)) { data.AddError(null, "INVALID_CONTRACT", "Nie można zalicytować kontraktu"); data.ThrowException(); } game.AddBid(contract); Console.WriteLine(username + "> Bid: " + contract.ToString()); // Broadcast do pozostałych graczy var broadcastData = new LobbySignalNewBidSerializer() { Signal = LobbySignalNewBidSerializer.SIGNAL_NEW_BID, Username = username, PlaceTag = (int)player.Tag, Color = data.Color, Height = data.Height, X = data.X, XX = data.XX }; var broadcastWrapper = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = broadcastData.GetApiObject() }; lobby.Broadcast(broadcastWrapper.GetApiObject()); // Broadcast o przepasowaniu całej licytacji, nowe rozdanie if (game.CurrentBidding.IsEnd() && game.CurrentBidding.HighestContract.ContractColor == ContractColor.NONE) { game.GameState = GameState.BIDDING; game.StartBidding(); var bData = new LobbySignalGameStartedNextBiddingSerializer() { Signal = LobbySignalGameStartedNextBiddingSerializer.SIGNAL_GAME_STARTED_NEXT_BIDDING, PointsNSAboveLine = game.PointsNS[1], PointsNSBelowLine = game.PointsNS[0], PointsWEAboveLine = game.PointsWE[1], PointsWEBelowLine = game.PointsWE[0], RoundsNS = game.RoundsNS, RoundsWE = game.RoundsWE }; var bWrapper = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = bData.GetApiObject() }; lobby.Broadcast(bWrapper.GetApiObject()); } return(resp); }
public void RemoveFromLobby(ClientConnection client) { if (!ConnectedClients.Contains(client)) { throw new ArgumentException("Client not connected to Lobby"); } // Komunikat o opuszczeniu Lobby przez użytkownika string username = client.Session.Get <string>("username"); var signal = new LobbySignalUserRemovedSerializer() { Signal = LobbySignalUserRemovedSerializer.SINGAL_USER_REMOVED, Message = "User " + username + " left the lobby", Username = username }; var player = Game.GetPlayerByUsername(username); if (player != null) { Game.RemovePlayer(player); signal.WasSitted = true; signal.PlaceTag = (int)player.Tag; SetLobbyState(LobbyState.IDLE); // Użytkownik siedział przy stole, jeśli gra była w trakcie, należy ją zapauzować } else { signal.WasSitted = false; } var result = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = signal.GetApiObject() }; Broadcast(result.GetApiObject()); // Usuwamy klienta z Lobby ConnectedClients.Remove(client); client.BeforeDispose -= OnClientConnectionDisposed; Console.WriteLine("Użytkownik usunięty z Lobby: " + username); // Ustawianie nowego właściciela Lobby if (LobbyOwner == client) { if (ConnectedClients.Count > 0) { LobbyOwner = ConnectedClients.First(); } else { if (ParentManager == null) { Close(); } else { ParentManager.CloseLobby(Id); } } } client.Dispose(); }
private void Listen() { TcpListener = new TcpListener(IpAddress, Port); TcpListener.Start(); List <ClientConnection> toRemove = new List <ClientConnection>(); List <ClientConnection> currentlyAuthorized = new List <ClientConnection>(); while (true) { // Komunikaty toRemove.Clear(); foreach (var connection in AuthorizedConnections) { try { connection.SendCommunicates(); } catch (IOException) { toRemove.Add(connection); } catch (ObjectDisposedException) { toRemove.Add(connection); } catch (InvalidOperationException) { toRemove.Add(connection); } catch (Exception) { Console.WriteLine("Nie można było wysłać komunikatów do klienta: " + connection.ToString()); } } // Usuwanie zamkniętych połączeń foreach (var connection in toRemove) { connection.Dispose(); AuthorizedConnections.Remove(connection); } toRemove.Clear(); foreach (var connection in UnauthorizedConnections) { try { connection.SendCommunicates(); } catch (IOException) { toRemove.Add(connection); } catch (ObjectDisposedException) { toRemove.Add(connection); } catch (InvalidOperationException) { toRemove.Add(connection); } catch (Exception) { Console.WriteLine("Nie można było wysłać komunikatów do klienta: " + connection.ToString()); } } // Usuwanie zamkniętych połączeń foreach (var connection in toRemove) { connection.Dispose(); UnauthorizedConnections.Remove(connection); } // Zautoryzowane połączenia bool canContinue; toRemove.Clear(); foreach (var connection in AuthorizedConnections) { if (connection.DataAvailable) { connection.LastActivateAt = DateTime.Now; JObject data = connection.GetData(); JObject response; canContinue = true; // Inicjalna walidacja (Bierzemy kod zapytania, jeśli został podany) var initialCheck = new StandardRequestSerializer(data); try { initialCheck.Validate(); } catch (ValidationException) { // Inicjalny format nie przechodzi sprawdzenia var result = new StandardCommunicateSerializer(); var resp = new StandardResponseSerializer(); result.CommunicateType = StandardCommunicateSerializer.TYPE_REQUEST_ERROR; resp.Status = "INVALID_FORMAT"; resp.Message = "Request failed initial validation"; result.Data = resp.GetApiObject(); response = result.GetApiObject(); connection.WriteData(response); connection.Flush(); canContinue = false; } if (canContinue) { try { try { var resp = HandleRequest(connection, initialCheck.Data); var respWrapper = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_RESPONSE, RequestCode = initialCheck.RequestCode, Data = resp }; response = respWrapper.GetApiObject(); } catch (ValidationException e) { var resp = e.GetJson(); var respWrapper = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_RESPONSE, RequestCode = initialCheck.RequestCode, Data = resp }; response = respWrapper.GetApiObject(); } } catch (Exception e) { var resp = new StandardResponseSerializer() { Status = "ERR_INTERNAL", Message = "Wystąpił wewnętrzny błąd serwera" }; var respWrapper = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_REQUEST_ERROR, RequestCode = initialCheck.RequestCode, Data = resp.GetApiObject() }; response = respWrapper.GetApiObject(); } try { connection.WriteData(response); connection.Flush(); } catch (IOException) { toRemove.Add(connection); } catch (InvalidOperationException) { toRemove.Add(connection); } } } else if (TimeSpan.Compare(DateTime.Now - connection.LastActivateAt, MaxIdleTime) > 0) { Console.WriteLine("IDLE CHECK"); connection.LastActivateAt = DateTime.Now; var wrappedResponse = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_CONNECTION_CHECK, RequestCode = -1, Data = null }; try { connection.WriteData(wrappedResponse.GetApiObject()); } catch (IOException) { toRemove.Add(connection); } catch (ObjectDisposedException) { toRemove.Add(connection); } catch (InvalidOperationException) { toRemove.Add(connection); } catch (Exception) { Console.WriteLine("Nie można było wysłać komunikatów do klienta: " + connection.ToString()); } } } // Usuwanie zamkniętych połączeń foreach (var connection in toRemove) { connection.Dispose(); AuthorizedConnections.Remove(connection); } // Niezautoryzowane połączenia toRemove.Clear(); foreach (var connection in UnauthorizedConnections) { bool authorized = false; if (connection.DataAvailable) { canContinue = true; JObject data = connection.GetData(); var initialCheck = new StandardRequestSerializer(data); try { try { initialCheck.Validate(); } catch (ValidationException e) { var wrappedResponse = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_AUTHORIZATION, RequestCode = initialCheck.RequestCode, Data = GetAuthorizationResponseFailed() }; connection.WriteData(wrappedResponse.GetApiObject()); connection.Flush(); canContinue = false; } if (canContinue) { // Zero zaufania do niezautoryzowanych połączeń try { if (AuthorizeConnection(connection, initialCheck.Data)) { var response = GetAuthorizationResponseSuccessful(); var wrappedResponse = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_AUTHORIZATION, RequestCode = initialCheck.RequestCode, Data = response }; authorized = true; // Informacja dla odbiorcy o poprawnej autoryzacji connection.WriteData(wrappedResponse.GetApiObject()); connection.Flush(); connection.LastActivateAt = DateTime.Now; currentlyAuthorized.Add(connection); } else { var response = GetAuthorizationResponseFailed(); var wrappedResponse = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_AUTHORIZATION, RequestCode = initialCheck.RequestCode, Data = response }; connection.WriteData(wrappedResponse.GetApiObject()); connection.Flush(); } } catch (ValidationException e) { var wrappedResponse = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_AUTHORIZATION, RequestCode = initialCheck.RequestCode, Data = GetAuthorizationResponseFailed() }; connection.WriteData(wrappedResponse.GetApiObject()); connection.Flush(); } } } catch (IOException e) { // Połączenie socketu rozłączone toRemove.Add(connection); } catch (ObjectDisposedException e) { // Połączenie socketu rozłączone toRemove.Add(connection); } catch (InvalidOperationException) { toRemove.Add(connection); } catch (Exception e) { Console.WriteLine("Nieobsłużony wyjątek dla zapytania od połączenia " + connection.ToString() + "\n" + e.ToString()); } } if (!authorized && TimeSpan.Compare(connection.GetConnectionTime(), TimeForAuthorization) > 0) { connection.WriteData(GetAuthorizationTimeoutSignal()); connection.Flush(); connection.TcpClient.Close(); toRemove.Add(connection); } } // Finalizacja przenoszenie połączenia po zautoryzowaniu lub zamknięciu foreach (var connection in currentlyAuthorized) { UnauthorizedConnections.Remove(connection); AuthorizedConnections.Add(connection); } currentlyAuthorized.Clear(); foreach (var connection in toRemove) { connection.Dispose(); UnauthorizedConnections.Remove(connection); } // Odłączanie klientów do odłączenia foreach (var connection in ClientsToDisconnect) { if (AuthorizedConnections.Contains(connection)) { try { connection.WriteData(GetDisconnectedSignal()); connection.Flush(); } catch (Exception) { } connection.Dispose(); AuthorizedConnections.Remove(connection); } else if (UnauthorizedConnections.Contains(connection)) { try { connection.WriteData(GetDisconnectedSignal()); connection.Flush(); } catch (Exception) { } connection.Dispose(); UnauthorizedConnections.Remove(connection); } } // Nowe połączenia HandleIncommingConnections(); } }
protected override BaseSerializer PerformAction(ClientConnection conn, BaseSerializer requestData) { RequestSerializer data = (RequestSerializer)requestData; ResponseSerializer resp = (ResponseSerializer)InitializeResponseSerializer(); resp.Status = "OK"; Lobby lobby = (Lobby)conn.Session.Get("joined-lobby"); Match game = lobby.Game; if (lobby.LobbyState != LobbyState.IN_GAME) { data.AddError(null, "INVALID_LOBBY_STATE", "Nie można wyłożyć karty w tym stanie lobby"); data.ThrowException(); } if (game.GameState != GameState.PLAYING) { data.AddError(null, "INVALID_GAME_STATE", "Gra nie jest w poprawnym stanie do tej akcji"); data.ThrowException(); } var username = conn.Session.Get <string>("username"); Console.WriteLine(username + "> Card attempt: " + data.CardOwnerPosition + " " + data.Figure + " " + ((CardColor)data.Color).ToString()); if (!conn.Session.Has("player")) { data.AddError(null, "INVALID_USER", "Podany użytkownik nie jest uczestnikiem rozgrywki"); data.ThrowException(); } var player = conn.Session.Get <Player>("player"); var cardOwner = game.GetPlayerAt((PlayerTag)data.CardOwnerPosition); // Inny gracz niz my (gracz musi byc dziadkiem) if (player != game.GetPlayerAt((PlayerTag)data.CardOwnerPosition)) { if (player.Tag != game.CurrentBidding.Declarer) { data.AddError(null, "INVALID_HAND", "Nie można wyłożyć karty z ręki tego gracza"); data.ThrowException(); } if (((int)player.Tag + 2) % 4 == (int)game.CurrentBidding.Declarer) { // Próbujemy wyłożyć kartę kogoś innego niż dziadka data.AddError(null, "INVALID_HAND", "Nie można wyłożyć karty jako dziadek"); data.ThrowException(); } } else { if (((int)player.Tag + 2) % 4 == (int)game.CurrentBidding.Declarer) { // Jesteśmy dziadkiem data.AddError(null, "INVALID_HAND", "Nie można wyłożyć karty jako dziadek"); data.ThrowException(); } } // czy gracz ma taką kartę na ręce bool cardFound = false; Card card = null; for (int i = 0; i < cardOwner.Hand.Length; i++) { if (cardOwner.Hand[i].Color == (CardColor)data.Color && cardOwner.Hand[i].Figure == (CardFigure)data.Figure) { cardFound = true; card = cardOwner.Hand[i]; break; } } // gracz nie ma takiej karty na ręce if (!cardFound) { data.AddError(null, "INVALID_CARD", "Gracz nie posiada takiej karty na ręce"); data.ThrowException(); } bool canPlayerPutCard = game.CheckNextCard(cardOwner.Tag, card.Color, card.Figure); // gracz nie może wyłożyć tej karty if (!canPlayerPutCard) { data.AddError(null, "INVALID_CARD", "Nie można wyłożyć tej karty"); data.ThrowException(); } game.NextCard((PlayerTag)data.CardOwnerPosition, card.Color, card.Figure); Console.WriteLine(username + "> Card: " + data.CardOwnerPosition + " " + (int)card.Figure + " " + card.Color.ToString()); var broadcastData = new PutCardSignalSerializer() { Signal = PutCardSignalSerializer.SIGNAL_USER_PUT_CARD, Username = username, OwnerPosition = data.CardOwnerPosition, CardFigure = data.Figure, CardColor = data.Color }; var broadcastWrapper = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = broadcastData.GetApiObject() }; lobby.Broadcast(broadcastWrapper.GetApiObject()); if (game.GameState == GameState.BIDDING) { var bData = new LobbySignalGameStartedNextBiddingSerializer() { Signal = LobbySignalGameStartedNextBiddingSerializer.SIGNAL_GAME_STARTED_NEXT_BIDDING, PointsNSAboveLine = game.PointsNS[1], PointsNSBelowLine = game.PointsNS[0], PointsWEAboveLine = game.PointsWE[1], PointsWEBelowLine = game.PointsWE[0], RoundsNS = game.RoundsNS, RoundsWE = game.RoundsWE }; var bWrapper = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = bData.GetApiObject() }; lobby.Broadcast(bWrapper.GetApiObject()); } else if (game.GameState == GameState.GAME_FINISHED) { var bData = new LobbySignalGameFinishedSerializer() { Signal = LobbySignalGameFinishedSerializer.SIGNAL_GAME_FINISHED, Winner = (game.RoundsNS == 2) ? (short)0 : (short)1, PointsNS = game.PointsNS[0] + game.PointsNS[1], PointsWE = game.PointsWE[0] + game.PointsWE[1], RoundsNS = game.RoundsNS, RoundsWE = game.RoundsWE }; var bWrapper = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = bData.GetApiObject() }; lobby.Broadcast(bWrapper.GetApiObject()); } resp.CardFigure = (int)card.Figure; resp.CardColor = (int)card.Color; resp.OwnerPosition = (int)data.CardOwnerPosition; return(resp); }
protected override BaseSerializer PerformAction(ClientConnection conn, BaseSerializer requestData) { RequestSerializer data = (RequestSerializer)requestData; ResponseSerializer resp = (ResponseSerializer)InitializeResponseSerializer(); resp.Status = "OK"; Lobby lobby = conn.Session.Get <Lobby>("joined-lobby"); Match game = lobby.Game; // Check czy ktokolwiek w ogóle siedzi na tym miejscu var playerAtPlace = lobby.Game.GetPlayerAt((PlayerTag)data.PlaceTag); if (playerAtPlace == null) { data.AddError("PlaceTag", "NO_PLAYER_HERE", "Żaden gracz nie siedzi na tym miejscu"); data.ThrowException(); } // Check uprawnień w przypadku, gdy nie jesteśmy właścicielem Lobby if (lobby.LobbyOwner != conn) { if (playerAtPlace.Name != conn.Session.Get <string>("username")) { data.AddError(null, "FORBIDDEN", "Brak uprawnień do tej czynności."); data.ThrowException(); } } // Lepiej jeśli cokolwiek zepsuje się po usunięciu gracza ze stołu. Wtedy rozgrywkę będzie można kontynuować mimo błędu lobby.Game.RemovePlayer(playerAtPlace); lobby.SetLobbyState(LobbyState.IDLE); // Jeśli Lobby miało rozpoczętą grę, zostanie zapauzowane var username = playerAtPlace.Name; var signal = new LobbySignalUserSittedOutSerializer() { Signal = LobbySignalUserSittedOutSerializer.SIGNAL_USER_SITTED_OUT, Message = "User " + username + " joined the lobby", Username = username, PlaceTag = (int)playerAtPlace.Tag }; var result = new StandardCommunicateSerializer() { CommunicateType = StandardCommunicateSerializer.TYPE_LOBBY_SIGNAL, Data = signal.GetApiObject() }; lobby.Broadcast(result.GetApiObject()); var index = lobby.ConnectedClients.FindIndex((client) => { return(client.Session.Get <string>("username") == playerAtPlace.Name); }); if (index != -1) { var client = lobby.ConnectedClients[index]; client.Session.Remove("player"); } return(resp); }