// Private Methods private void checkServerPassword(AdvancedNetworkLib.Client client, ServerPassword serverPassword) { if (serverPassword.Hash == Server.PasswordHash) { client.send(new Success { Job = Job.AcceptPassword }); client.UserData = new ClientUserData(); } else { client.send(new Error { Job = Job.AcceptPassword }); } }
private void Server_ObjectReceived(object sender, AdvancedNetworkLib.ObjectReceivedEventArgs e) { AdvancedNetworkLib.Client client = (sender as AdvancedNetworkLib.Client); ClientUserData userData = client.UserData as ClientUserData; RoomInfo roomInfo = this.rooms.Find(c => c.Name == userData?.RoomName); var obj = e.Object; if (obj is ServerPassword) { ServerPassword serverPassword = obj as ServerPassword; this.checkServerPassword(client, serverPassword); } else if (obj is ChangeState) { var oldState = userData.State; ChangeState changeState = obj as ChangeState; userData.State = changeState.State; if (userData.State == State.RoomChoice) { userData.PlayerName = string.Empty; userData.RoomName = string.Empty; userData.Password = 0; userData.IsDrawing = false; userData.Points = 0; userData.Host = false; // if player was in lobby if (oldState == State.Lobby || oldState == State.LobbyReady) { this.sendLobbyListToAll(roomInfo); } // if player was in game if (oldState == State.Game) { // check if only one player is left in game var playersInGame = this.getPlayersInGame(roomInfo); if (playersInGame.Count() == 1) { // kick last player in game playersInGame.First().send(new KickedNoMorePlayer()); } else if (playersInGame.Count() > 1) { // update ranklist for players in game this.sendRankListToAll(roomInfo); } } // update and send roomlist this.sendRoomListToAll(); } else if (userData.State == State.RoomCreation) { string randomRoomName = string.Empty; // generate random room name // TODO: better performance when checking host boolean first int i = 1000; while (Server.Clients.Count(c => (c.UserData as ClientUserData).RoomName == (randomRoomName = $"Room{Server.rand.Next(0, 999).ToString().PadLeft(3, '0')}") && (c.UserData as ClientUserData).Host) > 0 && i-- > 0) { } client.send(new RandomRoomName { Name = randomRoomName }); } else if (userData.State == State.LobbyReady || userData.State == State.Lobby) { if (userData.PlayerName == string.Empty) { string randomPlayerName = string.Empty; // generate random room name var players = this.getPlayers(roomInfo); while (players.Any(p => { return((p.UserData as ClientUserData).PlayerName == (randomPlayerName = $"Player{Server.rand.Next(0, 999).ToString().PadLeft(3, '0')}")); })) { } userData.PlayerName = randomPlayerName; client.send(new RandomPlayerName { Name = randomPlayerName }); // update and send lobbylist this.sendLobbyListToAll(roomInfo); } else { string newPlayerName = changeState.Data as string; // check if any player has already the same name int playerWithSameName = Server.Clients.Count(c => c.UserData != null && c != client && (c.UserData as ClientUserData).RoomName == userData.RoomName && (c.UserData as ClientUserData).PlayerName == newPlayerName); if (playerWithSameName > 0) { client.send(new Error { Job = Job.NameChange }); } else { // name is free and will be used userData.PlayerName = newPlayerName; if (userData.Host) { client.send(new Success { Job = Job.NameChange }); } else { bool hostIsPlaying = Server.Clients.Count(c => c.UserData != null && (c.UserData as ClientUserData).RoomName == userData.RoomName && (c.UserData as ClientUserData).Host && (c.UserData as ClientUserData).State == State.Game) > 0; client.send(new Success { Job = hostIsPlaying ? Job.GameStart : Job.NameChange }); } // update and send lobbylist this.sendLobbyListToAll(roomInfo); } } // update and send roomlist this.sendRoomListToAll(); } else if (userData.State == State.Game) { if (userData.Host) { // send ranklist this.sendRankListToAll(roomInfo); // tell other players that the game starts var players = this.getPlayersInLobbyAndReady(roomInfo); this.sendObjectToPlayers(players, new StartGame()); } else { // check if player joins later if (this.rooms.Exists(c => c.Name == userData.RoomName && c.Started)) { // this player joins later // send ranklist this.sendRankListToAll(roomInfo); // get current drawer and send drawing request var currentDrawer = this.getCurrentDrawer(roomInfo); if (currentDrawer != null) { currentDrawer.send(new DrawingRequest()); } } else { // count players in lobby var playersInLobbyCount = this.getPlayersInLobbyAndReady(roomInfo).Count(); // start game when all players are in the game if (playersInLobbyCount == 0) { // start game for the first time roomInfo.Started = true; // start first round this.startRound(roomInfo); } } } this.sendRoomListToAll(); } this.updateCountLabels(); } else if (obj is CreateRoom) { CreateRoom createRoom = obj as CreateRoom; this.createRoom(client, createRoom); } else if (obj is JoinRoom) { JoinRoom joinRoom = obj as JoinRoom; this.joinRoom(client, joinRoom); } else if (obj is StartGame) { int playerCount = this.getPlayers(roomInfo).Count(); int playerCountReady = this.getPlayersInLobbyAndReady(roomInfo).Count(); if (playerCount != playerCountReady || playerCount < 2) { client.send(new Error { Job = Job.GameStart }); } else { client.send(new Success { Job = Job.GameStart }); } } else if (obj is ChatMessage) { var chatMessage = obj as ChatMessage; chatMessage.PlayerName = userData.PlayerName; // get all clients in the same room and that are playing var players = this.getPlayersInGame(roomInfo); // check if entered word is equal to searched word bool foundWord = (roomInfo.CurrentWord.ToLower() == chatMessage.Text.ToLower()); if (foundWord && (roomInfo.RoundInfo.PlayerTimes.ContainsKey(userData.PlayerName) || userData.IsDrawing)) { client.send(new WhatDoYouWantInfo()); } else { var foundWordInfo = foundWord ? new FoundWordInfo { PlayerName = userData.PlayerName } : null; if (foundWord) { // give points roomInfo.RoundInfo.PlayerTimes.Add(userData.PlayerName, 500 * ((players.Count() - 1) - roomInfo.RoundInfo.PlayerTimes.Count)); } foreach (var player in players) { if (foundWord) { player.send(foundWordInfo); } else { player.send(chatMessage); } } // check if this is the last player that found the word if (foundWord && roomInfo.RoundInfo.PlayerTimes.Count == players.Count() - 1) { // end round roomInfo.RoundInfo.WordUpdateTimer.Stop(); // send revealed word string revealedWord = string.Join(" ", roomInfo.CurrentWord); var choosedWordInfo = new ChoosedWordInfo { Word = revealedWord }; this.sendObjectToPlayers(players, choosedWordInfo); this.nextDrawer(roomInfo); } } } else if (obj is Drawing) { // get every player in the same room, except drawer var players = this.getPlayersInGameExceptDrawer(roomInfo); this.sendObjectToPlayers(players, obj); } else if (obj is ChoosedWord) { var choosenWord = obj as ChoosedWord; roomInfo.CurrentWord = choosenWord.Word; roomInfo.CurrentWordRevealed.Clear(); // store choosen word to list with choosen words => solution is a bit ugly roomInfo.ChoosenWordIndices.Add(this.wordList.IndexOf(this.wordList.First(w => w.Word == choosenWord.Word))); var timer = roomInfo.RoundInfo.WordUpdateTimer = new Timer(); timer.Interval = (int)((this.roundDuration * 1000.0) / choosenWord.Word.Length); timer.Tick += (s2, e2) => this.revealCharOfWord(s2, roomInfo); this.revealCharOfWord(timer, roomInfo); timer.Start(); } else if (obj is KickedByHost) { var playerName = (obj as KickedByHost).PlayerName; var player = this.getPlayerByName(playerName); player?.send(obj); } }