public static void CancelMatchmaking(Session session)
        {
            // 메시지 핸들러 함수는 세션 ID 를 이벤트 태그로 하는 이벤트 위에서 실행합니다.
            // 아래는 이 함수를 메시지 핸들러 위에서 실행하게 강제하게 검사하는 식입니다.
            // 세션 ID 별로 이 함수를 직렬화하지 않으면 동시에 서로 다른 곳에서
            // 이 세션에 접근할 수 있습니다.
            Log.Assert(Event.GetCurrentEventTag() == session.Id);

            JObject context = session.Context;

            if (context[kMatchHistory] == null || context[kMatchHistory].Type != JTokenType.Object)
            {
                // 매칭을 요청한 적이 없습니다. 종료합니다.
                return;
            }

            Log.Assert(context[kMatchHistory][kAccountId] != null && context[kMatchHistory][kAccountId].Type == JTokenType.String);
            Log.Assert(context[kMatchHistory][kMatchType] != null && context[kMatchHistory][kMatchType].Type == JTokenType.Integer);

            string account_id = context[kMatchHistory][kAccountId].Value <string>();
            long   match_type = context[kMatchHistory][kMatchType].Value <long>();

            funapi.Matchmaking.Client.CancelCallback cancel_callback =
                new funapi.Matchmaking.Client.CancelCallback(
                    (string account_id2, funapi.Matchmaking.CancelResult result) => {
                // 아무것도 하지 않습니다.
            });

            Log.Info("Canceling matchmaking(with session context): session_id={0}, account_id={1}, match_type={2}",
                     session.Id, account_id, match_type);

            funapi.Matchmaking.Client.Cancel(match_type, account_id, cancel_callback);
        }
コード例 #2
0
        // 세션을 정리합니다.
        public static void FreeUser(Session session)
        {
            // 유저를 정리하기 위한 Context 를 읽어옵니다.
            string matching_state;
            string id;

            session.GetFromContext("matching", out matching_state);
            session.GetFromContext("id", out id);

            // Session Context 를 초기화 합니다.
            session.Context = new JObject();

            // 로그아웃하고 세션을 종료합니다.
            if (id != string.Empty)
            {
                AccountManager.LogoutCallback logout_cb = (string param_account_id,
                                                           Session param_session,
                                                           bool param_result) => {
                    Log.InfoIf(param_result, "Logged out(local) by session close: id={0}", param_account_id);
                };
                AccountManager.SetLoggedOutAsync(id, logout_cb);
            }

            // 매치메이킹이 진행 중이면 취소합니다.
            if (matching_state == "doing")
            {
                // Matchmaking cancel 결과를 처리할 람다 함수입니다.
                funapi.Matchmaking.Client.CancelCallback cancel_cb =
                    (string player_id, funapi.Matchmaking.CancelResult result) => {
                    if (result == funapi.Matchmaking.CancelResult.kSuccess)
                    {
                        Log.Info("Succeed to cancel matchmaking by session close: id={0}", id);
                    }
                    else
                    {
                        Log.Info("Failed to cancel matchmaking by session close: id={0}", id);
                    }
                };
                funapi.Matchmaking.Client.Cancel((long)MatchmakingType.kMatch1vs1, id, cancel_cb);
            }
        }
