# 유니티 C# 코드 가이드

매치메이킹 SDK(Unity) 사용 방법에 대해 설명합니다.

### 1) 매치메이킹 초기화

#### 초기화 메서드 호출

매치메이킹을 초기화하기 위해서 필요한 값을 채운 뒤 `StoveMatchSDK.Initialize` 메서드를 호출합니다.

    using Stove.PCSDK.NET.Matchmaking;

    bool result = StoveMatchSDK.Initialize();
    if (true == result)
    {
        // 여기에 초기화 성공 후 게임로직
    }
    else
    {
        // 여기에 초기화 실패에 대한 처리
    }

> 스토브 런처에 로그인하지 않은 상태로 `StoveMatchSDK.Initialize` 메서드를 호출하면 초기화에 실패합니다.

#### 초기화 실패 시 확인 방법

로그폴더(./log) MatchmakingSDK_날짜.log 파일에서 에러 이유를 확인할 수 있습니다.

### 2) 매치메이킹 종료

매치메이킹 사용이 끝난 뒤에 호출하여 사용 중인 리소스를 정리합니다. 매치메이킹에 등록한 델리게이트 및 입력했던 모든 정보가 삭제됩니다.

    using Stove.PCSDK.NET.Matchmaking;

    StoveMatchSDK.Uninitialize();

### 3) RunCallback

매치메이킹의 API는 게임엔진 및 게임 로직에 방해가 되지 않도록 대부분 비동기로 수행됩니다.

- API 호출 후 매치메이킹 서버에서 수신한 결과는 SDK 내부 큐에 적재됩니다.
- 게임에서 수신된 결과를 처리하고자 할 때 RunCallback 메서드를 호출합니다.
- 큐에 적재된 콜백이 순차적으로 실행됩니다.

유니티는 주기적으로 특정 메서드를 호출할 수 있는 수단을 제공합니다.

    using Stove.PCSDK.NET.Matchmaking;

    private FixedUpdate()
    {
        // 고정된 프레임마다 반복적으로 호출
        StoveMatchSDK.RunCallback();
    }

### 4) 매치메이킹 서버에 접속하기

#### 서버 접속 API

`StoveMatchSDK.Connect` 메서드로 매치메이킹 서버에 접속합니다.

    using Stove.PCSDK.NET.Matchmaking;

    // 닉네임
    string nickname = user.Nickname;
    StoveMatchSDK.Connect(nickname);

#### 서버 접속 콜백

서버 접속에 대한 콜백을 받기위해서는 사전에 델리게이트를 등록해야 합니다. `StoveMatchSDK.Connect` 메서드가 처리되면 `OnConnect` 콜백이 호출됩니다.

    using Stove.PCSDK.NET.Matchmaking;

    // 서버 접속 델리게이트를 등록
    StoveMatchSDK.EventConnect += GameObj.OnConnect;

    private void OnConnect(StovePCMatchmakingError error)
    {
        // 매치메이킹 서버 접속 성공
        // 신 이동등 다음 게임 로직 처리
        if (error.result == StovePCMatchmakingResult.NO_ERROR)
        {
            GameManager.Instance.LoadModScene();
        }
        // 매치메이킹 서버 접속 실패
        // 에러 처리
        else
        {
            StringBuilder sb = new StringBuilder();
            // 에러 코드
            sb.AppendFormat(" - fail code : {0}", error.result);
            // 구체적인 에러 내용이 있을 경우
            sb.AppendFormat(" - fail message : {0}", error.message);

            Debug.Log(sb.ToString());
        }
    }

error.result(에러 코드)는 `StovePCMatchmakingResult`에서 내용을 확인할 수 있습니다. 더 구체적인 에러 내용은 error.message 로 전달됩니다.

### 5) 매치메이킹 서버에서 접속 종료하기

#### 서버 접속 종료 API

