15. API 구현 가이드 (개발자용)

15.1. 아이펀 디플로이의 동작 흐름

아이펀 디플로이의 기능 대부분은 아래와 같은 흐름으로 동작합니다.

  1. 디플로이 사용자가 특정 기능을 수행 한다. (ex: 아이템 선물하기, 로그 조회 등)
  2. 게임 서버가 구현한 해당 기능의 REST API를 호출 한다.
  • 만약 해당 기능이 예약 작업인 경우 사용자가 지정한 일시까지 대기 한다. (ex: 캠페인 시작/종료 등)
  1. 디플로이 사용자가 수행 결과를 알 수 있도록 게임 서버로부터 돌려받은 response를 출력 한다.

보시다시피 아이펀 디플로이는 게임 DB를 직접 조작하지 않고 게임 서버의 API를 호출 함으로써 게임 서버에 처리를 일임하고 있습니다.

15.2. 디플로이 연동 API란?

위와 같이 아이펀 디플로이는 게임 서버와의 REST API 통신 을 통해 기능합니다. 정리하자면, 아래의 두 가지 역할만을 담당하는 셈입니다.

  • 디플로이 사용자에게 입력을 받는 역할
  • 게임 서버에서 구현한 REST API를 호출 하는 역할

아이펀 디플로이에서는 저 REST API를 디플로이 연동 API 라고 부르고 있으며, 게임 서버에 디플로이 연동 API가 구현되어 있어야 아이펀 디플로이 이용이 가능 합니다.

이 페이지는 디플로이 연동 API에 대해 설명하고 구현을 돕는 것을 목적으로 합니다.

Danger

디플로이 연동 API에서 디플로이로 값을 반환하실 때, 응답에 포함되는 문자열은 슬래시(/)를 포함하지 않는 것이 좋습니다. 특히 account id, character id 등 게임 내 특정 대상을 지정하는 값에는 슬래시(/)를 포함해서는 안 됩니다. 예를 들어 다음과 같은 응답은 허용되지 않습니다.

