private void revealCharOfWord(object sender, RoomInfo roomInfo) { bool fullyRevealed = false; if (roomInfo.CurrentWordRevealed.Count == 0) { // make placeholder for every char in word foreach (char c in roomInfo.CurrentWord) { roomInfo.CurrentWordRevealed.Add('_'); } } else { // get unrevelead chars List <int> unrevealedChars = new List <int>(); for (int i = 0; i < roomInfo.CurrentWordRevealed.Count; i++) { if (roomInfo.CurrentWordRevealed[i] == '_') { unrevealedChars.Add(i); } } // get random index int randomIdx = unrevealedChars[Server.rand.Next(unrevealedChars.Count)]; // reveal char roomInfo.CurrentWordRevealed[randomIdx] = roomInfo.CurrentWord[randomIdx]; fullyRevealed = unrevealedChars.Count == 1; } // send partly revealed word to all players, except drawer var players = this.getPlayersInGameExceptDrawer(roomInfo); // check if word is fully revealed string revealedWord; if (fullyRevealed) { (sender as Timer).Stop(); revealedWord = string.Join(" ", roomInfo.CurrentWord); } else { revealedWord = string.Join(" ", roomInfo.CurrentWordRevealed); } var choosedWordInfo = new ChoosedWordInfo { Word = revealedWord }; foreach (var player in players) { player.send(choosedWordInfo); } if (fullyRevealed) { this.nextDrawer(roomInfo); } }
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); } }