`StoveMatchSDK.Disconnect` 메서드로 매치메이킹 서버에서 접속 종료합니다.

    using Stove.PCSDK.NET.Matchmaking;

    StoveMatchSDK.Disconnect()

#### 서버 접속 종료 콜백

서버 접속 종료에 대한 콜백을 받기위해서는 사전에 델리게이트를 등록해야 합니다. `StoveMatchSDK.Disconnect` 메서드가 정상적으로 처리되면 `OnDisconnect` 콜백이 호출됩니다.

    using Stove.PCSDK.NET.Matchmaking;

    // 서버 접속 종료 델리게이트를 등록
    StoveMatchSDK.EventDisconnect += GameObj.OnDisconnect;

    // 매치메이킹 서버 접속 종료
    private void OnDisconnect(StovePCMatchmakingError error, StovePCMatchmakingDisconnectCode code)
    {
        switch (code)
        {
            // Disconnect API를 호출하여 접속 종료한 경우
            case StovePCMatchmakingDisconnectCode.DISCONNECT_CLIENT:
                break;
            // 매치메이킹 서버에서 클라이언트 접속 종료
            case StovePCMatchmakingDisconnectCode.DISCONNECT_SERVER:
                break;
            // 핑 타임아웃으로 끊김 (네트워크 불안정)
            case StovePCMatchmakingDisconnectCode.DISCONNECT_BY_HOST:
                break;
            // 중복 로그인으로 접속 종료
            case StovePCMatchmakingDisconnectCode.DISCONNECT_CONFLICT:
                break;
        }

        // 신 이동등 다음 게임 로직 처리
    }

code(종료 코드)는 `StovePCMatchmakingDisconnectCode`에서 내용을 확인할 수 있습니다. 더 구체적인 에러 내용은 error.message로 전달됩니다.

#### 추가 정보

정기점검등으로 서버에서 접속이 종료될 수도 있기때문에 접속 종료 코드에 대한 확인이 필요합니다. 다른 런처에서 동일한 유저로 로그인한 경우 현재 연결이 접속 종료되므로 적절한 처리가 필요합니다.

### 6) 매치메이킹 로비 입장

로비 입장시 검색 조건을 주어 원하는 로비에 참여할 수 있습니다. 검색 조건은 메타 데이터(`StovePCMatchmakingMetadata`)로 설정합니다.

#### 로비 메타 데이터

    using Stove.PCSDK.NET.Matchmaking;

    // meta 데이터의 key값 정의
    public struct LOBBY_META_KEY
    {
        public const string DIFFICULTY_TYPE_KEY = "DifficultyType";
        public const string GAMEMODE_TYPE_KEY = "GameModeType";
        public const string ROOM_TYPE_KEY = "RoomType";
        public const string STAGE_TYPE_KEY = "StageType";
    }

    // 게임 난이도
    public struct Difficulty
    {
        public string value;        //meta value
        public string name;         //UI 표시될 이름
        public bool isDefault;      //기본 선택 여부(복수일 경우 처음것을 사용합니다.)
        public string resourcePath; //UI 표시될 리소스 경로
    }

    // 게임 모드
    public struct Mode
    {
        public string value;        //meta value
        public string name;         //UI 표시될 이름
        public bool isDefault;      //기본 선택 여부(복수일 경우 처음것을 사용합니다.)
        public string resourcePath; //UI 표시될 리소스 경로
        public bool isBattleMode;   //배틀 모드 여부에 따라 UI가 변경됩니다.
        public string[] roomValues; //모드에서 사용되는 방정보 meta value
    }

    //방 설정
    public struct Room
    {
        public string value;        //meta value
        public int maxUser;         //최대 인원수
        public string name;         //UI 표시될 이름
        public string resourcePath; //UI 표시될 리소스 경로
    }

    //게임 스테이지
    public struct Stage
    {
        public string value;        //meta value
        public string name;         //UI 표시될 이름
        public bool isDefault;      //기본 선택 여부(복수일 경우 처음것을 사용합니다.)
        public string resourcePath; //UI 표시될 리소스 경로
    }

    Difficulty.value = "Beginner";
    Mode.value = "Arcade";
    Room.value = "Arcade2";

    List<StovePCMatchmakingMetadata> metaList = new List<StovePCMatchmakingMetadata>()
    {
        // 첫 번째 메타 데이터 설정
        // key = "DifficultyType", value = "Beginner"
        new StovePCMatchmakingMetadata(LOBBY_META_KEY.DIFFICULTY_TYPE_KEY, Difficulty.value),
        // 두 번째 메타 데이터 설정
        // key = "GameModType", value = "Arcade"
        new StovePCMatchmakingMetadata(LOBBY_META_KEY.GAMEMODE_TYPE_KEY, Mode.value),
        // 세 번째 메타 데이터 설정
        // key = "RoomType", value = "Arcade2"
        new StovePCMatchmakingMetadata(LOBBY_META_KEY.ROOM_TYPE_KEY,  Room.value),
    };