{ "search_result" : [ { "id" : "test/account", "name": "sample/_name" } ]

15.3. 디플로이 연동 API HTTP 헤더

디플로이 연동 API가 호출될 때, HTTP 헤더에는 다음과 같은 값이 들어갑니다. API 응답을 보내실 때 참고해주세요.

예를 들어 GET /cs-api/v1/item/giftable API가 호출되어 선물 가능한 아이템 목록을 요청받았을 경우, Operator-Language-Code 헤더를 참고하여 아이템 이름을 브라우저의 언어에 맞게 보내줄 수 있습니다.

헤더 설명
Operator-Auth-Id 아이펀 디플로이 유저 ID (디플로이 내부에서 사용)
Operator-Auth-Provider 아이펀 디플로이 유저 인증 방식
Operator-Name 아이펀 디플로이 유저 ID
Operator-Language-Code 유저가 사용하는 브라우저의 언어 코드
  • 예시
{
  "Host": "ifun-deploy.com",
  "Connection": "keep-alive",
  "Accept-Encoding": "gzip, deflate",
  "Accept": "*/*",
  "User-Agent": "python-requests/2.12.4",
  "Content-Length": "4",
  "Content-Type": "application/json",

  "Operator-Auth-Id": "1028510000000000000000",
  "Operator-Auth-Provider": "google-openidconnect",
  "Operator-Name": "user@gmail.com",
  "Operator-Language-Code": "ko"
}

15.4. 지원 언어와 코드

디플로이 에서 현재 지원하는 언어와 코드는 아래의 표와 같습니다.

언어명 코드
English en
Australian English en-au
British English en-gb
Spanish es
French fr
Japanese ja
Korean (Korea) ko
Dutch (Netherlands) nl
Polish pl
Portuguese (Brazil) pt-br
Russian ru
Dutch (Netherlands) nl
Simplified Chinese zh-cn
Traditional Chinese zh-tw

15.5. API 컨벤션

디플로이 연동 API는 아래와 같은 컨벤션으로 디자인되어 있습니다.

  • URL의 <…> 부분은 파라미터값으로 치환됩니다

    GET /cs-api/v1/account/<id> 의 경우,실제 API 호출 시 <id> 대신 계정의 id가 들어갑니다.

  • URL은 /cs-api/v1/ 로 시작합니다

    v1 은 현재 사용 중인 디플로이 연동 API의 버전을 의미합니다. 추후 기능 추가 및 변경으로 인하여 API가 바뀌면 v2 등을 사용하게 될 수도 있습니다.

  • /cs-api/v1/ 이후의 URL은 자원의 경로를 뜻합니다

    /cs-api/v1/account/search-condition 은 account의 search-condition 자원을 가리킵니다.

  • GET 메소드는 URL 경로의 자원을 읽습니다

    GET /cs-api/v1/account/search-condition 은 search-condition을 읽어오라는 의미입니다.

  • PUT 메소드는 URL 경로의 자원을 덮어씁니다

    예를 들어 PUT /cs-api/v1/account/1/name/john 이라는 API가 호출되면 1번 유저 계정 테이블의 name 필드에 john이라는 값을 집어넣어 주어야 합니다. 이 때, 해당 API를 몇 번이고 호출해도 결과가 달라지지 않는다는 점을 주목해주세요.

  • POST 메소드는 URL 경로에 자원을 추가합니다

    기능이 PUT과 유사하지만, API 호출 횟수에 따라 결과가 달라지는 경우에 사용되며 자원에 대한 데이터는 HTTP body에 JSON 형식으로 들어가게 됩니다. 예를 들어 POST /item/gift 는 선물을 보내는 용도로 사용됩니다. 이 API를 한 번 호출하면 선물이 한 번 가겠지만 여러 번 호출하면 선물이 여러 번 가게 되겠지요. POST는 이처럼 API 호출 횟수가 결과에 영향을 미치는 경우에 사용되고 있습니다.

Tip

보시다시피 디플로이 연동 API는 최대한 RESTful 하도록 디자인되어 있으므로, RESTful API의 특징을 참고하시면 이해에 많은 도움이 됩니다.

Note

PUT과 같이 API의 호출 횟수가 결과에 영향을 미치지 않는 성질을 멱등성(idempotency) 이라고 하며, POST와 PUT의 차이, 멱등성에 관해서는 인터넷 검색을 통해 더 자세한 설명을 찾아보실 수 있습니다.

15.6. 디플로이 연동 API

게임 서버에서 구현해야 하는 디플로이 연동 API 리스트입니다.

게임 서버에 이 API들이 구현되어 있어야 정상적인 아이펀 디플로이 사용이 가능하며, 당사에서 제공하는 라이브러리를 이용하시면 더욱 간편하고 빠르게 API를 연동하실 수 있습니다. (이용을 원하실 경우 손쉬운 API 구현을 위해 제공되는 library 항목을 참조해주세요.)

Note

참고로 아래 설명 중 성공인 경우 응답HTTP 상태값 으로 지정된 것을 제외한 모든 응답은 아이펀 디플로이에 의해서 오류로 인식됩니다. 따라서 만일 API 가 구현되어있지 않거나, 오류가 발생하는 등의 상황은 일반적인 HTTP 응답인 404 Not Found500 Internal Error 와 같이 표준적인 응답을 반환하시면 됩니다.

아이펀 디플로이는 API 호출 시 응답이 없거나 기대하지 않은 응답 코드가 왔을 경우, 해당 API를 미구현된 것으로 간주하고 관련 기능을 비활성화시킵니다.

15.6.1. Meta API

GET /cs-api/v1

  • 게임 서버에서 해야 하는 동작

    게임 서버에서 구현한 디플로이 연동 API 리스트를 JSON 형태로 반환합니다.

    아이펀 디플로이는 이를 통해서 게임 서버가 구현한 API 를 파악하고 호출하게 됩니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

      • 계정 관련 API , 캐릭터 관련 API , 아이템 지급 관련 API , 게임 내 캠페인 (이벤트) 관련 API 인벤토리 조회 / 아이템 회수 관련 API 에 기술된 API 들 중에서 실제로 게임 서버가 구현하고 있는 API 들만 각각 [ "<METHOD>", "URL" ] 형태의 배열로 해서 전체 리스트로 만들어서 반환합니다.

      • 즉 다음과 같은 형태가 됩니다.

        [
          ["GET", "/account/search-condition"],
          ["GET", "/account/search"],
          ["GET", "/account/<id>"],
          ["PUT", "/account/<id>/<field>/<value>"],
          ["GET", "/account/<id>/connection"],
          ["POST", "/account/<id>/logout"],
          ["GET", "/account/<id>/ban"],
          ["POST", "/account/<id>/ban"],
          ["POST", "/account/<id>/ban/reinstate"],
          ["GET", "/account/<id>/character"],
          ["GET", "/character/<id>"],
          ["PUT", "/character/<id>/<field>/<value>"],
          ["GET", "/character/<id>/inventory"],
          ["GET", "/inventory/<type>/<id>"],
          ["POST", "/inventory/<type>/<id>/item/<item_id>"],
          ["POST", "/inventory/items"],
          ["GET", "/item/giftable"],
          ["POST", "/item/gift"],
          ["GET", "/campaign/type"],
          ["POST", "/campaign/<type>/<id>/begin"],
          ["POST", "/campaign/<type>/<id>/end"],
          ["POST", "/campaign/<type>/<id>/cancel"],
          ["GET", "/editable/account"],
          ["GET", "/editable/character"],
          ["PUT", "/payment/refund/<receipt_id>"],
          ["POST", "/accounts/ban"],
          ["POST", "/accounts/ban/reinstate"],
          ["GET", "/notice/realtime/category"],
          ["POST", "/notice/realtime"],
          ["GET", "/mission/category"],
          ["GET", "/character/<character_id>/mission/status/periodic"],
          ["GET", "/character/<character_id>/mission/record/normal"],
          ["GET", "/character/<character_id>/mission/status/achievement"]
        ]
        
      • 이 때 API URL 중 파라미터를 받는 형태는 <...> 형태로 넣게 됩니다.

        예를 들자면 /cs-api/v1/account/<id> API에서 <id> 는 해당 계정의 ID를 받아오기 위한 파라미터를 의미합니다.

15.6.2. 계정 관련 API

GET /cs-api/v1/account/search-condition

  • 게임 서버에서 해야 하는 동작

    서버에서 지원하는 게임 유저 검색 조건을 JSON 으로 반환합니다.

    이 때 검색 조건을 의미하는 문자열은 사용자가 구분할 수 있는 임의의 문자열로 지정하시면 됩니다. (게임 유저 검색 시에 이 문자열이 condition 이라는 URL 파라미터로 게임 서버에 전달됩니다)

    아이펀 디플로이는 이 문자열이 실제 의미하는 것이 뭔지는 신경 쓰지 않고, 게임 서버가 각 문자열에 해당하는 검색 조건을 지원한다고 이해하게 됩니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

      {
        "search_conditions": ["condition1", "condition2", "condition3"]
      }
      

      게임 서버에서 지원하는 검색 조건을 지칭하는 문자열들을 배열로 넣습니다. 이 때, condition1, condition2, condition3 를 게임 서버에서 지정한 문자열로 반환하시면 됩니다.

    • 예시: 만일 서버 내부에서 account_id, email, character_name, level 의 4가지 검색 조건을 제공한다면,

      HTTP/1.1 200 OK
      
      {
        "search_conditions": ["account_id", "email", "character_name", "level"]
      }
      

GET /cs-api/v1/account/<id>

  • 게임 서버에서 해야 하는 동작

    <id> 파라미터의 값을 ID로 가진 계정의 데이터를 JSON 형태로 반환합니다.

    아이펀 디플로이는 반환되는 JSON 의 key 나 value 는 신경 쓰지 않고, JSON 결과를 테이블 형태로 보여줍니다. 따라서 게임 서버에서는 계정에 대해서 외부에 노출하고 싶은 어떤 정보든 자유롭게 노출할 수 있습니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: GET /cs-api/v1/account/K1234 에 해당하는 아이디가 있을 때

      HTTP/1.1 200 OK
      
      {
        "account": {
          "created": "2016-01-01",
          "last_login": "2016-03-23",
          "banned": false,
          "coin": 100,
          "clover": 200
        }
      }
      

      account 라는 멤버 아래 계정 정보를 JSON object 로 넣습니다.

    Note

    여기에 반환되는 데이터는 고객 지원 등 제한적인 이유로 사용되기 때문에, 반환되는 데이터가 DB 구조를 그대로 반영할 필요는 없습니다. 따라서 보여주어야될 필드들 리스트나 필드 이름이나, 데이터가 nested 되는 구조 등을 임의로 지정하실 수 있습니다.

    Important

    사용자 정보가 nested 된 상태도 상관은 없습니다. 다만 account 에 맵핑된 오브젝트의 최상위 레벨에 있는 key 가 아닌 경우 읽기는 가능하지만 쓰기는 제한됩니다. 따라서 쓰기가 가능해야 하는 필드는 최상위 레벨에 지정해주셔야 합니다. 앞서 설명해 드린 것처럼 여기 반환되는 내용이 DB 구조를 그대로 반영할 필요가 없으므로 최상위 레벨의 필드가 아닌 것을 최상위로 옮기시더라도 문제는 없습니다.

PUT /cs-api/v1/account/<id>/<field>/<value>

  • 게임 서버에서 해야 하는 동작

    사용자 계정 정보 중에서 <field> 에 해당하는 필드를 <value> 로 덮어씁니다.

    이렇게 덮어쓸 수 있는 필드들을 별도로 확인하는 이유는 자칫 아이펀 디플로이로 민감한 유저 정보까지 덮어쓰는 것을 막기 위함입니다. JSON 안에 포함되는 필드 이름은 앞의 GET /cs-api/v1/account/<id> 에서 반환되는 필드 중 account 바로 아래 최상위 레벨의 필드들이어야 합니다. 아이펀 디플로이는 이 API 에서 덮어쓰는 것이 가능하다고 된 필드들에 대해서 GET /cs-api/v1/account/<id> 를 통해 계정 정보를 보여줄 때 업데이트할 수 있게 표시해줍니다.

    Important

    게임 서버에서 복잡한 schema 를 아이펀 디플로이에 넘겨야 하는 상황 이 간단하게 데이터를 조작하기 위해서, 아이펀 디플로이는 변경 가능한 계정 정보를 GET /cs-api/v1/account/<id> 에 반환되는 결과 중 최상위 레벨의 필드로 제한합니다. 따라서 변경하려는 <field> 가 계정 정보에서 최상위 필드들인지 확인해주세요.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: coin 을 10 으로 갱신하는 경우 (PUT /cs-api/v1/account/K1234/coin/10)

      HTTP/1.1 200 OK
      

      별도의 body 는 없이 상태값만 반환하면 됩니다.

GET /cs-api/v1/account/<id>/connection

  • 게임 서버에서 해야 하는 동작

    사용자 계정이 로그인 상태인지를 true/false 로 반환합니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: K1234 라는 아이디의 접속 정보 확인 (GET /cs-api/v1/account/K1234/connection)

      HTTP/1.1 200 OK
      
      {
        "logged_in": true
      }
      

      logged_in 라는 멤버 아래 로그인 상태를 true/false 로 반환합니다. true 는 로그인 상태, false 는 로그아웃 상태입니다.

POST /cs-api/v1/account/<id>/logout

  • 게임 서버에서 해야 하는 동작

    사용자 계정을 강제로 로그아웃 시킵니다.

    이 기능은 사용자 정보를 갱신한다거나 할 때, 로그인 된 상태에서 사용자 정보를 바꾸게 되면 문제가 될 수 있기 때문에 이용됩니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: K1234 라는 아이디의 강제 로그아웃 (POST /cs-api/v1/account/K1234/logout)

      HTTP/1.1 200 OK
      

      별도의 body 는 없이 상태값만 반환하면 됩니다.

GET /cs-api/v1/account/<id>/ban

  • 게임 서버에서 해야 하는 동작

    사용자 계정이 정지 상태인지를 true/false 로 반환합니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

      {
        "is_banned": true
      }
      
      • is_banned 라는 멤버 아래 로그인 상태를 true/false 로 반환합니다. true 는 계정 정지 상태, false 는 정상 상태입니다.
  • 예시: K1234 라는 아이디가 계정 정지 상태인지 확인 (GET /cs-api/v1/account/K1234/ban)

    HTTP/1.1 200 OK
    
    {
      "is_banned": true
    }
    

    Note

    게임은 계정 정지 여부를 true/false 로만 반환하게 되지만, 아이펀 디플로이는 과거 계정 정지 기록을 별도 DB 에 저장하고 이를 확인해서 아이펀 디플로이 대시보드 상에 해당 계정의 계정 정지 기간 및 정지 사유를 같이 표시하게 됩니다.

POST /cs-api/v1/account/<id>/ban

  • 게임 서버에서 해야 하는 동작

    사용자 계정을 강제로 로그아웃 시키고, 계정을 정지 상태로 바꿉니다.

    Tip

    계정을 정지 상태로 바꾸기 위해서 게임 서버는 유저 데이터에 계정 정지 상태인지에 대한 필드를 추가해서 관리해야 될 수도 있습니다.

    Tip

    아이펀 디플로이 대시보드에서는 계정을 정지시킬 때, 정지 기간과 사유도 입력을 받습니다. 그러나 게임 서버에서 이 정지 기간과 사유의 히스토리를 관리하는 것이 번거로우므로, 이 정보는 아이펀 디플로이 자체에 남고, 아이펀 디플로이는 계정 정지 기간이 시작될 때와 끝날 때 자동으로 POST /cs-api/v1/account/<id>/banPOST /cs-api/v1/account/<id>/ban/reinstate 를 게임 서버에 호출하게 됩니다. 이로써 게임 서버는 정지 기간이나 사유에 대한 기록을 별도 관리 하지 않아도 됩니다. 계정 정지 작업과 관련된 모든 내용은 운영 로그로 기록이 남게 됩니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK
    • HTTP body: 없음
  • 예시: K1234 라는 아이디를 계정 정지 (POST /cs-api/v1/account/K1234/ban)

    HTTP/1.1 200 OK
    

    Caution

    별도의 body 는 없이 상태값만 반환하면 됩니다.

  • 실패인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

      {
        "is_error": true,  // false 일 경우 성공으로 처리됩니다.
        "description": "<실패 상황에 대한 메시지>",  // optional
        "error_info": {
          "errors": [
            {
              "target": "<실패한 대상 계정 ID>"
              "detail": "<실패한 계정 ID 의 실패 메시지>"  // optional
            }
          ]
        }
      }
      
  • 예시: 존재하지 않는 K1234 라는 아이디를 계정 정지 (POST /cs-api/v1/account/K1234/ban)

    HTTP/1.1 200 OK
    
    {
      "is_error": true,
      "description": "unknown account id",
      "error_info": {
        "errors": [
          {
            "target": "K1234"
            "detail": "존재하지 않는 계정입니다."
          }
        ]
      }
    }
    

    Caution

    is_error 의 값이 false 인 경우 에러에 대한 정보가 무시되고 성공으로 처리됩니다.

    Caution

    지정된 형식과 맞지 않는 값이 반환되면 실패로 처리됩니다.

POST /cs-api/v1/account/<id>/ban/reinstate

  • 게임 서버에서 해야 하는 동작

    사용자 계정의 정지 상태를 해지합니다.

    Tip

    계정을 정지 상태에서 복구하기 위해서 게임 서버는 유저 데이터에 계정 정지 상태인지에 대한 필드를 추가해서 관리해야 될 수도 있습니다.

    Tip

    계정 정지의 경우에 설명된 대로, 아이펀 디플로이는 계정 정지 기간과 사유에 대한 기록을 자체적으로 관리합니다. 따라서 게임 서버에서 이 API 를 호출받는 경우에는 이런 정보에 대한 고려 없이 그냥 계정을 정지 해제하시면 됩니다. 이 API 는 계정 정지 때 명시한 정지 기간이 끝났을 때나, 아니면 작업자가 명시적으로 정지 해제를 선택하는 경우 호출됩니다. 또한, 이 모든 내용은 감사 로그로 기록이 남게 됩니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK
    • HTTP body: 없음
  • 예시: K1234 라는 아이디를 계정 정지 해제(POST /cs-api/v1/account/K1234/ban)

    HTTP/1.1 200 OK
    

    Caution

    별도의 body 는 없이 상태값만 반환하면 됩니다.

  • 실패인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

      {
        "is_error": true,  // false 일 경우 성공으로 처리됩니다
        "description": "<실패 상황에 대한 메시지>",  // optional
        "error_info": {
          "errors": [
            {
              "target": "<실패한 대상 계정 ID>"
              "detail": "<실패한 계정 ID 의 실패 메시지>"  // optional
            }
          ]
        }
      }
      
    • 예시: 정지되지 않은 K1234 라는 아이디를 계정 정지 해제(POST /cs-api/v1/account/K1234/ban)

      HTTP/1.1 200 OK
      
      {
        "is_error": true,
        "description": "not blocked account",
        "error_info": {
          "errors": [
            {
              "target": "K1234"
              "detail": "정지되지 않은 계정입니다."
            }
          ]
        }
      }
      

      Caution

      is_error 의 값이 false 인 경우 에러에 대한 정보가 무시되고 성공으로 처리됩니다.

      Caution

      지정된 형식과 맞지 않는 값이 반환되면 실패로 처리됩니다.

POST /cs-api/v1/accounts/ban

  • 게임 서버에서 해야 하는 동작

    지정한 사용자 계정을 강제로 로그아웃 시키고, 계정을 정지 상태로 바꿉니다. 지정 대상들은 HTTP body 에 다음과 같은 형태로 전달됩니다.

    {
      "targets": [
        "<정지 대상 ID 1>",
        "<정지 대상 ID 2>",
        "<정지 대상 ID 3>",
        "<정지 대상 ID 4>",
        "<정지 대상 ID 5>",
        "<정지 대상 ID 6>",
        ...
      ]
    }
    

    Note

    정지 대상들은(targets) 중복되지 않고, 최대 1000 개까지 지정되어 전달됩니다.

    Tip

    계정을 정지 상태로 바꾸기 위해서 게임 서버는 유저 데이터에 계정 정지 상태인지에 대한 필드를 추가해서 관리해야 될 수도 있습니다.

    Tip

    아이펀 디플로이 대시보드에서는 계정을 정지시킬 때, 정지 기간과 사유도 입력을 받습니다. 그러나 게임 서버에서 이 정지 기간과 사유의 히스토리를 관리하는 것이 번거로우므로, 이 정보는 아이펀 디플로이 자체에 남고, 아이펀 디플로이는 계정 정지 기간이 시작될 때와 끝날 때 자동으로 POST /cs-api/v1/accounts/banPOST /cs-api/v1/accounts/ban/reinstate 를 게임 서버에 호출하게 됩니다. 이로써 게임 서버는 정지 기간이나 사유에 대한 기록을 별도 관리 하지 않아도 됩니다. 계정 정지 작업과 관련된 모든 내용은 운영 로그로 기록이 남게 됩니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK
    • HTTP body: 없음
  • 예시: 정지 대상 K1, K2, K3, K4 라는 아이디를 계정 정지

    HTTP/1.1 200 OK
    

    Caution

    별도의 body 는 없이 상태값만 반환하면 됩니다.

  • 실패인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

      {
        "is_error": true,  // false 일 경우 성공으로 처리됩니다
        "description": "<실패 상황에 대한 메시지>",  // optional
        "error_info": {
          "errors": [
            {
              "target": "<실패한 대상 계정 ID 1>"
              "detail": "<실패한 계정 ID 1 의 실패 메시지>"  // optional
            },
            {
              "target": "<실패한 대상 계정 ID 2>"
              "detail": "<실패한 계정 ID 2 의 실패 메시지>"  // optional
            }
          ]
        }
      }
      
  • 예시: 정지 대상 K1, K2, K3, K4 중 K1, K2 아이디를 계정 정지 실패

    HTTP/1.1 200 OK
    
    {
      "is_error": true,
      "description": "some account block fail",
      "error_info": {
        "errors": [
          {
            "target": "K1"
            "detail": "존재하지 않는 계정입니다."
          },
          {
            "target": "K2"
            "detail": "해당 계정은 이미 정지된 계정 입니다."
          }
        ]
      }
    }
    

    Caution

    is_error 의 값이 false 인 경우 에러에 대한 정보가 무시되고 성공으로 처리됩니다.

    Caution

    지정된 형식과 맞지 않는 값이 반환되면 실패로 처리됩니다.

POST /cs-api/v1/accounts/ban/reinstate

  • 게임 서버에서 해야 하는 동작

    지정한 사용자 계정의 정지 상태를 해제 합니다. 지정 대상들은 HTTP body 에 다음과 같은 형태로 전달됩니다.

    {
      "targets": [
        "<정지 해제 대상 ID 1>",
        "<정지 해제 대상 ID 2>",
        "<정지 해제 대상 ID 3>",
        "<정지 해제 대상 ID 4>",
        "<정지 해제 대상 ID 5>",
        "<정지 해제 대상 ID 6>",
        ...
      ]
    }
    

    Note

    정지 해제 대상들은(targets) 중복되지 않고, 최대 1000 개까지 지정되어 전달됩니다.

    Tip

    계정을 정지 상태에서 복구하기 위해서 게임 서버는 유저 데이터에 계정 정지 상태인지에 대한 필드를 추가해서 관리해야 될 수도 있습니다.

    Tip

    계정 정지의 경우에 설명된 대로, 아이펀 디플로이는 계정 정지 기간과 사유에 대한 기록을 자체적으로 관리합니다. 따라서 게임 서버에서 이 API 를 호출받는 경우에는 이런 정보에 대한 고려 없이 그냥 계정을 정지 해제하시면 됩니다. 이 API 는 계정 정지 때 명시한 정지 기간이 끝났을 때나, 아니면 작업자가 명시적으로 정지 해제를 선택하는 경우 호출됩니다. 또한, 이 모든 내용은 감사 로그로 기록이 남게 됩니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK
    • HTTP body: 없음
  • 예시: 정지 해제 대상 K1, K2, K3, K4 라는 아이디를 계정 정지 해제

    HTTP/1.1 200 OK
    

    Caution

    별도의 body 는 없이 상태값만 반환하면 됩니다.

  • 실패인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

      {
        "is_error": true,  // false 일 경우 성공으로 처리됩니다
        "description": "<실패 상황에 대한 메시지>",  // optional
        "error_info": {
          "errors": [
            {
              "target": "<실패한 대상 계정 ID 1>"
              "detail": "<실패한 계정 ID 1 의 실패 메시지>"  // optional
            },
            {
              "target": "<실패한 대상 계정 ID 2>"
              "detail": "<실패한 계정 ID 2 의 실패 메시지>"  // optional
            }
          ]
        }
      }
      
  • 예시: 정지 해제 대상 K1, K2, K3, K4 중 K1, K2 아이디를 계정 정지 해제 실패

    HTTP/1.1 200 OK
    
    {
      "is_error": true,
      "description": "some account unblock fail",
      "error_info": {
        "errors": [
          {
            "target": "K1"
            "detail": "존재하지 않는 계정입니다."
          },
          {
            "target": "K2"
            "detail": "해당 계정은 정지된 계정이 아닙니다."
          }
        ]
      }
    }
    

    Caution

    is_error 의 값이 false 인 경우 에러에 대한 정보가 무시되고 성공으로 처리됩니다.

    Caution

    지정된 형식과 맞지 않는 값이 반환되면 실패로 처리됩니다.

15.6.3. 캐릭터 관련 API

GET /cs-api/v1/account/<id>/character

  • 게임 서버에서 해야 하는 동작

    사용자 계정에 포함되는 게임 캐릭터 리스트를 JSON 으로 반환합니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: K1234 라는 계정의 캐릭터를 가져올 때 (GET /cs-api/v1/account/K1234/character)

      HTTP/1.1 200 OK
      
      {
        "character_ids": [
          {
            "id": "my_character1",
            "name" "캐릭터이름1"
          },
          {
            "id": "my_character2",
            "name" "캐릭터이름2"
          }
        ]
      }
      

      character_ids 라는 멤버 아래 캐릭터 정보를 나타내는 JSON 오브젝트의 배열로 반환하셔야 합니다.

      Tip

      캐릭터 정보에서 id 는 인증 타입에 관계없이 캐릭터를 고유하게 지칭할 수 있어야 하며, 사용자가 만든 이름, UUID 등 게임 정책에 따라 사용하시는 것을 쓰시면 됩니다.

      name 은 선택적으로 입력할 수 있는데, 만일 게임 내부에서 캐릭터를 고유하게 지칭하는 것과 별개로 사용자들이 보게 되는 이름이 별도로 존재하는 경우에 지정하실 수 있습니다. 예를 들어 id 는 UUID 형태이고 name 은 사용자가 지정하는 이름이지만 나중에 변경 가능한 형태로 게임을 구현하셨다면, name 을 따로 지정하실 수 있습니다.

      아이펀 디플로이 대시보드의 유저 검색처럼 이 API 를 쓰는 화면에서는 name 이 있으면 name 을 표시하고, 없으면 id 를 표시해줍니다.

      Important

      id 는 인증 타입에 관계없이 게임 내에서 고유해야 합니다.

GET /cs-api/v1/character/<id>

  • 게임 서버에서 해야 하는 동작

    해당 <id> 의 캐릭터 정보를 JSON 형태로 반환합니다.

    GET /cs-api/v1/account/<id> 에서와 마찬가지로 아이펀 디플로이는 반환되는 JSON 의 key 나 value 는 신경 쓰지 않고, JSON 결과를 테이블 형태로 보여줍니다. 따라서 게임 서버에서는 캐릭터에 대해서 외부에 노출하고 싶은 어떤 정보든 자유롭게 노출할 수 있습니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: GET /cs-api/v1/character/superman 에 해당하는 캐릭터가 있을 때

      HTTP/1.1 200 OK
      
      {
        "character": {
          "nickname": "동양챔피언"
          "hp": 100,
          "mp": 200,
          "parts": {
            "head": {
              "type": "helmet1",
              "duration": 100
            },
            "lhand": {
              "type": "shield1",
              "duration": 100
            },
            "rhand": {
              "type": "dagger1",
              "duration": 100
            }
          ]
        }
      }
      

      character 라는 멤버 아래 계정 정보를 JSON object 로 넣습니다.

    Note

    여기에 반환되는 데이터는 고객 지원 등 제한적인 이유로 사용되기 때문에, 반환되는 데이터가 DB 구조를 그대로 반영할 필요는 없습니다. 따라서 보여주어야 될 필드들 리스트나 필드 이름이나, 데이터가 nested 되는 구조 등을 임의로 지정하실 수 있습니다.

    Important

    사용자 정보가 nested 된 상태도 상관은 없습니다. 다만 character 에 맵핑된 오브젝트의 최상위 레벨에 있는 key 가 아닌 경우 읽기는 가능하지만 쓰기는 제한됩니다. 따라서 쓰기가 가능해야 하는 필드는 최상위 레벨에 지정해주셔야 합니다. 앞서 설명해 드린 것처럼 여기 반환되는 내용이 DB 구조를 그대로 반영할 필요가 없으므로 최상위 레벨의 필드가 아닌 것을 최상위로 옮기시더라도 문제는 없습니다.

PUT /cs-api/v1/character/<id>/<field>/<value>

  • 게임 서버에서 해야 하는 동작

    캐릭터 정보 중에서 <field> 에 해당하는 필드를 <value> 로 덮어씁니다.

    이렇게 덮어쓸 수 있는 필드들을 별도로 확인하는 이유는 자칫 아이펀 디플로이로 민감한 유저 정보까지 덮어쓰는 것을 막기 위함입니다. JSON 안에 포함되는 필드 이름은 앞의 GET /cs-api/v1/character/<id> 에서 반환되는 필드 중 character 바로 아래 최상위 레벨의 필드들이어야 합니다. 아이펀 디플로이는 이 API 에서 덮어쓰는 것이 가능하다고 된 필드들에 대해서 GET /cs-api/v1/character/<id> 를 통해 계정 정보를 보여줄 때 업데이트할 수 있게 표시해줍니다.

    Important

    게임 서버에서 복잡한 schema 를 아이펀 디플로이에 넘겨야 하는 상황없이 간단하게 데이터를 조작하기 위해서, 아이펀 디플로이는 변경 가능한 계정 정보를 GET /cs-api/v1/character/<id> 에 반환되는 결과 중 최상위 레벨의 필드로 제한합니다. 따라서 바꾸려는 <field> 가 캐릭터 정보에서 최상위 필드들인지 확인해주세요.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: hp 을 10 으로 갱신하는 경우 (PUT /cs-api/v1/character/superman/hp/10)

      HTTP/1.1 200 OK
      

      별도의 body 는 없이 상태 값만 반환하면 됩니다.

15.6.4. 인벤토리 조회 / 아이템 회수 관련 API

GET /cs-api/v1/character/<id>/inventory

  • 게임 서버에서 해야 하는 동작

    <id>에 해당하는 캐릭터가 소유하고 있는 인벤토리의 type/ id 정보를 JSON 형태로 반환합니다. 특정 캐릭터는 0개 이상의 인벤토리 type을 가질 수 있으며, 하나의 인벤토리 type 내에는 0개 이상의 인벤토리 id가 존재할 수 있습니다. 이 정보들은 캐릭터가 보유하고 있는 아이템의 목록을 조회하거나 특정 인벤토리 내의 아이템을 삭제하는 데 사용됩니다.

    Important

    인벤토리 type 과 인벤토리 id를 조합한 값은 캐릭터에 관계없이 유일해야 합니다. 즉, 캐릭터 id 없이 인벤토리 type 과 인벤토리 id 값만으로 인벤토리를 특정할 수 있어야 합니다. 예를 들면 superman이라는 캐릭터가 “weapon” 이라는 인벤토리 타입과 “slot_1”이라는 인벤토리 id를 가질 경우 superman 이외의 캐릭터는 인벤토리 타입이 “weapon” 이며, 인벤토리 id가 “slot_1” 인 인벤토리를 가질 수 없습니다. 인벤토리 참조 시 인벤토리 타입(“weapon”), 인벤토리 id(“slot_1”)를 지정하면 캐릭터 id 없이 해당 인벤토리 정보를 반환할 수 있어야 합니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK
    • HTTP body
    • 예시: superman 캐릭터가 보유한 인벤토리의 type,id 들의 정보를 가져오는 경우

    GET /cs-api/v1/character/superman/inventory

    HTTP/1.1 200 OK
    
    {
      "inventory_info" : {
        "weapon" : [ "slot_1", "slot_2"],
        "armor" : ["slot_1"]
      }
    }
    

    인벤토리 type 을 key로, 인벤토리 id의 array 을 값으로 가지는 pair들의 object 를 반환하셔야 합니다.

GET /cs-api/v1/inventory/<type>/<id>

  • 게임 서버에서 해야 하는 동작

    <type>/<id> 에 해당하는 인벤토리 내의 아이템 정보들을 JSON 형태로 반환합니다. 아이템 인스턴스 하나의 정보는 하나의 JSON object 형태로 구성되어야 하며, 아이템 정보들의 array 를 반환해 주셔야 합니다.

    <type>, <id> 외에도 페이징에 필요한 값들이 URL 파라미터로 전달됩니다. URL을 파싱하신 뒤 아래의 파라미터들을 참조해서 페이징 처리 를 해주셔야 합니다.

    1. __page : 페이지 번호
    2. __page_size : 페이지 사이즈

    Response는 아래와 같은 조건을 만족하여야 합니다.

    {
      "inventory" : [
        {
          "id" : 아이템 ID,
          "quantity": 20,
          "key1" : value1,
           ...
          "key9" : value9
        },
      ]
    }
    
    • Response body는 JSON Object 형태로, inventory 키가 존재해야 함
    • 아이템들의 정보는 inventory 키 안에 JSON Array 형태로 들어가 있어야 함
    • 아이템들의 정보는 (array)는 페이징 처리 가 된 상태이어야 함 (array 크기 <= __page_size)
    • 아이템들의 정보(array) 안에 아이템 데이터가 JSON Object 형태로 들어가 있어야 함
    • 아이템 정보를 나타내는 JSON Object는 다음 두 개의 필수 필드들을 가져야 합니다.
      • 해당 아이템의 IDid 키의 값으로 들어가 있어야 함
      • 해당 아이템의 개수quantity 키의 값으로 들어가 있어야 함
    • inventory 안의 데이터는 인벤토리 탭의 테이블 출력에 사용됩니다. 테이블에 출력하고자 하는 데이터를 마음대로 넣을 수 있습니다.

    Important

    items 는 내부적으로 사용하는 이름이므로 아이템 데이터에 넣으실 수 없습니다.

    • 페이징 처리

      /cs-api/v1/inventory/default/2?__page=2&__page_size=20

      위의 예시는 2페이지째의 데이터를 요청하고 있고 한 페이지에 결과가 최대 20개까지만 출력되어야 합니다. 그러므로 검색 후에 요청받은 데이터의 범위를 계산해서 21~40번째 검색결과만을 잘라 보내주셔야 합니다. ( __page(1) * __page_size(20) = 20 , 20 + __page_size(20) = 40 )

      Caution

      페이징 처리는 결과 조회의 편의성과 더불어 너무 큰 사이즈의 response로 인해 디플로이 서비스에 지장을 주는 경우를 막기 위해 결정된 사항입니다. __page_size 를 초과한 개수의 검색 결과가 들어올 경우, 디플로이는 검색 결과를 출력하지 않고 에러 메시지를 띄울 것입니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK
    • HTTP body
    • 예시: 인벤토리 type이 weapon, 인벤토리 id가 slot_1 인 인벤토리 내의 아이템 정보를 표시하는 경우

    GET /cs-api/v1/inventory/weapon/slot_1

    HTTP/1.1 200 OK
    {
      "inventory" : [
        {
         "id" : "33",
         "item_code" : "short_sword_1",
         "description" : "wooden short sword",
         "quantity" : 20,
         "atk" : 30,
         "dur" : 40,
         "grade" : 4
       },
       {
         "id" : "34",
         "item_code" : "short_sword_1",
         "description" : "wooden short sword",
         "quantity" : 1,
         "atk" : 35,
         "dur" : 40,
         "grade" : 5
       }
     ]
    }
    

POST /cs-api/v1/inventory/<type>/<id>/item/<item_id>

  • 게임 서버에서 해야 하는 동작

    <type>/<id> 에 해당하는 인벤토리 내에서 <item_id> 를 가지는 아이템 인스턴스의 개수를 전달받은 정보 current_quantityquantity_to_reclaim 의 값을 가지고 변경합니다.

    HTTP body 는 다음과 같은 형태로 전달됩니다.

    {
        "current_quantity": 20,
        "quantity_to_reclaim": 3
    }
    
    • current_quantity: 아이템 회수 실행 시 운영자가 화면에서 보이는 아이템 현재 개수의 값입니다.
    • quantity_to_reclaim: 아이템을 몇 개를 회수할지에 대한 값입니다.

    Important

    해당 아이템 DB 정보의 quantitycurrent_quantity 값이 같은지 반드시 확인해주세요. quantity_to_reclaim 가 DB 정보보다 크거나 같다면 아이템이 삭제되어야 합니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body: 없음

    • 예시: 인벤토리 type이 weapon이고 인벤토리 id가 slot_1 인 인벤토리 내에서 item_id가 33, quantity가 30개인 아이템 15개를 회수하는 경우

    • HTTP 요청: POST /cs-api/v1/inventory/weapon/slot_1/item/33

    • HTTP body

      {
          "current_quantity": 30,
          "quantity_to_reclaim": 15
      }
      
    • HTTP 응답

      HTTP/1.1 200 OK
      

      별도의 body 는 없이 상태값만 반환하면 됩니다.

POST /cs-api/v1/inventory/items

  • 게임 서버에서 해야 하는 동작

    전달받은 정보를 확인 후 해당하는 다수의 아이템 인스턴스를 제거합니다.

    HTTP body 는 다음과 같은 형태로 전달 됩니다.

    인벤토리 typeid 를 key 로 가진 JSON Object 에 JSON Array 로 회수할 아이템의 item_id, 현재 개수(current_quantity), 회수할 개수(quantity_to_reclaim)를 전달 합니다.

    {
      "weapon" {  // inventory type
        "w_slot_1" : [  // inventory id
          {"item_id": "1", "current_quantity": 30, "quantity_to_reclaim": 15},
          {"item_id": "2", "current_quantity": 63, "quantity_to_reclaim": 21},
          {"item_id": "3", "current_quantity": 71, "quantity_to_reclaim": 16},
          {"item_id": "4", "current_quantity": 5, "quantity_to_reclaim": 2}
        ],
        "w_slot_2" : [  // inventory id
          {"item_id": "2", "current_quantity": 1, "quantity_to_reclaim": 1},
          {"item_id": "3", "current_quantity": 5, "quantity_to_reclaim": 1}
        ]
      }
      "armor" {  // inventory type
        "a_slot_1" : [  // inventory id
          {"item_id": "1", "current_quantity": 33, "quantity_to_reclaim": 11},
        ],
        "b_slot_2" : [  // inventory id
          {"item_id": "1", "current_quantity": 150, "quantity_to_reclaim": 67},
          {"item_id": "2", "current_quantity": 1, "quantity_to_reclaim": 1},
          {"item_id": "3", "current_quantity": 79, "quantity_to_reclaim": 2}
        ]
      }
      ...
    }
    
    • item_id: 삭제할 아이템 인스턴스의 id 입니다.
    • current_quantity: ‘아이템 회수 실행 시 운영자가 화면에서 보이는 아이템 현재 개수의 값입니다.
    • quantity_to_reclaim: 아이템을 몇 개를 회수할지에 대한 값입니다.
  • 성공인 경우 응답

    • HTTP 상태값: 200 OK
    • HTTP body: 없음
  • 예시: 인벤토리 type weapon 안의 인벤토리 id w_slot_1 에 있는 삭제할 3개의 아이템 인스턴스 요청을 받은 경우

    • HTTP 요청: POST /cs-api/v1/inventory/items

    • HTTP body

      {
        "weapon" {
          "w_slot_1" : [
            {"item_id": "1", "current_quantity": 30, "quantity_to_reclaim": 15},
            {"item_id": "2", "current_quantity": 63, "quantity_to_reclaim": 21},
            {"item_id": "4", "current_quantity": 5, "quantity_to_reclaim": 2}
          ]
        }
      }
      
    • HTTP 응답

      HTTP/1.1 200 OK
      

      별도의 body 는 없이 상태값만 반환하면 됩니다.

15.6.5. 아이템 지급 관련 API

GET /cs-api/v1/item/giftable

  • 게임 서버에서 해야 하는 동작

    아이펀 디플로이를 통해서 지급 가능한 아이템들을 JSON 배열로 반환합니다.

    Important

    고객 지원에서 많은 경우 아이템 지급에 있어서 사고가 발생하게 됩니다. 이 때문에 아이펀 디플로이에서는 가능한 아이템을 한정하고 이 아이템만 지급되도록 강제하고 있습니다. 사용자 정의 기능 를 통해서 아이템을 지급하는 경우 이런 보호 장치를 건너뛰는 일이 발생할 수 있는데, 이 부분에 대해 충분한 고려를 하셔야 합니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: GET /cs-api/v1/item/giftable

      HTTP/1.1 200 OK
      
      {
        "giftable_items": [
          {
            "id": "sword1",
            "name": "1성검"
          }
          {
            "id": "sword2",
            "name": "2성검"
          }
          {
            "id": "sword3",
            "name": "3성검"
          }
        ]
      }
      

      giftable_items 라는 멤버 아래 아이템 정보를 나타내는 JSON 오브젝트의 배열로 반환하셔야 합니다. 아이템 정보를 나타내는 JSON 오브젝트는 다음 두 개의 필수 필드들을 가져야 합니다.

      • id: 유일하게 아이템 타입을 구분할 수 있는 아이템의 타입 아이디. 이 id 는 아래 POST /cs-api/v1/character/<id>/gift 에 사용됩니다.
      • name: 사람이 읽을 수 있는 형태의 해당 아이템의 이름입니다.

POST /cs-api/v1/item/gift

  • 게임 서버에서 해야 하는 동작

    지정한 대상 또는 모두에게 아이템을 지급합니다. HTTP body 는 다음과 같은 형태로 구성됩니다.

    {
      "title": "...",
      "content": "...",
      "expires": <timestamp int>
      "items": [{
        "id": <아이템 타입 ID 1>,
        "count": <number int>
      }, {
        "id": <아이템 타입 ID 2>,
        "count": <number int>
      },
      ...],
      "targets": "all" or [<대상 ID 1>, <대상 ID 2>, ...],
      "target_id_type": "characters"
    }
    
    • title: 아이템 지급 건에 대한 타이틀로 쓰입니다.

      보통 지급된 아이템은 우편함에 들어가게끔 하는 경우가 많은데, 이때 우편함에 노출되는 지급 이유에 해당합니다. (예, 점검보상, 식곤증 극복 이벤트 보상, …)

    • content: 아이템 지급 건에 대한 상세 설명이 필요한 경우 사용됩니다.

      title 과 유사한 이유로 쓰일 수 있는데, 좀 더 상세한 설명이 필요한 경우 선택적으로 쓰실 수 있습니다.

    • expires: 아이템을 지급하고 언제까지 받아야 하는지를 지정합니다.

      Note

      아이펀 디플로이는 만료 정보만을 전달하는 역할을 하며, 아이템 만료에 따라 자동으로 아이템을 삭제하지는 않습니다. 지급 아이템 만료 처리는 게임 서버에서 구현하셔야 합니다.

    • items: 지급할 아이템들의 ID, 수량을 리스트로 전달합니다.

    • targets: 아이템을 지급할 대상을 지정합니다. “all” 로 설정하면 모든 대상에게 지급합니다. ID 리스트로 지정하면 해당 대상들에게 아이템을 지급합니다.

    • target_id_type: targets 가 지급 대상 계정(accounts) ID 정보인지, 지급 대상 캐릭터(characters) ID 정보인지를 나타냅니다. 예를 들어 targets 는 “all” 이고 target_id_type 이 “accounts”라면 모든 계정에 아이템을 지급함을 뜻하며, targets 가 [ “1”, “2” ] 이고 target_id_type 이 “characters”라면 ID 가 “1”, “2” 인 캐릭터에 아이템을 지급함을 뜻합니다.

    Tip

    비록 아이펀 디플로이가 GET /cs-api/v1/item/giftable 을 통해서 지급 가능한 아이템을 파악하긴 하지만, 그래도 게임서버에서 POST /cs-api/v1/item/gift 에 대해서 입력으로 들어오는 아이템에 대해 검증은 하시는 것이 좋습니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK
    • HTTP body: 없음
  • 예시:

    • HTTP 요청: POST /cs-api/v1/item/gift

    • HTTP body

      {
        "title": "아이템을 지급합니다.",
        "content": "즐거운 하루 되세요~",
        "expires": 1487147962,
        "items": [{
          "id": "7",
          "count": 10,
        }, {
          "id": "8"
          "count": 11,
        }],
        "targets": ["user_1", "user_3", "user_7"],
        "target_id_type": "characters"
      }
      
    • HTTP 응답

      HTTP/1.1 200 OK
      

      별도의 body 는 없이 상태값만 반환하면 됩니다.

15.6.6. 게임 내 변경가능 정보 API

GET /cs-api/v1/editable/account

  • 게임 서버에서 해야 하는 동작

    사용자 계정 정보 중에서 아이펀 디플로이를 통해서 덮어쓰는 것을 허용할 필드들의 리스트를 JSON 으로 반환합니다.

    이렇게 덮어쓸 수 있는 필드들을 별도로 확인하는 이유는 자칫 아이펀 디플로이로 민감한 유저 정보까지 덮어쓰는 것을 막기 위함입니다. JSON 안에 포함되는 필드 이름은 앞의 GET /cs-api/v1/account/<id> 에서 반환되는 필드 중 최상위 레벨의 필드들이어야 합니다. 아이펀 디플로이는 이 API 에서 덮어쓰는 것이 가능하다고 된 필드들에 대해서 GET /cs-api/v1/account/<id> 를 통해 계정 정보를 보여줄 때 업데이트할 수 있게 표시해줍니다.

    Important

    게임 서버에서 복잡한 schema 를 아이펀 디플로이에 넘겨야 하는 상황 없이 간단하게 데이터를 조작하기 위해서, 아이펀 디플로이는 변경 가능한 계정 정보를 GET /cs-api/v1/account/<id> 에 반환되는 결과 중 최상위 레벨의 필드로 제한합니다. 따라서 이 editable 로 반환되는 필드들이 계정 정보에서 최상위 필드들인지 확인해주세요.

    Tip

    만일 최상위 레벨이 아니라 그 아래 nested 된 필드들을 수정해야 하는 일이 있다면 사용자 정의 기능 를 통해서 해당 기능을 추가하실 수 있습니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: coinclover 가 아이펀 디플로이의 고객 관리 기능을 통해서 갱신 가능할 경우.

      HTTP/1.1 200 OK
      
      {
        "editable_fields": [ "coin", "clover" ]
      }
      

      editable_fields 라는 멤버 아래 수정 가능한 필드 이름을 배열 형태로 반환합니다.

GET /cs-api/v1/editable/character

  • 게임 서버에서 해야 하는 동작

    캐릭터 정보 중에서 아이펀 디플로이를 통해서 덮어쓰는 것을 허용할 필드들의 리스트를 JSON 으로 반환합니다.

    이렇게 덮어쓸 수 있는 필드들을 별도로 확인하는 이유는 자칫 아이펀 디플로이로 민감한 유저 정보까지 덮어쓰는 것을 막기 위함입니다. JSON 안에 포함되는 필드 이름은 앞의 GET /cs-api/v1/character/<id> 에서 반환되는 필드 중 최상위 레벨의 필드들이어야 합니다. 아이펀 디플로이는 이 API 에서 덮어쓰는 것이 가능하다고 된 필드들에 대해서 GET /cs-api/v1/character/<id> 를 통해 계정 정보를 보여줄 때 업데이트할 수 있게 표시해줍니다.

    Important

    게임 서버에서 복잡한 schema 를 아이펀 디플로이에 넘겨야 하는 상황 없이 간단하게 데이터를 조작하기 위해서, 아이펀 디플로이는 변경 가능한 계정 정보를 GET /cs-api/v1/character/<id> 에 반환되는 결과 중 최상위 레벨의 필드로 제한합니다. 따라서 이 editable 로 반환되는 필드들이 계정 정보에서 최상위 필드들인지 확인해주세요.

    Tip

    만일 최상위 레벨이 아니라 그 아래 nested 된 필드들을 수정해야 하는 일이 있다면 사용자 정의 기능 를 통해서 해당 기능을 추가하실 수 있습니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: hpmp 가 아이펀 디플로이의 고객 관리 기능을 통해서 갱신 가능할 경우.

      HTTP/1.1 200 OK
      
      {
        "editable_fields": [ "hp", "mp" ]
      }
      

      editable_fields 라는 멤버 아래 수정 가능한 필드 이름을 배열 형태로 반환합니다.

15.6.7. 게임 내 캠페인 (이벤트) 관련 API

Important

아이펀 디플로이는 게임 서버에서 지원하는 이벤트 종류와 각 이벤트를 발동시키기 위해 필요한 파라미터 정보를 읽어왔다가, 게임 운영자가 이 캠페인 중에서 자유롭게 선택해서 캠페인을 진행할 수 있게 지원합니다. 이 때 아이펀 디플로이는 게임 서버로부터 받은 정보를 이벤트 발동 시에 그대로 호출하는 역할만을 하므로, 아래 설명에 나오는 캠페인 이름이나 파라미터 정보는 게임에서 필요한대로 임의로 넣으시면 됩니다.

GET /cs-api/v1/campaign/type

  • 게임 서버에서 해야 하는 동작

    게임 서버에서 지원하는 캠페인 (이벤트) 정보를 JSON 로 반환합니다.

    Note

    이 API 에 대한 응답은 게임 내에서 지원하는 캠페인 종류와 각 캠페인이 주는 보상 선택지를 반환합니다. 이 정보는 나중에 게임 운영자가 이벤트를 진행할 때 게임 서버에 이벤트 시작을 알리는 POST /cs-api/v1/campaign/<type>/<id>/begin 로 전달됩니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: 게임 서버에서 login_eventarmor_discount_event 가 가능하고, login_event 의 경우 보상으로 운영자가 골드나 방패 아이템을 줄 수 있는 경우

      HTTP/1.1 200 OK
      
      {
        "campaign_types": {
          "login_event": {
            "name": "로그인시 아이템 지급 이벤트",
            "reward_schemas": [
              {
                "id": "gold",
                "name": "게임 내 골드",
                "value_type": "int"
              },
              {
                "id": "shield2",
                "name": "2성급 방패",
                "value_type": "int"
              },
              ...
            ]
          },
      
          "armor_discount_event": {
          },
      
          ...
        }
      }
      

      campaign_types 라는 멤버 아래 캠페인 정보를 나타내는 JSON 오브젝트를 반환하셔야 합니다. 캠페인 정보는 캠페인 ID 를 key 로 하고 캠페인 정보를 JSON object 형태의 value 로 갖습니다.

      캠페인 정보를 나타내는 JSON 오브젝트는 다음과 같은 필드들을 가질 수 있습니다.

      • name: 사람이 읽을 수 있는 형태의 이벤트 이름입니다. 운영자가 캠페인을 구분하기 쉽도록 아이펀 디플로이 대시보드에 노출되는 이름입니다.

      • reward_schemas: 이 캠페인에서 가능한 보상 선택지들을 나열합니다.

        여기 나열된 모든 것을 지급한다는 것이 아니라, 게임 운영자가 이 이벤트를 시작할 때 어떤 보상을 줄 수 있는지 선택하게 하는 선택지로 동작합니다. 그때 몇 개의 선택지를 고르느냐애 따라 캠페인의 보상 개수가 달라집니다.

        reward_schemas 는 다시 다음과 같은 필드들을 갖는 JSON object 의 배열로 구성됩니다.

        • id: 캠페인 안에서 보상 내용을 구분하기 위한 ID 입니다.

          각 캠페인안에서 구분할 수 있는 이름이면 됩니다. 예를 들어 위의 예에서처럼 goldshield2 같은 이름을 써도 되고, 1, 2 와 같은 보상 아이템 순서를 사용할 수도 있습니다.

        • name: 게임 운영자가 읽을 수 있는 보상 물품의 이름입니다.

          게임 서버와는 특정 캠페인 타입의 특정 보상 ID 와 같은 방식으로 통신하기 때문에 여기 사용되는 이름은 단지 운영자의 이해를 돕기 위해서만 쓰입니다.

        • value_type: int, float, string 가 가능합니다.

          나중에 POST /cs-api/v1/campaign/<type>/<id>/begin 로 선택된 보상을 넘겨줄 때 적절한 JSON 타입으롬 변환하기 위해서 사용됩니다. 예를 들어 위의 예에서 gold 는 int 로 지정되어있기 때문에 나중에 "gold": 100 과 같은 형태로 전달이 됩니다. 만일 string 이면 "gold": "100" 이런 형태가 될 것입니다. 그리고 이 내용에 따라 아이펀 디플로이 대시보드에서 잘못된 입력이 들어올 경우 걸러주는 역할도 합니다.

POST /cs-api/v1/campaign/<type>/<id>/begin

  • 게임 서버에서 해야 하는 동작

    앞에서 설명한 GET /cs-api/v1/campaign/type 의 결과에 따른 캠페인 <type> 을 시작합니다. 이 때 같은 <type> 의 캠페인이 동시에 존재할 수도 있기 때문에, 아이펀 디플로이는 고유한 캠페인 <id> 를 붙여서 요청을 보내게 됩니다. 게임 서버는 이 <id>보상(rewards) 을 기억했다가 이후에 종료/취소 API 호출을 받게 되면 해당 캠페인을 종료/취소 처리해야 합니다.

    그리고 보상을 포함한 캠페인에 대한 정보는 HTTP body 에 실어서 가게 되는데, HTTP body 는 다음과 같은 형태로 구성됩니다.

    {
      "name": "오픈기념 로그인 이벤트",
      "description": "로그인만 해도 골드와 2성급 방패를 쏜다!",
      "begin": 1487051040,
      "end": 1487086200,
      "rewards": [
        {"id": "gold", "value": 2000, "name": "Gold"},
        {"id": "gem", "value": 40, "name": "Gem"},
        {"id": "iron_shield", "value": 1, "name": "Iron Shield"}
      ],
      "is_recurring": true,
      "recurring_schedule": {
        'days_of_the_week': [1, 5, 7],
        'time_range': ['11:55', '14:05'],
        'timezone': 'Asia/Seoul'
      }
    }
    
    • name: (필수) 캠페인의 이름

      게임 서버는 이 이름을 쓸지 말지 자유롭게 택할 수 있는데, 이를 이용하면 가령 전체 플레이어에게 주어진 문자열의 캠페인이 시작되었다는 메시지를 보내는 것 같은 동작을 할 수 있습니다.

    • description: (선택) 부가적인 설명

    • begin: (필수) 캠페인 시작 시간

      Unix 타임스탬프 정수 타입이고 단위는 초입니다. 캠페인 기간의 시작 시간입니다. 반복 캠페인의 경우 캠페인 기간의 시작 시간이 날짜로 지정되기 때문에, 이 필드는 시작 날짜의 00:00:00 에 해당하는 타임스탬프를 나타냅니다.

    • end: (필수) 캠페인 종료 시간

      Unix 타임스탬프 정수 타입이고 단위는 초입니다. 캠페인 기간의 종료 시간입니다. 반복 캠페인의 경우 캠페인 기간의 끝 시간이 날짜로 지정되기 때문에, 이 필드는 끝 날짜의 23:59:59 에 해당하는 타임스탬프를 나타냅니다.

    • rewards: (필수) 이벤트 보상 아이템들의 데이터가 JSON Object로 들어있는 JSON Array

      Tip

      rewards에 들어가는 항목이 반드시 아이템일 필요는 없습니다. gold 나 hp, 추가 경험치 비율 등 다양한 파라미터가 될 수 있습니다.

    • is_recurring: (필수) 반복 캠페인 여부를 표시합니다. JSON boolean 타입이고, true 면 반복, false 면 일회성 캠페인입니다.

    • recurring_schedule: (선택) 반복 캠페인인 경우 반복 스케줄을 표시합니다. JSON object 타입이고 일회성 캠페인이면 null 값을 가집니다.

      • days_of_the_week: 반복할 요일을 표시합니다. JSON 정수 배열 타입입니다. 각 정수는 요일을 나타내고, ISO8601 표기에 따라 월요일은 1, 화요일은 2, …, 일요일은 7 로 표시합니다. (예: [1,2,5,7])
      • time_range: 매 반복 일의 캠페인 시작과 종료 시간을 표시합니다. 크기 2인 JSON 문자열 배열 타입입니다. 배열의 각 원소는 <시간>:<분> 형태로 이루어져 있고, 24 시간 표기법을 사용합니다. (예: ["00:00", "23:59"])
      • timezone: 반복 캠페인 날짜 및 시간의 타임존을 표시합니다. JSON 문자열 타입으로, tz database(https://en.wikipedia.org/wiki/Tz_database) 에서 사용하는 zone 이름으로 표시합니다. (예: "Asia/Seoul")
    • 캠페인의 종료

      캠페인이 종료되면 POST /cs-api/v1/campaign/<type>/<id>/end 를 받게 되며 해당 캠페인을 종료 처리해야 합니다.

    • 캠페인 진행 도중 취소

      캠페인 목록 조회테이블 형태로 조회 에서 In progress 인 캠페인을 삭제하면 POST /cs-api/v1/campaign/<type>/<id>/cancel 을 받게 되며 해당 캠페인을 취소 처리해야 합니다.

      Important

      게임 서버에서 반드시 <id>rewards 를 저장해야 합니다. 이후 캠페인 종료/취소 시 필요합니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: POST /cs-api/v1/campaign/login_event/de305d54-75b4-431b-adb2-eb6b9e546014/begin

      HTTP/1.1 200 OK
      

      별도의 body 는 없이 상태 값만 반환하면 됩니다.

POST /cs-api/v1/campaign/<type>/<id>/end

  • 게임 서버에서 해야 하는 동작

    앞에서 설명한 POST /cs-api/v1/campaign/<type>/<id>/begin 으로 시작한 캠페인을 종료합니다. 이 때 같은 <type> 의 캠페인이 존재할 수도 있으므로, <id> 에 기재되어 있는 캠페인을 종료해야 합니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: POST /cs-api/v1/campaign/login_event/de305d54-75b4-431b-adb2-eb6b9e546014/end

      HTTP/1.1 200 OK
      

      별도의 body 는 없이 상태 값만 반환하면 됩니다.

POST /cs-api/v1/campaign/<type>/<id>/cancel

  • 게임 서버에서 해야 하는 동작

    이미 POST /cs-api/v1/campaign/<type>/<id>/begin 으로 시작한 캠페인 또는 아직 시작하지 않은 캠페인을 취소합니다. 이 때 같은 <type> 의 캠페인이 존재할 수도 있으므로, <id> 에 기재되어 있는 캠페인을 취소해야 합니다.

    Important

    게임 서버에서 진행 중인 캠페인 취소 시 플레이어에게 지급된 보상(rewards)에 대해서는 게임 서버에서 직접 회수해야 합니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: POST /cs-api/v1/campaign/login_event/de305d54-75b4-431b-adb2-eb6b9e546014/cancel

      HTTP/1.1 200 OK
      

      별도의 body 는 없이 상태값만 반환하면 됩니다.

15.6.8. 환불 API

PUT /cs-api/v1/payment/refund/<receipt_id>

  • 게임 서버에서 해야 하는 동작

    통계 분석 기능을 위한 필수 로그 의 결제 결과( PaymentEnd ) 에서 남긴 고유한 영수증 ID 인 <receipt_id> 와 결제 결과 데이터를 가지고, 게임 서버에서 저장 또는 불러올 수 있는 영수증과 대조 후 환불을 진행합니다.

    결제 결과 데이터는 HTTP body 에 다음과 같은 형태로 변환되어 전달됩니다.

    {
      "purchase_log": {
        "_ts": {"$date": 1500886110429},
        "receipt_id": "52fb979f-c728-4d6e-a3bf-9a0133a54081",
        "account_id": "1"
        "product_id": "gem.1000",
        "system_error": false,
        "amount": 400000,
         ...  // 필수 필드를 제외한 다른 필드들
       }
    }
    

    Note

    반드시 통계 분석 기능을 위한 필수 로그 의 환불 결과( PaymentRefund ) 로그를 남겨야 합니다. 환불 결과 로그가 없으면 디플로이에서 환불되지 않은 것으로 표시됩니다. 환불 결과 로그는 통계 분석 기능을 위한 필수 로그 의 환불 결과 항목을 참조해주세요.

    Important

    환불된 상품에 대해서는 게임 서버에서 직접 회수해야 합니다. 그리고 중복으로 환불이 진행되지 않게 해야 합니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: 영수증 ID 가 52fb979f-c728-4d6e-a3bf-9a0133a54081 인 결제를 환불

      • HTTP 요청 PUT /cs-api/v1/payment/refund/52fb979f-c728-4d6e-a3bf-9a0133a54081

      • HTTP body

        {
          "purchase_log": {
            "_ts": {"$date": 1500886110429},
            "receipt_id": "52fb979f-c728-4d6e-a3bf-9a0133a54081",
            "account_id": "1"
            "product_id": "gem.1000",
            "system_error": false,
            "amount": 400000
          }
        }
        
      • HTTP 응답

        HTTP/1.1 200 OK
        

      별도의 body 는 없이 상태값만 반환하면 됩니다.

15.6.9. 실시간 공지 API

GET /cs-api/v1/notice/realtime/category

  • 게임 서버에서 해야 하는 동작

    서버에서 추가로 지원할 실시간 게임 공지 분류를 JSON 으로 반환합니다. 디플로이에서는 기본적으로 chat, screen 두 가지 분류가 설정되어 있습니다. 이 두 가지 분류 외 다른 분류를 추가해야 할 때 해당 API 에 원하는 분류 값을 반환하면 됩니다.

    실시간 게임 공지 분류를 의미하는 문자열은 사용자가 구분할 수 있는 임의의 문자열로 지정하시면 됩니다. 실시간 게임 공지를 생성할 때에 이 문자열이 category 라는 JSON 파라미터로 게임 서버에 전달됩니다.

    아이펀 디플로이는 이 문자열이 실제 의미하는 것이 뭔지는 신경 쓰지 않고, 게임 서버가 각 문자열에 해당하는 실시간 게임 공지 분류를 지원한다고 이해하게 됩니다.

    Note

    다른 분류가 필요 없을면 빈값을 반환하면 됩니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

      • 다른 분류가 필요한 경우

        {
          "category": ["category1", "category2", "category3"]
        }
        
      • 다른 분류를 사용하지 않는 경우

        {
          "category": []
        }
        
    • 예시: 디플로이에서 게임 서버로 실시간 게임 공지 분류를 요청

      • HTTP 요청 GET /cs-api/v1/notice/realtime/category

      • HTTP 응답

        HTTP/1.1 200 OK
        
        {
          "category": ["boss_event", "buff_event"]
        }
        

POST /cs-api/v1/notice/realtime

  • 게임 서버에서 해야 하는 동작

    전달된 파라미터를 확인하여 실시간 게임 공지를 게임상에 출력합니다. 전달되는 파라미터 데이터는 HTTP body 에 다음과 같은 형태로 변환되어 전달됩니다.

    {
      "category": "<실시간 게임 공지 분류>",
      "color": "<게임상에 표시될 메시지 색깔 RGB color string>",
      "messages": {
        "<language code 1>": "<language code 1 에 맞는 언어의 게임상에 표시될 메시지>",
        "<language code 2>": "<language code 2 에 맞는 언어의 게임상에 표시될 메시지>",
        "<language code 3>": "<language code 3 에 맞는 언어의 게임상에 표시될 메시지>",
      }
    }
    
    • category: 실시간 게임 공지의 분류가 전달됩니다.
    • color: 실시간 게임 공지를 표시할 때 지정할 색깔이 전달됩니다.
    • messages: 실시간 게임 공지의 메시지가 언어별로 전달됩니다. key 가 각 언어코드이며 value 가 해당 언어에 대한 메시지가 됩니다.

Note

language code지원 언어와 코드 를 참조하세요.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: 버프 이벤트시 한국, 미국, 일본 게임 플레이어들에게 흰색으로 응원 메시지를 전달

      • HTTP 요청 POST /cs-api/v1/notice/realtime

      • HTTP body

        {
          "category": "buff_event",
          "color": "ffffff",
          "messages": {
            "ko": "힘내라!",
            "en": "fighting!",
            "ja": "がんばれ!"
          }
        }
        
      • HTTP 응답

        HTTP/1.1 200 OK
        

      별도의 body 는 없이 상태값만 반환하면 됩니다.

15.6.10. 미션 정보 조회 API

GET /cs-api/v1/mission/category

  • 게임 서버에서 해야 하는 동작

    서버에서 지원할 일반 미션업적 미션 의 하위 분류를 JSON 으로 반환합니다.

    미션 분류를 의미하는 문자열은 사용자가 구분할 수 있는 임의의 문자열로 지정하시면 됩니다. 일반 또는 업적 미션 정보를 조회 할때 이 문자열이 category 라는 JSON 파라미터로 게임 서버에 전달됩니다.

    아이펀 디플로이는 이 문자열이 실제 의미하는 것이 뭔지는 신경 쓰지 않고, 게임 서버가 각 문자열에 해당하는 미션 분류를 지원한다고 이해하게 됩니다.

Note

디플로이에서는 미션을 크게 기간제, 일반, 업적 미션의 3개로 나누어 관리하고, 편의를 위한 하위분류를 지원합니다. 하위 분류는 일반, 업적 미션의 두가지 분류에만 지원 하며, 해당 API 의 JSON 값의 문자열을 그대로 사용 합니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

      {
        "category": {
          "normal": ["<normal_category_1>", "<normal_category_2>"],
          "achievement": ["<achievement_category_1>", "<achievement_category_2>"]
        }
      }
      
    • normal: 일반 미션 분류 목록을 지정하시면 됩니다.

    • achievement: 업적 미션 분류 목록을 지정하시면 됩니다.

    • 예시: 디플로이에서 게임 서버로 미션 조회 시 사용할 분류를 요청

      • HTTP 요청 GET /cs-api/v1/mission/category

      • HTTP 응답

        HTTP/1.1 200 OK
        
        {
          "category": {
            "noraml": ["campaign", "character", "main", "sub"],
            "achievement": ["finish_skill", "great_success", "mana_slot", "max_damage"]
          }
        }
        

GET /cs-api/v1/character/<character_id>/mission/status/periodic

  • 게임 서버에서 해야 하는 동작

    해당하는 캐릭터의 기간제 미션 진행 상태를 JSON 으로 반환합니다. 결과 값에 표시 되는 미션은 해당 기간에 시작된 미션입니다.

    결과 출력에 필요한 값들은 character_id 를 제외하고 URL 파라미터로 전달되며, 사용되는 파라미터는 아래의 4가지입니다. URL을 파싱하신 뒤에 이 파라미터들의 값을 참조해서 검색을 수행하시면 됩니다.

    1. periodic_type : 결과의 기간 분류 조건 입니다. daily, weekly, monthly 중 하나의 값이 전달됩니다.
    2. mission_start_date : 결과의 기간 기준 값 입니다. timestamp 로 전달됩니다.
    3. __page : 페이지 번호
    4. __page_size : 페이지 사이즈

Note

daily, weekly, monthly 는 각각 일일, 주간, 월간 미션을 뜻 합니다.

  • 성공인 경우 응답

    • 각 필드에 대한 설명은 미션 정보 검색 결과 응답 을 참조하세요.

    • 예시: ID 가 1인 캐릭터의 2018년 3월에 시작하는 월간 미션 상태 조회

      • HTTP 요청

        GET /cs-api/v1/character/1/mission/status/periodic?periodic_type=monthly&mission_start_date=1519862400&__page=1&__page_size=20
        
      • HTTP 응답

        HTTP/1.1 200 OK
        
        {
            "search_result": [
                {
                    "accepted_at": 1520683616,
                    "category": "free",
                    "current_step": 1,
                    "description": "[퀘스트 시작 장소]\n마의산\n",
                    "finished_at": 1520689856,
                    "goal_step": 1,
                    "id": 1289,
                    "received_reward_at": null,
                    "rewards": "Gold Bar x 1",
                    "state": "failed",
                    "title": "연대기"
                },
                {
                    "accepted_at": 1520658716,
                    "category": "free",
                    "current_step": 1,
                    "description": "[퀘스트 시작 장소]\n산마루 마을\n",
                    "finished_at": 1520665196,
                    "goal_step": 1,
                    "id": 1285,
                    "received_reward_at": 1520665976,
                    "rewards": "Won Lottery x 1",
                    "state": "completed",
                    "title": "도전자의 동굴"
                },
                {
                    "accepted_at": 1520653616,
                    "category": "free",
                    "current_step": 1,
                    "description": "[퀘스트 시작 장소]\n관문의 마을\n",
                    "finished_at": 1520654336,
                    "goal_step": 1,
                    "id": 1283,
                    "received_reward_at": null,
                    "rewards": "Platemail x 1",
                    "state": "progressed",
                    "title": "쇠약 주의"
                },
                {
                    "accepted_at": 1520472716,
                    "category": "free",
                    "current_step": 1,
                    "description": "[퀘스트 시작 장소]\n성도\n",
                    "finished_at": 1520475776,
                    "goal_step": 1,
                    "id": 1267,
                    "received_reward_at": null,
                    "rewards": "Arcana x 1",
                    "state": "progressed",
                    "title": "시가전"
                }
            ]
        }
        

GET /cs-api/v1/character/<character_id>/mission/record/normal

  • 게임 서버에서 해야 하는 동작

    해당하는 캐릭터의 일반 미션 검색 결과를 JSON 으로 반환합니다.

    검색에 필요한 값들은 character_id 를 제외하고 URL 파라미터로 전달되며, 사용되는 파라미터는 아래의 6가지입니다. URL을 파싱하신 뒤에 이 파라미터들의 값을 참조해서 검색을 수행하시면 됩니다.

    1. category : 검색 분류 조건 입니다. GET /cs-api/v1/mission/category API 의 normal 값 중 하나의 값이 전달됩니다. 빈 문자열이 전달될 경우 검색 조건에 포함되지 않아야 합니다.
    2. search_condition : 키워드 검색 조건의 분류 값 입니다. mission_id, mission_reward, mission_title 중 하나의 값이 전달됩니다. 빈 문자열이 전달될 경우 검색 조건에 포함되지 않아야 합니다.
    3. search_keyword : 키워드 검색 조건의 값 입니다. search_condition 이 빈 문자열이 아니면, 2자 이상이 전달됩니다.
    4. is_completed : true 이면 완료한 미션false 이면 진행 중인 미션 검색을 뜻 합니다.
    5. __page : 페이지 번호
    6. __page_size : 페이지 사이즈

Note

mission_id, mission_reward, mission_title 각각 미션 ID, 미션 보상, 미션 제목 을 뜻 합니다.

Important

is_completedtrue 일때 미션의 완료 상태라 함은 미션 state 가 completed 이고, 미션 보상 또한 수령한 경우 를 말합니다. 이처럼 게임 서버 API 작성이 어려우면, 반환하는 값의 상태에 대해 운영자와 협의하여 혼란을 방지하여야 합니다.

  • 성공인 경우 응답

    • 각 필드에 대한 설명은 미션 정보 검색 결과 응답 을 참조하세요.

    • 예시: ID 가 1인 캐릭터의 진행 중인 일반 미션 중 보상에 Sword 가 포함된 미션 조회

      • HTTP 요청

        GET /cs-api/v1/character/1/mission/record/normal?search_condition=mission_reward&search_keyword=Sword&is_completed=false&__page=1 __page_size=20
        
      • HTTP 응답

        HTTP/1.1 200 OK
        
        {
            "search_result": [
                {
                    "accepted_at": 1520852276,
                    "category": "character",
                    "current_step": 1,
                    "description": "[퀘스트 시작 장소]\n동북동의 취락\n",
                    "finished_at": 1520858216,
                    "goal_step": 1,
                    "id": 1311,
                    "received_reward_at": null,
                    "rewards": "Short sword x 1",
                    "state": "progressed",
                    "title": "안녕, 전사"
                },
                {
                    "accepted_at": 1519303496,
                    "category": "character",
                    "current_step": 1,
                    "description": "[퀘스트 시작 장소]\n관문의 마을\n",
                    "finished_at": 1519306376,
                    "goal_step": 1,
                    "id": 1218,
                    "received_reward_at": null,
                    "rewards": "Short sword x 1",
                    "state": "progressed",
                    "title": "취재를 위해서라면"
                },
                {
                    "accepted_at": 1518396176,
                    "category": "character",
                    "current_step": 1,
                    "description": "[퀘스트 시작 장소]\n동북동의 취락\n",
                    "finished_at": 1518402116,
                    "goal_step": 6,
                    "id": 1135,
                    "received_reward_at": null,
                    "rewards": "Short sword x 1\nWooden Shield x 1\nSilver Coin x 1\nMedium Healing Potion x 1\nLarge Healing Potion x 1\nGem x 1",
                    "state": "progressed",
                    "title": "과학의 힘"
                },
                {
                    "accepted_at": 1517810216,
                    "category": "character",
                    "current_step": 1,
                    "description": "[퀘스트 시작 장소]\n미궁 산맥의 입구\n",
                    "finished_at": 1517813936,
                    "goal_step": 1,
                    "id": 1103,
                    "received_reward_at": null,
                    "rewards": "Long sword x 1",
                    "state": "progressed",
                    "title": "평소와는 다른 모습으로"
                }
            ]
        }
        

GET /cs-api/v1/character/<character_id>/mission/status/achievement

  • 게임 서버에서 해야 하는 동작

    해당하는 캐릭터의 업적 미션 검색 결과를 JSON 으로 반환합니다.

    검색에 필요한 값들은 character_id 를 제외하고 URL 파라미터로 전달되며, 사용되는 파라미터는 아래의 5가지입니다. URL을 파싱하신 뒤에 이 파라미터들의 값을 참조해서 검색을 수행하시면 됩니다.

    1. category : 검색 분류 조건 입니다. GET /cs-api/v1/mission/category API 의 achievement 값 중 하나의 값이 전달됩니다. 빈 문자열이 전달될 경우 검색 조건에 포함되지 않아야 합니다.
    2. search_condition : 키워드 검색 조건의 분류 값 입니다. mission_id, mission_reward, mission_title 중 하나의 값이 전달됩니다. 빈 문자열이 전달될 경우 검색 조건에 포함되지 않아야 합니다.
    3. search_keyword : 키워드 검색 조건의 값 입니다. search_condition 이 빈 문자열이 아니면, 2자 이상이 전달됩니다.
    4. __page : 페이지 번호
    5. __page_size : 페이지 사이즈

Note

mission_id, mission_reward, mission_title 각각 미션 ID, 미션 보상, 미션 제목 을 뜻 합니다.

  • 성공인 경우 응답

    • 각 필드에 대한 설명은 미션 정보 검색 결과 응답 을 참조하세요.

    • 예시: ID 가 1인 캐릭터의 업적 미션 중 category 가 finish_skill 인 미션 조회

      • HTTP 요청

        GET cs-api/v1/character/1/mission/status/achievement?category=finish_skill&__page=1&__page_size=20
        
      • HTTP 응답

        HTTP/1.1 200 OK
        {
            "search_result": [
                {
                    "accepted_at": 1519004996,
                    "category": "finish_skill",
                    "current_step": 1,
                    "description": "[퀘스트 성공 조건]\n적에게 대미지를 입히는 스킬을 사용해봐\n",
                    "finished_at": 1519010276,
                    "goal_step": 1,
                    "id": 1168,
                    "received_reward_at": 1519017476,
                    "rewards": "Gold Bar x 1",
                    "state": "completed",
                    "title": "공격계 스킬을 사용해 보자"
                },
                {
                    "accepted_at": 1516690316,
                    "category": "finish_skill",
                    "current_step": 1,
                    "description": "[퀘스트 성공 조건]\n아군이 회복되는 스킬을 사용해봐\n",
                    "finished_at": 1516693796,
                    "goal_step": 1,
                    "id": 999,
                    "received_reward_at": 1516711796,
                    "rewards": "Wooden Shield x 1",
                    "state": "completed",
                    "title": "스킬로 HP를 회복시켜 보자"
                },
                {
                    "accepted_at": 1511397356,
                    "category": "finish_skill",
                    "current_step": 1,
                    "description": "[퀘스트 성공 조건]\n배리어가 막을 수 있는 공격에는 횟수 제한이 있어\n",
                    "finished_at": 1511399936,
                    "goal_step": 1,
                    "id": 579,
                    "received_reward_at": 1511401556,
                    "rewards": "Silver Coin x 1",
                    "state": "completed",
                    "title": "배리어를 쳐보자"
                },
                {
                    "accepted_at": 1511258876,
                    "category": "finish_skill",
                    "current_step": 1,
                    "description": "[퀘스트 성공 조건]\n스킬로 일정 시간 파워 업!\n",
                    "finished_at": 1511261576,
                    "goal_step": 1,
                    "id": 565,
                    "received_reward_at": 1511262356,
                    "rewards": "Wooden Shield x 1",
                    "state": "completed",
                    "title": "스킬로 파티를 강화시켜 보자"
                }
            ]
        }
        

미션 정보 검색 결과 응답

미션 정보 검색 결과 응답은 아래와 같은 조건을 만족하여야 합니다.

{
  "search_result": [
    {
      "id": "<미션 ID>",
      "category": "<미션 분류>",
      "title": "<미션 제목>",
      "rewards": "<개행문자(\n)로 줄 바꿈 한 보상정보 Text>",
      "description": "<미션 상세 내용>",
      "goal_step": <미션이 완료되는 마지막 단계>,
      "current_step": <현재 진행  미션 단계>,
      "accepted_at": <미션 수락 일시>,
      "finished_at": <미션 완료 일시>,
      "state": "<미션의 상태 - 'completed', 'progressed', 'failed'>" ,
      "received_reward_at": <미션 보상 수령일시>
    },
    ...
  ]
}
  • Response body는 JSON Object 형태로, search_result 키가 존재해야 함
  • 검색 결과는 search_result 안에 JSON Array 형태로 들어가있어야 함
  • 검색 결과(array)는 페이징 처리 가 된 상태이어야 함 (array 크기 <= __page_size)
  • 검색 결과(array) 안에는 조건에 맞는 미션의 데이타가 JSON Object 형태로 들어가있어야 함
  • 미션 정보 데이터(object)에는 위의 JSON Object 의 키를 전부 가지고 있어야 합니다.
  • 미션 정보 데이터(object)에는 해당 미션의 IDid 의 값으로 들어가있어야 함
  • 미션 정보 데이터(object)에는 해당 미션의 제목title 의 값으로 1 자 이상 들어가있어야 함
  • 미션 정보 데이터(object)에는 해당 미션이 완료되는 마지막 단계goal_step 의 값으로 1 이상 으로 들어가있어야 함
  • 미션 정보 데이터(object)에는 해당 미션의 현재 진행한 단계current_step 의 값으로 0 이상 에서 goal_step 이하로 들어가있어야 함
  • 미션 정보 데이터(object)에는 미션 수락일시accepted_at 의 값으로 timestamp 형태 로 들어가있어야 함
  • 미션 정보 데이터(object)에는 미션 완료일시finished_at 의 값으로 timestamp 형태 로 들어가있어야 함
  • 미션 정보 데이터(object)에는 미션 보상 수령일시received_reward_at 의 값으로 timestamp 형태 또는 null 이어야 함
  • category, rewards, description, state 는 게임 서버에서 전달한 값이 그대로 보여지게 됩니다

Note

state 는 ‘completed’, ‘progressed’, ‘failed’ 로 보내면 각각 ‘완료’, ‘진행 중’, ‘실패’ 로 보여집니다. 그외의 값은 게임 서버에서 보내주는 그대로 화면에 보여지게 됩니다.

  • 페이징 처리

    /cs-api/v1/character/1/mission/status/periodic?periodic_type=daily&mission_start_date=1521528944&__page=2&__page_size=20
    

    위의 예시는 2페이지째의 데이터를 요청하고 있고 한 페이지에 결과가 최대 20개까지만 출력되어야 합니다. 그러므로 검색 후에 요청받은 데이터의 범위를 계산해서 21~40번째 검색결과만을 잘라 보내주셔야 합니다. ( __page(1) * __page_size(20) = 20 , 20 + __page_size(20) = 40 )

    Caution

    페이징 처리는 결과 조회의 편의성과 더불어 너무 큰 사이즈의 response로 인해 디플로이 서비스에 지장을 주는 경우를 막기 위해 결정된 사항입니다. __page_size 를 초과한 개수의 검색 결과가 들어올 경우, 디플로이는 검색 결과를 출력하지 않고 에러 메시지를 띄울 것입니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

      {
        "search_result": [
          {
            "id": 1289,
            "category": "free",
            "title": "연대기"
            "rewards": "Gold Bar x 1",
            "description": "[퀘스트 시작 장소]\n마의산\n",
            "goal_step": 1,
            "current_step": 1,
            "accepted_at": 1520683616,
            "finished_at": 1520689856,
            "state": "failed",
            "received_reward_at": null
          },
          {
            "id": 1285,
            "category": "free",
            "title": "도전자의 동굴"
            "rewards": "Won Lottery x 1",
            "description": "[퀘스트 시작 장소]\n산마루 마을\n",
            "goal_step": 1,
            "current_step": 1,
            "accepted_at": 1520658716,
            "finished_at": 1520665196,
            "state": "completed",
            "received_reward_at": 1520665976,
          },
          {
            "id": 1283,
            "category": "free",
            "title": "쇠약 주의"
            "rewards": "Platemail x 1",
            "description": "[퀘스트 시작 장소]\n관문의 마을\n",
            "goal_step": 10,
            "current_step": 2,
            "accepted_at": 1520653616,
            "finished_at": 1520654336,
            "state": "progressed",
            "received_reward_at": null
          },
          {
            "id": 1267,
            "category": "free",
            "title": "시가전"
            "rewards": "Arcana x 1",
            "description": "[퀘스트 시작 장소]\n성도\n",
            "goal_step": 1,
            "current_step": 1,
            "accepted_at": 1520472716,
            "finished_at": 1520475776,
            "state": "progressed",
            "received_reward_at": null
          },
        ...
        ]
      }
      

15.7. 사용자 정의 기능 추가하기

디플로이 연동 API 에서는 아이펀 디플로이의 기본 기능을 활용하기 위해서 게임 서버에서 구현해야 하는 API 들을 설명했습니다. 그러나 게임에 따라서는 운영 과정에서 더욱 다양한 기능이 필요한 경우가 있습니다. 예를 들어, 어떤 게임에서 길드에 대한 고객 지원을 해야 하는 경우 운영툴은 길드에 대한 정보에 접근하고 데이터를 수정할 수 있어야 할 것입니다.

아이펀 디플로이는 이렇게 게임마다 특수한 API 들을 기본적으로 모두 포함하기는 어렵습니다. 대신 이런 API 들을 사용자 정의 기능이라는 이름으로 추가할 수 있는 방식을 제공합니다.

Tip

사용자 정의 기능은 단순히 유저 데이터, 길드 데이터처럼 데이터에 접근하기 위한 것 외에도, 게임 내에 젠 (gen) 속도를 조정한다거나, 공지 메시지를 뿌린다거나 하는 관리용으로도 활용하실 수 있습니다.

아이펀 디플로이는 먼저 게임 서버에서 지원하는 사용자 정의 기능의 API 리스트를 알아와서, 각 API 별로 대시보드 상에서 API 를 호출할 수 있는 폼을 만들어줍니다. 따라서 기능별 API 구현 외에 다음 3개의 Meta API 를 추가로 구현하셔야 합니다.

  1. 전체 사용자 정의 기능의 API 리스트를 불러오는 API (GET /cs-api/v1/custom_query)
  2. 특정 사용자 정의 기능의 API에 대해서 기술하는 API (GET /cs-api/v1/custom_query/<query_id>)
  3. 특정 사용자 정의 기능의 API를 실제 호출하는 API (<METHOD> /cs-api/v1/custom_query/run/<query_id>)

Note

사용자 정의 기능 API 부분은 개발자가 좀 더 손쉽게 연동할 수 있는 더 나은 방법을 지속해서 고민하고 있습니다. 이에 따라 차후에 연동 방식이 다소 변경될 수 있습니다.

15.7.1. 사용자 정의 기능 API 를 위한 Meta API

GET /cs-api/v1/custom_query

  • 게임 서버에서 해야 하는 동작

    게임 서버에서 지원하는 사용자 정의 기능의 API 리스트를 반환합니다. 이 때 각 사용자 정의 기능 API 의 1) 이름, 2) 호출 시 필요한 인자, 3) 결과로 반환하는 결과값들 에 대한 정보도 같이 포함되어야 합니다. 자세한 필드는 아래 예시를 참고해주세요.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: 캐릭터 레벨을 갱신하는 set_character_level 과 길드의 골드를 갱신하는 set_guild_gold 라는 사용자 정의 기능 API 두 개가 있을 때

      set_character_level 은 유저 계정 ID (account_id), 캐릭터 ID (character_id), 새 레벨 수치 (level) 이렇게 인자로 받고, 결과값으로는 캐릭터 ID (character_id) 와 바뀐 레벨 (level) 이렇게 두 개를 반환한다고 하겠습니다.

      set_guild_gold 는 길드의 고유 id (guild_uuid) 와 새 골드 수치 (gold) 이렇게 인자로 받고, result 라는 결과 하나만 받는다고 하겠습니다.

      HTTP/1.1 200 OK
      
      [
        {
          "id": "set_character_level",
          "method": "POST",
          "name": "SetCharacterLevel",
          "params": ["account_id", "character_id", "level"],
          "response_fields": ["character_id", "level"],
          "extra_data": {
            "params": {
              "level": {
                "dropdown_values": ["1", "2", "3", "4", "5"]
              }
            }
          }
        },
        {
          "id": "set_guild_gold",
          "method": "POST",
          "name": "SetGuildGold",
          "params": ["guild_uuid", "gold"],
          "response_fields": ["result"]
        },
        {
          "id": "set_character_level_by_name",
          "method": "POST",
          "name": "SetCharacterLevelByName",
          "params": ["character_name", "level"],
          "response_fields": ["character_id", "level"]
        }
      ]
      
    • id: 사용자 정의 기능 API 를 고유하게 식별하는 식별자입니다.

    • method: 사용자 정의 기능 API 의 HTTP method 를 지정합니다.

    • name: 아이펀 디플로이 사용자 정의 기능 API 페이지에서 해당 API 가 표시될 때의 이름을 지정합니다.

    • params: 이 API 가 취하는 인자들의 이름을 배열로 반환합니다.

    • response_fields: param 과 유사한데, 결과값으로 반환되는 필드들의 이름을 배열로 반환합니다.

