예제 #1
0
        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;
                        }
                    }
                }
            }
        }
예제 #2
0
        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);
        }