#### 로비 입장 API

`StoveMatchSDK.JoinRandomLobby` 메서드로 매치메이킹 로비에 입장합니다. 검색 조건에 맞는 로비중 하나에 자동으로 입장합니다.

    using Stove.PCSDK.NET.Matchmaking;

    List<StovePCMatchmakingMetadata> metaList = new List<StovePCMatchmakingMetadata>()
    {
        // 첫 번째 메타 데이터 설정
        // key = "DifficultyType", value = "Beginner"
        new StovePCMatchmakingMetadata(LOBBY_META_KEY.DIFFICULTY_TYPE_KEY, Difficulty.value),
        // 두 번째 메타 데이터 설정
        // key = "GameModType", value = "Arcade"
        new StovePCMatchmakingMetadata(LOBBY_META_KEY.GAMEMODE_TYPE_KEY, Mode.value),
        // 세 번째 메타 데이터 설정
        // key = "RoomType", value = "Arcade2"
        new StovePCMatchmakingMetadata(LOBBY_META_KEY.ROOM_TYPE_KEY,  Room.value),
    }

    // 로비를 생성할 시 로비 입장가능한 최대 유저수
    int maxUser = 4;
    StoveMatchSDK.JoinRandomLobby(metaList.ToArray(), maxUser);

검색된 로비가 여러 개 일 경우 검색된 로비중 하나에 랜덤하게 입장합니다. 검색된 로비가 없을시 검색 조건으로 로비를 생성합니다. 로비 생성시 유저는 방장이 되며, `OnUserJoin` 콜백에서 StovePCMatchmakingAffiliation을 통해 유저 등급을 확인할 수 있습니다.

#### 로비 콜백

`StoveMatchSDK.JoinRandomLobby` 메서드가 실행중에 오류가 발생하면 error.result(에러 코드) `StovePCMatchmakingResult`에서 내용을 확인할 수 있습니다.

로비에 대한 여러 콜백을 받기 위해서는 사전에 델리게이트를 등록해야 합니다.