위에서 설명한 항목 외에, 각 사용자 정의 기능은 extra_data 라는 추가 정보를 가질 수 있습니다. 위의 예제를 보시면 set_character_level 외의 사용자 정의 기능들의 정보들은 extra_data 를 포함하지 않는 것을 보실 수 있습니다. extra_data 는 필수로 설정해야 하는 값이 아니기에, 추가 설정이 필요하지 않은 경우 응답에 포함하지 않으셔도 됩니다. extra_data 는 API의 인자/결과값 이름 외의 설정들을 포함합니다. 가질 수 있는 프로퍼티들은 다음과 같습니다.

  • params: API의 인자 값에 대한 추가 정보입니다. JSON object 여야 합니다. param 이 가질 수 있는 프로퍼티들은 다음과 같습니다.
    • <param_name>: 어떠한 인자에 대한 추가 정보인지를 나타냅니다. API 가 취하는 인자들의 이름 중 하나여야만 합니다. 가질 수 있는 프로퍼티들은 다음과 같습니다.
      • dropdown_values: 이 사용자 정의 기능 실행 시, 입력 UI를 셀렉트박스로 설정할 경우 선택 가능한 값들의 목록입니다. JSON array 여야 합니다.

예제의 사용자 정의 기능 정보들 중, set_character_level 의 정보는 다음과 같은 extra_data 정보를 가지고 있습니다.

