예제 #1
0
        GetRoomListAsync(
            byte startIndex, byte count, RoomDataSortKind sortKind,
            RoomSearchTargetFlag searchTargetFlags = RoomSearchTargetFlag.All,
            string searchName = "", ushort searchTag = PlayerFullName.NotAssignedTag)
        {
            if (!Validator.ValidateSearchName(searchName))
            {
                throw new ArgumentException(
                          $"null string or string whose length is more than {ClientConstants.PlayerNameLength} is not available.",
                          nameof(searchName));
            }

            await semaphore.WaitAsync().ConfigureAwait(false);

            try
            {
                var searchFullName = new PlayerFullName()
                {
                    Name = searchName, Tag = searchTag
                };

                if (searchName.Length > ClientConstants.PlayerNameLength)
                {
                    throw new ArgumentNullException(
                              $"The length of {nameof(searchName)} must be less than {ClientConstants.PlayerNameLength}.");
                }

                if (!Connected)
                {
                    throw new ClientErrorException(ClientErrorCode.NotConnected);
                }

                var requestBody = new ListRoomRequestMessage
                {
                    StartIndex        = startIndex,
                    Count             = count,
                    SortKind          = sortKind,
                    SearchTargetFlags = searchTargetFlags,
                    SearchFullName    = searchFullName
                };
                await SendRequestAsync(requestBody).ConfigureAwait(false);

                Logger.Log(LogLevel.Info,
                           $"Send ListRoomRequest. ({nameof(requestBody.StartIndex)}: {requestBody.StartIndex}, {nameof(requestBody.Count)}: {requestBody.Count}, {nameof(requestBody.SortKind)}: {requestBody.SortKind}, {nameof(requestBody.SearchTargetFlags)}: {requestBody.SearchTargetFlags}, {nameof(requestBody.SearchFullName)}: {requestBody.SearchFullName})");

                var replyBody = await ReceiveReplyAsync <ListRoomReplyMessage>().ConfigureAwait(false);

                Logger.Log(LogLevel.Info,
                           $"Receive ListRoomReply. ({nameof(replyBody.TotalRoomCount)}: {replyBody.TotalRoomCount}, {nameof(replyBody.MatchedRoomCount)}: {replyBody.MatchedRoomCount}, {nameof(replyBody.ReplyRoomCount)}: {replyBody.ReplyRoomCount})");
                var result = new ListRoomResultItem[replyBody.ReplyRoomCount];

                // Set results of reply to result list
                var currentIndex = requestBody.StartIndex;

                void SetResult(in ListRoomReplyMessage reply)
                {
                    for (var i = 0; i < RoomConstants.ListRoomReplyRoomInfoCount; ++i)
                    {
                        if (currentIndex >= replyBody.ReplyRoomCount)
                        {
                            return;
                        }

                        result[currentIndex++] = new ListRoomResultItem(reply.RoomInfoList[i]);
                    }
                }

                SetResult(replyBody);

                var separateCount = (replyBody.ReplyRoomCount - 1) / RoomConstants.ListRoomReplyRoomInfoCount + 1;

                for (var i = 1; i < separateCount; ++i)
                {
                    replyBody = await ReceiveReplyAsync <ListRoomReplyMessage>().ConfigureAwait(false);

                    Logger.Log(LogLevel.Info, $"Receive additional ListRoomReply ({i + 1}/{separateCount}).");
                    SetResult(replyBody);
                }

                return(replyBody.TotalRoomCount, replyBody.MatchedRoomCount, result);
            }
            finally
            {
                semaphore.Release();
            }
        }
 public ConnectResult(PlayerFullName playerFullName)
 {
     this.playerFullName = playerFullName;
 }
예제 #3
0
        /// <summary>
        /// Connect to matching server.
        /// </summary>
        /// <param name="serverAddress"></param>
        /// <param name="serverPort"></param>
        /// <param name="playerName"></param>
        /// <exception cref="ClientErrorException"></exception>
        /// <exception cref="ArgumentException"></exception>
        /// <returns></returns>
        public async Task <PlayerFullName> ConnectAsync(string serverAddress, ushort serverPort, string playerName)
        {
            if (!Validator.ValidateServerAddress(serverAddress))
            {
                throw new ArgumentException("IPv4, IPv6 or URL is available.", nameof(serverAddress));
            }

            if (!Validator.ValidateServerPort(serverPort))
            {
                throw new ArgumentException("0 is not available.", nameof(serverAddress));
            }

            if (!Validator.ValidatePlayerName(playerName))
            {
                throw new ArgumentException(
                          $"null string or string whose length is more than {ClientConstants.PlayerNameLength} is not available.",
                          nameof(serverAddress));
            }

            await semaphore.WaitAsync().ConfigureAwait(false);

            try
            {
                if (Connected)
                {
                    throw new ClientErrorException(ClientErrorCode.AlreadyConnected);
                }

                // Establish TCP connection
                try
                {
                    tcpClient = CreateTcpClient();
                    await tcpClient.ConnectAsync(serverAddress, serverPort).ConfigureAwait(false);

                    Logger.Log(LogLevel.Info, $"Connect to {serverAddress}:{serverPort} successfully.");
                }
                catch (SocketException e)
                {
                    throw new ClientErrorException(ClientErrorCode.FailedToConnect, e.Message);
                }
                catch (ObjectDisposedException e)
                {
                    throw new ClientErrorException(ClientErrorCode.FailedToConnect, e.Message);
                }

                keepAliveSenderNotificator.UpdateLastRequestTime();

                // Authentication Request
                var requestBody =
                    new AuthenticationRequestMessage {
                    Version = ClientConstants.ApiVersion, PlayerName = playerName
                };
                await SendRequestAsync(requestBody).ConfigureAwait(false);

                Logger.Log(LogLevel.Info,
                           $"Send AuthenticationRequest. ({nameof(ClientConstants.ApiVersion)}: {ClientConstants.ApiVersion}, {nameof(playerName)}: {playerName})");
                var replyBody = await ReceiveReplyAsync <AuthenticationReplyMessage>().ConfigureAwait(false);

                Logger.Log(LogLevel.Info,
                           $"Receive AuthenticationReply. ({nameof(replyBody.SessionKey)}: {replyBody.SessionKey}, {nameof(replyBody.Version)}: {replyBody.Version}, {nameof(replyBody.PlayerTag)}: {replyBody.PlayerTag})");
                sessionKey     = replyBody.SessionKey;
                PlayerFullName = new PlayerFullName {
                    Name = playerName, Tag = replyBody.PlayerTag
                };

                keepAliveSenderNotificator.StartKeepAliveProc();
                return(PlayerFullName);
            }
            finally
            {
                semaphore.Release();
            }
        }