- 로비에 입장하면 `OnJoinLobby` => (`OnUserJoin` * 자신을 포함한 유저 수)가 연속적으로 호출됩니다.
- 다른 유저가 로비에 입장 시마다 `OnUserJoin` 콜백이 호출됩니다. ** `OnUserJoin` 콜백에서 StovePCMatchmakingAffiliation을 통해 유저 등급을 확인할 수 있습니다.
- 다른 유저가 로비에서 퇴장 시마다 `OnUserLeave` 콜백이 호출됩니다.
- 로비에서 퇴장하면 `OnLeaveLobby` 콜백이 호출됩니다. ** API 호출 외에 로비 킥/밴, 로비 삭제 등으로 강제 퇴장당할 시에도 호출됩니다.
- 방장이 퇴장하면 입장 순서에 방장이 이양되며, `OnUserUpdate` 콜백이 호출됩니다. ** `OnUserUpdate` 콜백에서 방장이 이양된 유저 정보를 확인할 수 있습니다.

    using Stove.PCSDK.NET.Matchmaking;

    // 로비 관련 델리게이트
    // 로비 입장 델리게이트를 등록
    StoveMatchSDK.EventJoinLobby += GameObj.OnJoinLobby;
    // 로비에 유저 입장 델리게이트를 등록
    StoveMatchSDK.EventUserJoin += GameObj.OnUserJoin;
    // 로비에 유저 정보 갱신 델리게이트를 등록
    StoveMatchSDK.EventUserUpdate += GameObj.OnUserUpdate;
    // 로비에서 유저 퇴장 델리게이트를 등록
    StoveMatchSDK.EventUserLeave += GameObj.OnUserLeave;
    // 로비 퇴장 델리게이트를 등록
    StoveMatchSDK.EventLeaveLobby += GameObj.OnLeaveLobby;

    // 매치메이킹 로비 입장
    private void OnJoinLobby(StovePCMatchmakingError error, StovePCMatchmakingJoinLobby joinLobby)
    {
        // 신 이동등 다음 게임 로직 처리
        if (error.result == StovePCMatchmakingResult.NO_ERROR)
        {

        }
        // 에러 처리
        else
        {
            StringBuilder sb = new StringBuilder();
            // 에러 코드
            sb.AppendFormat(" - fail code : {0}", error.result);
            // 구체적인 에러 내용이 있을 경우
            sb.AppendFormat(" - fail message : {0}", error.message);

            Debug.Log(sb.ToString());
        }
    }

    // 로비에 유저 입장(나 포함)
    private void OnUserJoin(StovePCMatchmakingError error, StovePCMatchmakingUserJoin userJoin)
    {
        StringBuilder sb = new StringBuilder();
        // 로비 고유 아이디
        sb.AppendFormat("lobby = {0}", userJoin.lobby);
        // 유저 아이디
        sb.AppendFormat("userID = {0}", userJoin.UID);
        // 유저 닉네임
        sb.AppendFormat("userNickname = {0}", nickname);
        // 로비에서 유저 등급 ( 0 = 일반, 4 = 방장 )
        sb.AppendFormat("affiliation = {0}", userJoin.affiliation);
        // 유저 메타 데이터, 로비에서 해당 유저의 저장공간
        foreach (var data in userJoin.userDataArray)
        {
            sb.AppendFormat("meta {0} = {1}", data.key, data.value);
        }
        Debug.Log(sb.ToString());

        // 게임 로직 처리
    }

    // 로비에 유저 정보(나 포함) 업데이트
    private void OnUserUpdate(StovePCMatchmakingError error, StovePCMatchmakingUpdateLobbyUser userUpdate)
    {
        StringBuilder sb = new StringBuilder();
        // 로비 고유 아이디
        sb.AppendFormat("lobby = {0}", userUpdate.lobby);
        // 유저 아이디
        sb.AppendFormat("userID = {0}", userUpdate.UID);
        // 유저 닉네임
        sb.AppendFormat("userNickname = {0}", userUpdate.nickname);
        // 로비에서 유저 등급 ( 0 = 일반, 4 = 방장 )
        sb.AppendFormat("affiliation = {0}", userUpdate.affiliation);
        // 유저 메타 데이터, 로비에서 해당 유저의 저장공간
        foreach (var data in userUpdate.userDataArray)
        {
            sb.AppendFormat("meta {0} = {1}", data.key, data.value);
        }
        Debug.Log(sb.ToString());

        // 게임 로직 처리
    }

    // 로비에서 다른 유저 퇴장
    private void OnUserLeave(StovePCMatchmakingError error, StovePCMatchmakingUserLeave userLeave)
    {
        StringBuilder sb = new StringBuilder();
        // 로비 고유 아이디
        sb.AppendFormat("lobby = {0}", userLeave.lobby);
        // 유저 아이디
        sb.AppendFormat("userID = {0}", userLeave.userID);
        // 유저 닉네임
        sb.AppendFormat("userNickname = {0}", userLeave.nickname);
        // 유저가 퇴장한 이유 코드 ( `StovePCMatchmakingResult` 에서 내용을 확인할 수 있습니다. )
        sb.AppendFormat("leaveCode = {0}", error.result);

        Debug.Log(sb.ToString());

        // 다른 유저 로비 퇴장 사유
        switch(error.result)
        {
            // API 호출하여 로비 퇴장
            case StovePCMatchmakingResult.NO_ERROR:
                break;
            // 방장이 킥
            case StovePCMatchmakingResult.USER_KICKED:
                break;
            // 방장이 밴
            case StovePCMatchmakingResult.USER_BANNED:
                break;
            // 방장이 로비 삭제
            case StovePCMatchmakingResult.USER_ROOM_DESTROYED:
                break;
            // 서버에서 로비 제거
            case StovePCMatchmakingResult.USER_ROOM_SHUTDOWN:
                break;
            // 운영이슈로 로비 제거
            case StovePCMatchmakingResult.ROOM_DELETED_AS_OPERATIONAL:
                break;
        }

        // 게임 로직 처리
    }