"extra_data": {
  "params": {
    "level": {
      "dropdown_values": ["1", "2", "3", "4", "5"]
    }
  }
}

set_character_level의 extra_data 는 인자 중 “level” 인자에 대한 추가 설정을 포함하고 있으며, 해당 설정 내의 “dropdown_values” 의 값이 [“1”, “2”, “3”, “4”, “5”] 이므로, 사용자 정의 기능 실행 시 입력 UI를 셀렉트박스로 설정할 경우 선택 가능한 값은 “1”, “2”, “3”, “4”, “5” 중 하나가 됩니다.

Note

2017-09-12 현재, extra_data 는 사용자 정의 기능 실행 시 입력 UI를 셀렉트 박스 형식으로 보여줄 경우, 선택 가능한 값들을 설정하는 용도로만 사용됩니다.

GET /cs-api/v1/custom_query/<query_id>

  • 게임 서버에서 해야 하는 동작

    게임 서버에서 지원하는 사용자 정의 기능 API 하나의 정보를 반환합니다. GET /cs-api/v1/custom_query 와 유사하나 리스트가 아닌 한 API 의 정보만을 반환하는 것이 다릅니다.

  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: GET /cs-api/v1/custom_query/set_character_level

      HTTP/1.1 200 OK
      
      {
        "id": "set_character_level",
        "method": "POST",
        "name": "SetCharacterLevel",
        "params": ["account_id", "character_id", "level"],
        "response_fields": ["character_id", "level"],
        "extra_data": {
          "params": {
            "level": {
              "dropdown_values": ["1", "2", "3", "4", "5"]
            }
          }
        }
      }
      

    각 필드들은 GET /cs-api/v1/custom_query 에서와 동일합니다.

