예제 #1
0
        internal void ReceiveDiscoveryResponse(NetIncomingMessage message)
        {
            Debug.Assert(message.SenderEndPoint != null);

            // Read game info:
            DiscoveredGame discoveredGame = DiscoveredGame.ReadFromDiscoveryResponse(owner.appConfig, message);

            if (discoveredGame == null) // not a valid response
            {
                return;
            }

            // Check if we need to update an existing game:
            // (RemoteGameInfo could be versioned, if we were worried about packet ordering)
            for (int i = 0; i < discoveryList.Count; i++)
            {
                if (discoveryList[i].EndPoint.Equals(discoveredGame.EndPoint))
                {
                    discoveryList[i].CopyFrom(discoveredGame);
                    discoveryListDirty = true;
                    return;
                }
            }

            // Otherwise just add it:
            discoveryList.Add(discoveredGame);
            discoveryListDirty = true;
        }
예제 #2
0
        internal void CopyFrom(DiscoveredGame other)
        {
            GameInfo.CopyFrom(other.GameInfo);

            EndPoint        = other.EndPoint;
            expireTime      = other.expireTime;
            VersionMismatch = other.VersionMismatch;
            IsFull          = other.IsFull;
            applicationData = other.applicationData;             // <- assumed to be immutable
        }
예제 #3
0
        public void HandleMessage(NetIncomingMessage message, ref bool recycle)
        {
            Debug.Assert(!didDisconnect);

            RemotePeer senderRemotePeer = null;

            if (message.SenderConnection != null)
            {
                senderRemotePeer = message.SenderConnection.Tag as RemotePeer;
            }

            try
            {
                switch (message.MessageType)
                {
                case NetIncomingMessageType.DiscoveryRequest:                         // (Clients trying to find LAN games)
                {
                    var response = NetPeer.CreateMessage();
                    DiscoveredGame.WriteDiscoveryResponse(owner.appConfig, response, owner.GameInfo, IsFull,
                                                          owner.NetworkApplication.GetDiscoveryData());
                    NetPeer.SendDiscoveryResponse(response, message.SenderEndPoint);
                }
                break;


                case NetIncomingMessageType.StatusChanged:
                    var status = (NetConnectionStatus)message.ReadByte();
                    switch (status)
                    {
                    case NetConnectionStatus.Connected:
                        HandleConnection(message.SenderConnection);
                        break;

                    case NetConnectionStatus.Disconnected:
                        HandleDisconnection(message.SenderConnection, message);
                        break;
                    }

                    break;

                case NetIncomingMessageType.UnconnectedData:
                    HandleUnconnectedMessage(message);
                    break;

                case NetIncomingMessageType.Data:
                    HandleNetworkManagementFromClient(message);
                    break;
                }
            }
            catch (NetworkDataException exception)
            {
                NetworkDataError(senderRemotePeer, exception);
            }
        }
예제 #4
0
        public static DiscoveredGame FakeGame()
        {
            const string chars  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            var          random = new Random();
            var          name   = new string(Enumerable.Repeat(chars, 14).Select(s => s[random.Next(s.Length)]).ToArray());
            var          game   = new DiscoveredGame();

            game.GameInfo = new GameInfo(name, false, false);
            game.EndPoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), 65535);
            game.IsFull   = true;
            return(game);
        }
예제 #5
0
        public static DiscoveredGame ReadFromDiscoveryResponse(NetworkAppConfig appConfig, NetIncomingMessage message)
        {
            try
            {
                // START: Version safe data
                // {

                var theirAppId = message.ReadString();
                if (theirAppId != appConfig.AppId)
                {
                    return(null);                    // Wrong application
                }
                var gameName = message.ReadString().FilterName();

                var theirAppVersion         = message.ReadUInt16();
                var theirAppSignatureLength = (int)message.ReadVariableUInt32();

                byte[] theirAppSignature;
                if (theirAppSignatureLength < 0 ||
                    theirAppSignatureLength > NetworkAppConfig.ApplicationSignatureMaximumLength)
                {
                    theirAppSignature = null;
                }
                else
                {
                    theirAppSignature = message.ReadBytes(theirAppSignatureLength);
                }

                // }
                // END: Version safe data


                // Check for version mismatch
                if (theirAppVersion != appConfig.ApplicationVersion || theirAppSignature == null ||
                    !appConfig.ApplicationSignature.SequenceEqual(theirAppSignature))
                {
                    var gi = new GameInfo(gameName);
                    var dg = new DiscoveredGame(message);
                    dg.GameInfo = gi;

                    if (theirAppVersion < appConfig.ApplicationVersion)
                    {
                        dg.VersionMismatch = -1;
                    }
                    else if (theirAppVersion > appConfig.ApplicationVersion)
                    {
                        dg.VersionMismatch = 1;
                    }
                    else
                    {
                        dg.VersionMismatch = 0;
                    }

                    Debug.Assert(dg.VersionMismatch.HasValue);

                    return(dg);
                }

                // If we get here, all the versioning is correct:
                {
                    var isInternetGame = message.ReadBoolean();
                    var gi             = new GameInfo(gameName, isInternetGame,
                                                      false); // <- NOTE: we are assuming that the side-channel handles discovery

                    var dg = new DiscoveredGame(message);
                    dg.GameInfo        = gi;
                    dg.IsFull          = message.ReadBoolean();
                    dg.applicationData = message.ReadByteArray();
                    return(dg);
                }
            }
            catch
            {
                return(null);
            }
        }