로비 아이디(lobby)는 로비 고유의 아이디입니다. 다른 로비 관련 API호출 시 사용합니다.

> 로비에서 다른 유저 입장이나 정보 갱신, 메시지를 송신 받을 수 있기 때문에 주기적으로 RunCallback 메서드를 호출해야 합니다.

### 7) 매치메이킹 로비 퇴장

#### 로비 퇴장 API

`StoveMatchSDK.LeaveLobby` 메서드로 매치메이킹 로비에서 퇴장합니다.

    using Stove.PCSDK.NET.Matchmaking;

    string lobby = this.lobby;
    StoveMatchSDK.LeaveLobby(lobby);

#### 로비 콜백

`StoveMatchSDK.LeaveLobby` 메서드가 실행중에 오류가 발생하면 error.result(에러 코드) `StovePCMatchmakingResult`에서 내용을 확인할 수 있습니다.

로비 퇴장에 대한 콜백을 받기위해서는 사전에 델리게이트를 등록해야 합니다.

- 내가 로비에서 퇴장시 `OnLeaveLobby` 콜백이 호출됩니다.
- 방장에 의한 로비 킥/밴, 로비 삭제 등으로 강제 퇴장당할 시에도 콜백 됩니다.
- 다른 유저는 `OnUserLeave` 콜백이 호출됩니다.

    using Stove.PCSDK.NET.Matchmaking;

    // 로비 퇴장 델리게이트를 등록
    StoveMatchSDK.EventLeaveLobby += GameObj.OnLeaveLobby;

    // 로비에서 퇴장
    private void OnLeaveLobby(StovePCMatchmakingError error, StovePCMatchmakingLeaveLobby leaveLobby)
    {
        StringBuilder sb = new StringBuilder();
        // 로비 고유 아이디
        sb.AppendFormat("lobby = {0}", lobby);
        // 유저가 퇴장한 이유 코드 ( `StovePCMatchmakingResult` 에서 내용을 확인할 수 있습니다. )
        sb.AppendFormat("leaveCode = {0}", error.result);

        Debug.Log(sb.ToString());

        // 로비 퇴장 사유
        switch(error.result)
        {
            // API 호출하여 로비 퇴장
            case StovePCMatchmakingResult.NO_ERROR:
                break;
            // 방장이 킥
            case StovePCMatchmakingResult.USER_KICKED:
                break;
            // 방장이 밴
            case StovePCMatchmakingResult.USER_BANNED:
                break;
            // 방장이 로비 삭제
            case StovePCMatchmakingResult.USER_ROOM_DESTROYED:
                break;
            // 서버에서 로비 제거
            case StovePCMatchmakingResult.USER_ROOM_SHUTDOWN:
                break;
            // 운영이슈로 로비 제거
            case StovePCMatchmakingResult.ROOM_DELETED_AS_OPERATIONAL:
                break;
        }

        // 게임 로직 처리
    }