15.7.2. 사용자 정의 기능 API 호출하기

아이펀 디플로이에서 게임 서버가 정의해둔 사용자 정의 기능을 사용하는 경우 게임 서버 측에 요청하는 url은 다음과 같습니다.

<METHOD> /cs-api/v1/custom_query/run/<query_id>

  • 게임 서버에서 해야 하는 동작

<METHOD> 는 사용자 정의 기능 API 조회 기능 을 통해 얻어온 http method입니다. 게임 서버 측의 api 서버에서는 이에 해당하는 요청을 받으면 <query_id> 에 해당하는 사용자 정의 기능 API 를 실행해야 합니다. 해당 API 가 받아야 하는 파라미터 리스트는 파라미터 이름을 key 로 하고 파라미터 값을 value 로 하는 HTTP body 에 JSON 형태로 제공됩니다.

Note

이 때 파라미터의 값은 항상 문자열 형태로 전송됩니다. 게임 서버는 이 문자열을 적절한 타입으로 변환해서 쓰셔야 합니다.

예를 들어 위의 set_character_level 의 경우에는 account_id, character_id, level 을 인자로 받는다고 가정했기 때문에 다음과 같은 HTTP body 가 전송됩니다.

웅답은 위의 필드들을 포함하는 JSON object 1개, 혹은 위의 필드들을 포함하는 JSON object 의 array 둘 중 하나의 형태여야 합니다.