コード例 #3
0
        private static void CancelMatchmaking(Session session, Session.EncodingScheme encoding)
        {
            // 로그인 한 Id 를 가져옵니다.
            string id;

            if (!session.GetFromContext("id", out id))
            {
                Log.Warning("Failed to cancel matchmaking. Not logged in.");
                if (encoding == Session.EncodingScheme.kJsonEncoding)
                {
                    session.SendMessage("error", Utility.MakeResponse("fail", "not logged in"));
                }
                else
                {
                    Log.Assert(encoding == Session.EncodingScheme.kProtobufEncoding);
                    FunMessage       funmsg = new FunMessage();
                    PongErrorMessage msg    = new PongErrorMessage();
                    msg.result = "fail";
                    msg.msg    = "not logged in";
                    funmsg.AppendExtension_pong_error(msg);
                    session.SendMessage("error", funmsg);
                }
                return;
            }

            // 매치메이킹 취소 상태로 변경합니다.
            session.AddToContext("matching", "cancel");

            funapi.Matchmaking.Client.CancelCallback cancel_cb = (string player_id,
                                                                  funapi.Matchmaking.CancelResult result) => {
                if (encoding == Session.EncodingScheme.kJsonEncoding)
                {
                    JObject response = new JObject();

                    if (result == funapi.Matchmaking.CancelResult.kSuccess)
                    {
                        Log.Info("Succeed to cancel matchmaking: id={0}", player_id);
                        response = Utility.MakeResponse("Cancel");
                    }
                    else if (result == funapi.Matchmaking.CancelResult.kNoRequest)
                    {
                        response = Utility.MakeResponse("NoRequest");
                    }
                    else
                    {
                        response = Utility.MakeResponse("Error");
                    }

                    session.SendMessage("match", response, Session.Encryption.kDefault);
                }
                else
                {
                    Log.Assert(encoding == Session.EncodingScheme.kProtobufEncoding);
                    FunMessage      funmsg = new FunMessage();
                    LobbyMatchReply reply  = new LobbyMatchReply();

                    if (result == funapi.Matchmaking.CancelResult.kSuccess)
                    {
                        Log.Info("Succeed to cancel matchmaking: id={0}", player_id);
                        reply.result = "Cancel";
                    }
                    else if (result == funapi.Matchmaking.CancelResult.kNoRequest)
                    {
                        reply.result = "NoRequest";
                    }
                    else
                    {
                        reply.result = "Error";
                    }

                    funmsg.AppendExtension_lobby_match_repl(reply);
                    session.SendMessage("match", funmsg, Session.Encryption.kDefault);
                }
            };

            funapi.Matchmaking.Client.Cancel((int)MatchmakingType.kMatch1vs1, id, (_1, _2) => { cancel_cb(_1, _2); });
        }
        public static void CancelMatchmaking(
            Session session, JObject message, SessionResponse.SessionResponseHandler handler)
        {
            // 메시지 핸들러 함수는 세션 ID 를 이벤트 태그로 하는 이벤트 위에서 실행합니다.
            // 아래는 이 함수를 메시지 핸들러 위에서 실행하게 강제하게 검사하는 식입니다.
            // 세션 ID 별로 이 함수를 직렬화하지 않으면 동시에 서로 다른 곳에서
            // 이 세션에 접근할 수 있습니다.
            Log.Assert(Event.GetCurrentEventTag() == session.Id);

            // 클라이언트는 다음 메시지 형태로 매치메이킹 취소를 요청합니다.
            // {
            //   "account_id": "id",
            //   "match_type": 1
            // }

            if (message[kAccountId] == null || message[kAccountId].Type != JTokenType.String ||
                message[kMatchType] == null || message[kMatchType].Type != JTokenType.Integer)
            {
                Log.Error("Missing required fields: '{0}' / '{1}': session_id={2}, message={3}",
                          kAccountId, kMatchType, session.Id, message.ToString());
                handler(SessionResponse.ResponseResult.FAILED,
                        new SessionResponse(session, 400, "Missing required fields.", new JObject()));
                return;
            }

            // 매치 타입
            long match_type = message[kMatchType].Value <long>();

            if (!MatchmakingType.IsValidMatchType(match_type))
            {
                Log.Error("Invalid match_type: session_id={0}, message={1}", session.Id, message.ToString());
                handler(SessionResponse.ResponseResult.FAILED,
                        new SessionResponse(session, 400, "Invalid arguments.", new JObject()));
                return;
            }

            if (match_type == (long)MatchmakingType.MatchType.kNoMatching)
            {
                // 매치메이킹 기능을 쓰지 않으므로 취소 처리한다.
                handler(SessionResponse.ResponseResult.OK,
                        new SessionResponse(session, 200, "OK.", new JObject()));
            }

            // 계정
            string account_id = message[kAccountId].Value <string>();

            // 요청한 계정과 로그인 중인 세션이 일치하는 지 검사합니다.
            // 이 검사를 통해 다른 유저 ID 로 매칭을 취소하는 행위를 방지할 수 있습니다.
            if (AccountManager.FindLocalSession(account_id).Id != session.Id)
            {
                Log.Info("CancelMatchmaking denied: bad request: session_id={0}, message={1}",
                         session.Id, message.ToString());
                handler(SessionResponse.ResponseResult.FAILED,
                        new SessionResponse(session, 400, "Access denied for this account.", new JObject()));
                return;
            }

            funapi.Matchmaking.Client.CancelCallback cancel_callback =
                new funapi.Matchmaking.Client.CancelCallback(
                    (string account_id2, funapi.Matchmaking.CancelResult result2) => {
                if (result2 != funapi.Matchmaking.CancelResult.kSuccess)
                {
                    // kCRNoRequest (요청하지 않은 매치) 또는
                    // kCRError (엔진 내부 에러)가 올 수 있습니다.
                    handler(SessionResponse.ResponseResult.FAILED,
                            new SessionResponse(session, 500, "Internal server error.",
                                                new JObject()));
                }
                else
                {
                    handler(SessionResponse.ResponseResult.OK,
                            new SessionResponse(session, 200, "OK.", new JObject()));
                }
            });
            Log.Info("Canceling matchmaking: session_id={0}, account_id={1}, match_type={2}",
                     session.Id, account_id, match_type);

            funapi.Matchmaking.Client.Cancel(match_type, account_id, cancel_callback);
        }