강제 퇴장당한 경우 error.result 를 통해 `StovePCMatchmakingResult` 에서 내용을 확인할 수 있습니다.

### 8) 매치메이킹 로비 채팅 메시지 송수신

#### 로비 채팅 메시지 전송 API

`StoveMatchSDK.SendLobbyMsg` 메서드로 매치메이킹 로비 내의 모든 유저에게 채팅 메시지를 송신합니다.

    using Stove.PCSDK.NET.Matchmaking;

    string lobby = this.lobby;
    string message = "채팅 메시지";
    string myProfile = "http://onstove.myprofile";
    StoveMatchSDK.SendLobbyMsg(lobby, message, myProfile);

채팅 메시지(message)는 금칙어가 적용됩니다. 금칙어로 필터링된 메시지는 "****" 형태로 전송됩니다.
마지막 파라미터(myProfile)는 금칙어 적용없이 데이터 그대로 전송하며, json string / 내 프로필 uri등을 전송시 활용할 수 있습니다.

#### 로비 채팅 메시지 송수신 콜백

`StoveMatchSDK.SendLobbyMsg` 메서드가 실행중에 오류가 발생하면 error.result(에러 코드) `StovePCMatchmakingResult`에서 내용을 확인할 수 있습니다.

로비 채팅에 대한 콜백을 받기위해서는 사전에 델리게이트를 등록해야 합니다.

- 내가 로비에 채팅 메시지 전송시 `OnSendLobbyMessage` 콜백이 호출됩니다.
- 로비에서 다른 유저의 채팅 메시지 수신시 `OnRecvLobbyMessage` 콜백이 호출됩니다.

    using Stove.PCSDK.NET.Matchmaking;

    // 로비 채팅 송신 델리게이트를 등록
    StoveMatchSDK.EventSendLobbyMessage += GameObj.OnSendLobbyMessage;
    // 로비 채팅 수신 델리게이트를 등록
    StoveMatchSDK.EventRecvLobbyMessage += GameObj.OnRecvLobbyMessage;

    // 로비에서 채팅 전송
    private void OnSendLobbyMessage(StovePCMatchmakingError error, StovePCMatchmakingSendLobbyMessage sendLobbyMessage)
    {
        // 게임 로직 처리
        if (error.result == StovePCMatchmakingResult.NO_ERROR)
        {

        }
        // 에러 처리
        else
        {
            StringBuilder sb = new StringBuilder();
            // 에러 코드
            sb.AppendFormat(" - fail code : {0}", error.result);
            // 구체적인 에러 내용이 있을 경우
            sb.AppendFormat(" - fail message : {0}", error.message);

            Debug.Log(sb.ToString());
        }
    }

    // 로비에서 채팅 수신
    private void OnRecvLobbyMessage(StovePCMatchmakingError error, StovePCMatchmakingRecvLobbyMessage recvLobbyMessage)
    {
        // 게임 로직 처리
        if (error.result == StovePCMatchmakingResult.NO_ERROR)
        {

        }
        // 에러 처리
        else
        {
            StringBuilder sb = new StringBuilder();
            // 에러 코드
            sb.AppendFormat(" - fail code : {0}", error.result);
            // 구체적인 에러 내용이 있을 경우
            sb.AppendFormat(" - fail message : {0}", error.message);

            Debug.Log(sb.ToString());
        }
    }

> 로비에서 다른 유저 메시지를 수신할 수 있기때문에 주기적으로 RunCallback 메서드를 호출해야 합니다.