Note

아이펀 디플로이 대시보드의 사용자 정의 기능 메뉴에서 set_character_level API 를 선택하면 아이펀 디플로이가 필요하다고 한 파라미터들을 자동으로 form 으로 생성해줍니다. 그 form 에 값을 채워서 전송하게 되면 아래와 같은 파라미터 값들을 전송할 수 있게 됩니다.

Note

사용자 정의 기능 설정하기 에서 각 입력 인자별로 설정한 출력 형식 설정에 따라, 각 인자는 다음 형태로 전달됩니다.

액션 설정하기사용자 정의 기능 파라미터 설정 에서 파라미터를 자동으로 입력하게 했을 때의 입력 값도 같은 형태여야 합니다. 만약 형태가 달라 자동으로 입력하지 못할 경우에는 경고 문구를 출력하며 값을 입력하지 않습니다. * 단일 라인 텍스트 / 다중 라인 텍스트 : 입력한 문자열 그대로 전달 * 일시 : Unix timestamp 값을 가지는 문자열( ex: “1504839884” ) 형태로 전달 * 체크박스 : 체크되었다면 “True”, 체크되지 않았다면 “False” 전달 * 셀렉트박스 : 모든 사용자 정의 기능 정보 목록특정 사용자 정의 기능 정보 에 포함된 extra_data 내의, dropdown_values 의 값 중 하나

