private void MessageReceiver() { while (true) { byte[] data = _NetworkComms.GetMessage(); if (data == null) { Thread.Sleep(50); continue; } Message msg = JsonSerializer.Deserialize <Message>(data); if (msg != null) { //Ignore our own message if (msg.Sender != _UniqueID) { switch (msg.MsgType) { case MessageType.TurnInfo: HandleTurnInfoMessage(JsonSerializer.Deserialize <TurnInfoMessage>(data)); break; case MessageType.Response: ResponseMessage responseMessage = JsonSerializer.Deserialize <ResponseMessage>(data); //Only add message to queue if we are receiver if (responseMessage.Receiver == _UniqueID) { ResponseMessages.Enqueue(responseMessage); } break; case MessageType.AdvertiseLobby: AdvertiseLobbyMessages.Enqueue(JsonSerializer.Deserialize <AdvertiseLobbyMessage>(data)); break; case MessageType.JoinLobby: JoinLobbyMessage joinLobbyMessage = JsonSerializer.Deserialize <JoinLobbyMessage>(data); //Only add message to queue if we are receiver if (joinLobbyMessage.Receiver == _UniqueID) { JoinLobbyMessages.Enqueue(joinLobbyMessage); } break; default: Debug.WriteLine("Unknown message type: " + msg.MsgType); Debug.WriteLine(BitConverter.ToString(data)); break; } } } } }
public LobbyInfo JoinGame(string name, int lobbySize, int interfaceIndex, string address, int port) { _NetworkComms.JoinGroup(interfaceIndex, address, port); _NetworkComms.StartReceiving(); Stopwatch sw = new Stopwatch(); _LobbyInfo = new LobbyInfo(); PlayerInfo localPlayerInfo = new PlayerInfo { PlayerID = _UniqueID, PlayerName = name }; _logger.Log("Local player: " + localPlayerInfo.ToString()); _logger.Log("Looking for available lobby with size " + lobbySize + "..."); bool lobbyAvailable = false; sw.Start(); //Look for other advertising their lobby and check if size matches while (sw.ElapsedMilliseconds < 2000) { bool messageAvailable = AdvertiseLobbyMessages.TryDequeue(out AdvertiseLobbyMessage receivedMsg); if (messageAvailable) { //Check if advertised lobby size matches if (receivedMsg.LobbySize == lobbySize) { lobbyAvailable = true; } } else { Thread.Sleep(100); } } sw.Reset(); if (lobbyAvailable) { _logger.Log("Available lobby found, trying to join it..."); int hostID = 0; while (true) { bool messageAvailable = AdvertiseLobbyMessages.TryDequeue(out AdvertiseLobbyMessage receivedMsg); if (messageAvailable) { //Check if advertised lobby size matches if (receivedMsg.LobbySize != lobbySize) { continue; } //Check if lobby advertisement was from our host if (receivedMsg.Sender == hostID) { //Check if lobby is now full if (receivedMsg.LobbyInfo.Players.Count == lobbySize) { //Lobby full, we can proceed initiating game _LobbyInfo = receivedMsg.LobbyInfo; _logger.Log("Lobby is now full"); break; } } else { //Log message Debug.WriteLine("Received correct AdvertiseLobbyMessages: " + JsonSerializer.Serialize(receivedMsg)); //Check if we are already in lobby foreach (PlayerInfo info in receivedMsg.LobbyInfo.Players) { if (info.PlayerID == _UniqueID) { //We are in this lobby so we can set hostID hostID = receivedMsg.Sender; _logger.Log("We are added to lobby"); } } //If we don't have host try to join game if (hostID == 0) { JoinLobbyMessage joinLobbyMessage = new JoinLobbyMessage() { Sender = _UniqueID, MsgID = _JoinLobbyMessageID, Name = name, Receiver = receivedMsg.Sender }; _logger.Log("Sent request to join lobby, receiver: " + joinLobbyMessage.Receiver); _NetworkComms.SendMessage(JsonSerializer.SerializeToUtf8Bytes(joinLobbyMessage)); _JoinLobbyMessageNumber++; } } } else { Thread.Sleep(100); } } } else { _logger.Log("No available lobby found, creating own lobby..."); //Add local player to lobby _LobbyInfo.Players.Add(localPlayerInfo); string advertiseLobbyMessageID = _AdvertiseLobbyMessageID; _AdvertiseLobbyMessageNumber++; AdvertiseLobbyMessage advertiseLobbyMessage = new AdvertiseLobbyMessage() { Sender = _UniqueID, MsgID = advertiseLobbyMessageID, LobbySize = lobbySize, LobbyInfo = _LobbyInfo }; byte[] advertiseLobbyMessageBytes = JsonSerializer.SerializeToUtf8Bytes(advertiseLobbyMessage); //Advertise lobby until lobby full while (_LobbyInfo.Players.Count < lobbySize) { _logger.Log("Sent lobby advertisement"); _NetworkComms.SendMessage(advertiseLobbyMessageBytes); Thread.Sleep(500); bool joinLobbyMessageAvailable; do { joinLobbyMessageAvailable = JoinLobbyMessages.TryDequeue(out JoinLobbyMessage joinLobbyMessage); if (joinLobbyMessageAvailable) { //Log message _logger.Log("Received response to lobby advertisement from: Name: " + joinLobbyMessage.Name + ", ID: " + joinLobbyMessage.Sender); //Check if player is already in lobby if (IsThisPlayerInLobby(joinLobbyMessage.Sender) == false) { //Add new player to lobby PlayerInfo newPlayerInfo = new PlayerInfo { PlayerID = joinLobbyMessage.Sender, PlayerName = joinLobbyMessage.Name }; _LobbyInfo.Players.Add(newPlayerInfo); //Update lobbyInfo in advertisement message advertiseLobbyMessage.LobbyInfo = _LobbyInfo; //Serialize advertisement message advertiseLobbyMessageBytes = JsonSerializer.SerializeToUtf8Bytes(advertiseLobbyMessage); _logger.Log("New player added to lobby: " + newPlayerInfo.ToString()); } } } while (joinLobbyMessageAvailable); } _logger.Log("Lobby is now full"); //Lobby is now full, send some extra advertisements so all other nodes realize for sure that lobby is full for (int i = 0; i < 10; i++) { _NetworkComms.SendMessage(advertiseLobbyMessageBytes); Thread.Sleep(200); } } //Sort player list so that first one has smallest ID _LobbyInfo.Players.Sort((PlayerInfo a, PlayerInfo b) => { return(a.PlayerID.CompareTo(b.PlayerID)); }); //Search smallest playerID int smallestPlayerID = int.MaxValue; foreach (PlayerInfo info in _LobbyInfo.Players) { if (info.PlayerID < smallestPlayerID) { smallestPlayerID = info.PlayerID; } } //Set smallest playerID player as a dealer foreach (PlayerInfo info in _LobbyInfo.Players) { if (info.PlayerID == smallestPlayerID) { info.Dealer = true; } } _logger.Log("Players:"); foreach (PlayerInfo info in _LobbyInfo.Players) { _logger.Log(info.ToString()); } _logger.Log("Initiating game..."); _GameState.InitGame(_LobbyInfo.Players, _LobbyInfo.Players.Find(player => player.PlayerID == _UniqueID), smallestPlayerID); _logger.Log("Initing ready"); return(_LobbyInfo); }