### 9) 매치메이킹 로비 데이터 송수신

#### 로비 데이터 전송 API

`StoveMatchSDK.SendLobbyBinarydata` 메서드로 매치메이킹 로비 내의 모든 유저에게 데이터를 송신합니다.

    using Stove.PCSDK.NET.Matchmaking;

    string lobby = this.lobby;
    byte[] data = new byte[5]{ (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', };
    string myProfile = "http://onstove.myprofile";
    StoveMatchSDK.SendLobbyBinarydata(lobby, data, myProfile);

데이터는 금칙어가 적용되지 않습니다. 마지막 파라미터(myProfile)는 데이터 그대로 전송하며, json string / 내 프로필 uri등을 전송시 활용할 수 있습니다.

#### 로비 데이터 송수신 콜백

`StoveMatchSDK.SendLobbyBinarydata` 메서드가 실행중에 오류가 발생하면 error.result(에러 코드) `StovePCMatchmakingResult`에서 내용을 확인할 수 있습니다.

로비 데이터에 대한 콜백을 받기위해서는 사전에 델리게이트를 등록해야 합니다.

- 내가 로비에 데이터 전송시 `OnSendLobbyBinarydata` 콜백이 호출됩니다.
- 로비에서 다른 유저의 데이터 수신시 `OnRecvLobbyBinarydata` 콜백이 호출됩니다.

    using Stove.PCSDK.NET.Matchmaking;

    // 로비 데이터 전송 델리게이트를 등록
    StoveMatchSDK.EventSendLobbyBinarydata += GameObj.OnSendLobbyBinarydata;
    // 로비 데이터 수신 델리게이트를 등록
    StoveMatchSDK.EventRecvLobbyBinarydata += GameObj.OnRecvLobbyBinarydata;

    // 로비에서 데이터 전송
    private void OnSendLobbyBinarydata(StovePCMatchmakingError error, StovePCMatchmakingSendLobbyBinarydata sendLobbyBinarydata)
    {
        // 게임 로직 처리
        if (error.result == StovePCMatchmakingResult.NO_ERROR)
        {

        }
        // 에러 처리
        else
        {
            StringBuilder sb = new StringBuilder();
            // 에러 코드
            sb.AppendFormat(" - fail code : {0}", error.result);
            // 구체적인 에러 내용이 있을 경우
            sb.AppendFormat(" - fail message : {0}", error.message);

            Debug.Log(sb.ToString());
        }
    }

    // 로비에서 데이터 수신
    private void OnRecvLobbyMessage(StovePCMatchmakingError error, StovePCMatchmakingRecvLobbyBinarydata recvLobbyBinarydata)
    {
        // 게임 로직 처리
        if (error.result == StovePCMatchmakingResult.NO_ERROR)
        {

        }
        // 에러 처리
        else
        {
            StringBuilder sb = new StringBuilder();
            // 에러 코드
            sb.AppendFormat(" - fail code : {0}", error.result);
            // 구체적인 에러 내용이 있을 경우
            sb.AppendFormat(" - fail message : {0}", error.message);

            Debug.Log(sb.ToString());
        }
    }

> 로비에서 다른 유저 데이터를 수신할 수 있기때문에 주기적으로 RunCallback 메서드를 호출해야 합니다.

### 10) 매치메이킹 로비 게임 시작

#### 로비 게임 시작 API

`StoveMatchSDK.StartGame` 메서드로 로비가 게임을 시작함을 매치메이킹 서버와 모든 유저에게 알립니다.

    using Stove.PCSDK.NET.Matchmaking;

    string lobby = this.lobby;
    StoveMatchSDK.StartGame(lobby, "", 0);

방장만 호출할 수 있습니다. 방장이 아닌 유저가 호출할 시 에러가 콜백됩니다. 서버 아이피와 포트는 클라이언트에서 연동할 게임서버 주소를 입력합니다. 연동할 게임 서버가 없을 시 빈값을 입력합니다. 게임이 시작된 후에는 해당 로비에 입장할 수 없습니다.

#### 로비 게임 시작 콜백

`StoveMatchSDK.StartGame` 메서드가 실행중에 오류가 발생하면 error.result(에러 코드) `StovePCMatchmakingResult`에서 내용을 확인할 수 있습니다.

로비 게임 시작에 대한 콜백을 받기위해서는 사전에 델리게이트를 등록해야 합니다. 로비 내 모든 유저에게 `StartGame` 콜백이 호출됩니다.

    using Stove.PCSDK.NET.Matchmaking;

    // 로비 게임시작 델리게이트를 등록
    StoveMatchSDK.EventStartGame += GameObj.OnStartGame;

    // 로비 게임 시작
    private void OnStartGame(StovePCMatchmakingError error, StovePCMatchmakingStartGame startGame)
    {
        // 신 이동등 게임 로직 처리
        if (error.result == StovePCMatchmakingResult.NO_ERROR)
        {

        }
        // 에러 처리
        else
        {
            StringBuilder sb = new StringBuilder();
            // 에러 코드
            sb.AppendFormat(" - fail code : {0}", error.result);
            // 구체적인 에러 내용이 있을 경우
            sb.AppendFormat(" - fail message : {0}", error.message);

            Debug.Log(sb.ToString());
        }
    }

    > 로비에서 게임 시작 통보를 수신할 수 있기때문에 주기적으로 RunCallback 메서드를 호출해야 합니다.

    ### 11) 매치메이킹 로비 게임 종료
    #### 로비 게임 종표 API
    `StoveMatchSDK.EndGame` 메서드로 로비가 게임을 종료함을 매치메이킹 서버와 모든 유저에게 알립니다.

    ``` cs
    using Stove.PCSDK.NET.Matchmaking;

    string lobby = this.lobby;
    StoveMatchSDK.EndGame(lobby, "", 0);

방장만 호출할 수 있습니다. 방장이 아닌 유저가 호출할 시 에러가 콜백됩니다. 서버 아이피와 포트는 클라이언트에서 연동할 게임서버 주소를 입력합니다. 연동할 게임 서버가 없을 시 빈값을 입력합니다. 게임이 종료된 후에 로비는 자동으로 삭제됩니다.

#### 로비 게임 종료 콜백

`StoveMatchSDK.EndGame` 메서드가 실행중에 오류가 발생하면 error.result(에러 코드) `StovePCMatchmakingResult`에서 내용을 확인할 수 있습니다.

로비 게임 종료에 대한 콜백을 받기위해서는 사전에 델리게이트를 등록해야 합니다.

- 로비 내 모든 유저에게 `EndGame` 콜백이 호출됩니다.
- 로비 내 모든 유저는 `OnLeaveLobby` 콜백이 호출됩니다.

    using Stove.PCSDK.NET.Matchmaking;

    // 로비 게임 시작 델리게이트를 등록
    StoveMatchSDK.EventEndGame += GameObj.OnEndGame;

    // 로비 게임 종료
    private void OnEndGame(StovePCMatchmakingError error, StovePCMatchmakingEndGame endGame)
    {
        // 신 이동등 게임 로직 처리
        if (error.result == StovePCMatchmakingResult.NO_ERROR)
        {

        }
        // 에러 처리
        else
        {
            StringBuilder sb = new StringBuilder();
            // 에러 코드
            sb.AppendFormat(" - fail code : {0}", error.result);
            // 구체적인 에러 내용이 있을 경우
            sb.AppendFormat(" - fail message : {0}", error.message);

            Debug.Log(sb.ToString());
        }
    }

    > 로비에서 게임 종료 통보를 수신할 수 있기때문에 주기적으로 RunCallback 메서드를 호출해야 합니다.