Warning

extra_data 에서 특정 인자의 dropdown_values 를 지정하셨더라도, 운영 툴 사용자는 해당 사용자 정의 기능 실행 시 단일 라인 텍스트 등 다른 형태의 입력 UI를 선택할 수 있으며, dropdown_values 외의 값을 인자로 넘길 수 있습니다. 따라서 해당 사용자 정의 기능의 인자가 특정 값들만을 취해야 하는 경우, dropdown_values 의 설정 여부와 관계 없이 해당 인자의 값을 확인해야만 합니다.

{
   "account_id": "K1234",
   "character_id": "de305d54-75b4-431b-adb2-eb6b9e546014",
   "level": "20"
}
  • 성공인 경우 응답

    • HTTP 상태값: 200 OK

    • HTTP body

    • 예시: POST /cs-api/v1/custom_query/run/set_character_level

      HTTP/1.1 200 OK
      
      {
        "character_id": "de305d54-75b4-431b-adb2-eb6b9e546014",
        "level": "20"
      }
      
      혹은
      
      [
        {
          "character_id": "de305d54-75b4-431b-adb2-eb6b9e546014",
          "level": "20"
        }
      ]
      

    set_character_levelcharacter_idlevel 을 반환한다고 가정했기 때문에, 게임 서버는 이 필드들로 이루어진 JSON object 를 결과로 반환해야 합니다.

    위의 예제에서는 character_id 를 지정하는 쿼리의 특성 상 둘 이상의 결과값이 있을 수 없지만, 응답이 둘 이상 있을 수 있는 쿼리의 경우에는 JSON object 둘 이상을 포함하는 array 도 가능합니다. 예를 들어 게임에서 여러 캐릭터가 동일한 이름을 가지는 것을 허용할 때, 특정 이름을 가진 캐릭터의 레벨을 업데이트하는 set_character_level_by_name 이라는 커스텀 쿼리의 응답은 다음과 같을 수 있습니다.

    HTTP/1.1 200 OK
    [
      {
        "character_id": "de305d54-75b4-431b-adb2-eb6b9e546014",
        "level": "20"
      },
      {
        "character_id": "ca6f78ca-50da-11e7-bd47-080027971dde",
        "level": "20"
      },
      {
        "character_id": "d1a8d50a-50da-11e7-bd47-080027971dde",
        "level": "20"
      }
    ]
    

