Ejemplo n.º 1
0
        /// <summary>
        /// Sends a request to room, to retrieve an access to it for a specified peer,
        /// with some extra properties
        /// </summary>
        public void GetAccess(IPeer peer, Dictionary <string, string> properties, GetAccessCallback callback)
        {
            // If request is already pending
            if (_requestsInProgress.Contains(peer.Id))
            {
                callback.Invoke(null, "You've already requested an access to this room");
                return;
            }

            // If player is already in the game
            if (_players.ContainsKey(peer.Id))
            {
                callback.Invoke(null, "You are already in this room");
                return;
            }

            // If player has already received an access and didn't claim it
            // but is requesting again - send him the old one
            var currentAccess = _unconfirmedAccesses.Values.FirstOrDefault(v => v.Peer == peer);

            if (currentAccess != null)
            {
                // Restore the timeout
                currentAccess.Timeout = DateTime.Now.AddSeconds(Options.AccessTimeoutPeriod);

                callback.Invoke(currentAccess.Access, null);
                return;
            }

            // If there's a player limit
            if (Options.MaxPlayers != 0)
            {
                var playerSlotsTaken = _requestsInProgress.Count
                                       + _accessesInUse.Count
                                       + _unconfirmedAccesses.Count;

                if (playerSlotsTaken >= Options.MaxPlayers)
                {
                    callback.Invoke(null, "Room is already full");
                    return;
                }
            }

            var packet = new RoomAccessProvideCheckPacket()
            {
                PeerId = peer.Id,
                RoomId = RoomId
            };

            // Add the username if available
            var userExt = peer.GetExtension <IUserExtension>();

            if (userExt != null && !string.IsNullOrEmpty(userExt.Username))
            {
                packet.Username = userExt.Username;
            }

            // Add to pending list
            _requestsInProgress.Add(peer.Id);

            Peer.SendMessage((short)MsfOpCodes.ProvideRoomAccessCheck, packet, (status, response) =>
            {
                // Remove from pending list
                _requestsInProgress.Remove(peer.Id);

                if (status != ResponseStatus.Success)
                {
                    callback.Invoke(null, response.AsString("Unknown Error"));
                    return;
                }

                var accessData = response.Deserialize(new RoomAccessPacket());

                var access = new RoomAccessData()
                {
                    Access  = accessData,
                    Peer    = peer,
                    Timeout = DateTime.Now.AddSeconds(Options.AccessTimeoutPeriod)
                };

                // Save the access
                _unconfirmedAccesses[access.Access.Token] = access;

                callback.Invoke(access.Access, null);
            });
        }