15.8. 손쉬운 API 구현을 위해 제공되는 library

위의 API 들은 REST 기반의 API 들이기 때문에, 게임 서버가 어떤 프로그래밍 언어로 만들어져있든 해당 REST API 를 구현하는 것만으로 아이펀 디플로이의 기능들을 쓸 수 있음을 의미합니다.

그러나 이런 구현 자체가 시간을 소모하는 귀찮은 작업일 수 있고, C++ 같이 HTTP 친화적이지 않은 프로그래밍 언어의 경우는 별도로 REST API 용 소켓을 열고 이에 따라 구현을 해주어야 하는 어려움이 있을 수 있습니다. 아이펀 디플로이는 이런 귀찮음 혹은 어려움을 해결하기 위해서 게임 서버 개발에 많이 사용되는 언어들에 대해서 소스 수준의 라이브러리를 제공합니다. 이 라이브러리를 이용하면 각 API 구현을 위해 소켓 처리나 URL 파싱 같은 작업을 할 필요 없이, API 별 핸들러를 붙이는 간단한 작업만으로 필요한 API 를 구현하실 수 있습니다.

현재는 PHP helper library 를 제공합니다. 사용을 원하시는 경우 Deploy Support 로 메일 주시면 발송해드리겠습니다. 또한, 저희 아이펀 엔진 내에도 deploy 연동을 위한 컴포넌트가 포함되어 있습니다. 자세한 사항은 아이펀 엔진 문서 내 해당 항목 를 참고해 주시기 바랍니다.

Note

앞서 설명해 드린 것처럼, 위의 언어 리스트는 아이펀 디플로이에서 사용 가능한 언어를 제한하는 것이 아니라, 편의를 위해서 저희가 제공하는 라이브러리의 언어를 나타낼 뿐입니다. 어떤 언어든 API 만 구현하면 해당 기능들을 쓰시는 데는 문제가 없습니다. 만일 위의 언어 외에 추가적인 프로그래밍 언어 지원 요청이 있는 경우 Deploy Support 로 연락해주시면 검토 후 지원하도록 노력하겠습니다.

Tip

Helper library 는 추후 Github를 통해서 배포될 예정입니다.

15.9. API 연동 상황 확인하기

아래 그림에 표시된 버튼을 클릭 시 보실 수 있는 세부 설정에서 디플로이 연동 API가 잘 연동되어 있는지를 확인할 수 있는 기능을 제공하고 있습니다.

_images/deployment-mgmt-10.png

사이드 바에서 API 연동 상태 메뉴를 클릭하면 다음과 같은 화면이 나옵니다.

_images/deployment-mgmt-06.png

그림: API 연동에 따른 기능별 활성화 여부 확인

이 화면은 아이펀 디플로이가 제공하는 기능별로 그룹핑해서, 그 기능을 위한 필요 API 들이 잘 연동되었는지를 표시합니다. 녹색은 필요 API 들이 모두 연동되어 해당 기능이 정상 동작하는 것을 의미하며, 빨간색은 연동에 문제가 있는 경우를 표시합니다.

만일 특정 기능을 클릭하면 아래 그림처럼 그 기능에 필요한 API 들 각각의 연동 상황을 볼 수 있습니다. 아래는 아이펀 디플로이의 캠페인 관리 기능 을 위해서 GET /cs-api/v1/campaign/type, POST /cs-api/v1/campaign/<type>/<id>/end, POST /cs-api/v1/campaign/<type>/<id>/begin 3개의 API 가 필요하고 이들이 잘 연동되었음을 보여줍니다.

_images/deployment-mgmt-06-02.png

그림: API 연동에 따른 기능별 활성화 여부 확인

Note

API 이름이 출력될 때는 /cs-api/v1 의 prefix 는 제외된 상태로 표시되어 있지만, 게임 서버에서는 이 prefix 를 포함해서 API URL 을 정해야 함을 기억해주세요.