Overview
com.111percent.ranking
Ranking 기능을 제공하는 패키지입니다.
정책
- 협동 랭킹은 자신의 랭킹 정보를 제공하지 않습니다.
- 랭킹 갱신은 실시간
스코어는 최대 100만점까지 저장 가능- 운영툴에서 랭킹 생성시 설정가능
- 스코어 동점일 경우
- 가장 먼저 기록을 달성한 유저
- 랭킹의 경우 각 프로젝트에서 랭킹보드를 구성하기 위하여 저장하는 etc의 어떤 가공도 진행하지 않습니다. 또한, 이미 등록된 etc 데이터를 스코어 갱신 이외에 업데이트 하는 기능은 제공하지 않습니다.
- 랭킹은 랭킹보드 구성하는 용도로만 사용 부탁드리겠습니다.
랭킹 서비스 사용 가이드
운영툴 제공 기능
-
- 랭킹 모드 ↔ ID 맵핑
public enum RankMode { Battle = "RANK_-cfNMU856XBeauiZxBtvC", Speed = "RANK_I41XGyh6sa1bl_WJF76Zd" }
- 랭킹 모드 ↔ ID 맵핑
랭킹 삭제 (운영툴에서만 제공됩니다.)
더미 랭킹 추가(Dev / QA 환경에서만 제공됩니다.)
내부 Flow
랭킹 등록 (운영툴)
sequenceDiagram
actor O as Operator
participant OS as 운영툴
participant RS as RankServer
O ->> OS: 프로젝트 > 랭킹관리 > 등록
OS ->> RS: Rank Initialize<br>[rankId,type]
OS ->> O: Response<br>[rankId]
랭킹 스코어 등록
sequenceDiagram
actor C as Client
participant RC as Provider
participant RS as RankServer
C ->> RC: Initialize<br>[rankId]
C ->> RC: UpdateScore<br>[pId,score,userInfo]
RC ->> RS: UpdateScore<br>[pId,score,userInfo]
사용 가이드
- 랭킹 등록 및 업데이트
- 랭킹을 랭킹 서버에 등록합니다. (운영툴에 등록된 정렬방식에 따라 스코어 갱신)
- UpdateRank(
int score
,string etc = “”
)- score : 기록 될 점수
- etc : 게임에서 사용하고 있는 클래스를 json화 한 string 값, 없는 경우 빈 값 넘겨주면 됩니다.
- UpdateRankWithName(int score, string name, string etc = "")
- score : 기록 될 점수
- name: 운영툴에 표시되는 닉네임
- etc : 게임에서 사용하고 있는 클래스를 json화 한 string 값, 없는 경우 빈 값 넘겨주면 됩니다.
- 협동 랭킹 등록 및 업데이트
- 협동 모드에서 랭킹을 등록합니다.
- UpdateRankWithOthers(
int score
,string etc = ""
,params string[] accountIds
)- score : 기록 될 점수
- etc : 게임에서 사용하고 있는 클래스를 json화 한 string 값, 없는 경우 빈 값 넘겨주면 됩니다.
- accountIds: 협동을 같이 진행한 플레이어의 accountId
- 나의 accountId는 자동으로 주입되니 제외해주세요.
- UpdateCoopRankWithNames(int score, string name, List
coopRankList, string etc = "") score : 기록 될 점수
name: 랭킹을 등록하는 유저의 닉네임 (운영툴에 협동을 진행한 모든 유저의 닉네임이 같이 표시됩니다.)
- ex) nickname1_nickname_2_nickname3
- accountId를 기준으로 소팅된 결과로 운영툴에 닉네임이 표시 됩니다.
coopRankList: 같이 협동을 진행한 유저의 대한 정보를 담은 구조체 리스트 입니다.
public readonly struct CoopRankDto { public string accountId { get; init; } public string name { get; init; } }
etc : 게임에서 사용하고 있는 클래스를 json화 한 string 값, 없는 경우 빈 값 넘겨주면 됩니다.
- 랭킹 조회
- 내 데이터와 내 주변의 랭킹 데이터를 받아옵니다.
- 협동 랭킹의 경우는 내 랭킹과 주변랭킹 정보를 제공하지 않습니다.
- GetRank(
int nearCount
)- nearCount : 내 등 수 ±nearCount만큼 RankData를 응답에 받아옵니다.
- GetRankResult를 반환합니다.
- 내 데이터와 내 주변의 랭킹 데이터를 받아옵니다.
- 랭킹 리스트 조회 ⇒ return RankData[]
- 랭킹을 리스트로 가져옵니다.
- GetRankList(
int limit
,int page
)limit : 받아 올 갯수
page : 받아 올 페이지
ex) limit : 10, page : 2 ⇒ 11~20등까지 랭킹 받아옴 limit : 100, page : 4 ⇒ 301~400등까지 랭킹 받아옴
GetRankListResult를 반환합니다.
- 100만 이상의 랭크를 사용하면서, 동점자 처리가 필요한 경우의 랭킹 리스트 조회
- 랭킹을 1위부터 limit까지 리스트로 가져옵니다.
- GetTopRankList(
ìnt limit
) [1.0.8 버전에 추가된 신규 기능]- limit : 받아 올 갯수
- GetRankListResult를 반환합니다.
- 사용 예시 : 랭커들 리스트 보여줄 때
위에 말씀드린 클래스들은 아래와 같습니다.
사용하시게 될 Dto와 Result 데이터들입니다.
namespace Percent.Ranking
{
public class RankData
{
public string pId { get; set; }
public int rank { get; set; }
public int score { get; set; }
public long createdAt { get; set; }
public string etc { get; set; } // json 형식으로 주고 받는 string 값
public RankData[] nearRankers { get; set; } // GetRank의 nearCount로 받아온 RankData
}
// ----------- API 응답 후 반환 값 -----------------
public class GetRankResult : RankResult
{
public RankData result;
}
public class GetRankListResult : RankResult
{
public RankData[] result;
}
public class RankResult
{
public int code { get; set; }
public bool IsSuccess => code == RankingResultCode.SUCCESS;
}
}
Important
- Update 함수들은 점수를 기반으로 운영툴 데이터에 Update 됩니다.
- 갱신 할 점수가 운영툴 데이터에 등록된 점수보다 높을 경우에만 etc를 포함한 데이터가 갱신됩니다.
- 호출되는 점수가 낮거나 동일하면 데이터 갱신은 이루어지지 않습니다.
- 위와 같은 이유로 랭킹 등록 시마다 etc 데이터 갱신은 불분명할 수 있으니 해당 방법은 지양해주세요.
- 모든 API는 null을 반환하지 않고, Dto에 에러코드를 포함하여 사용자가 에러코드를 통해 후처리할 수 있도록 하였습니다.
- 주요 에러
- HTTP_EXCEPTION(400) : 통신 에러로 인한 에러 코드
- JSON_DATA_EXCEPTION(1000) : json 파싱 에러로 인한 에러 코드, 실제 들어오는 데이터를 확인해야 합니다.
- 주요 에러
예제
using Percent.Ranking;
// 운영툴 API에 생성된 '랭킹명'을 가져오는 클래스입니다.
// 이 클래스는 패키지에 포함되지 않습니다.
public class RankingName {
public static readonly string Normal = "Normal";
public static readonly string COOP = "COOP";
}
public class RankingSample {
IRankingClient _normalRanking;
IRankingClient _coopRanking;
public async void Initialize()
{
// accessToken을 사용하기 때문에 Login을 먼저 진행하여 토큰 취득 후 호출해주세요.
var initializeResult = RankingClientFactory.RankingInitializeAsync();
if (initializeResult.IsSuccess)
{
_normalRanking = RankingClientFactory.CreateByName(RankingName.Normal);
_coopRanking = RankingClientFactory.CreateByName(RankingName.Coop);
}
else
{
if (initializeResult.code == RankingResultCode.JSON_DATA_EXCEPTION)
{
Debug.Log("json 데이터 파싱 오류.");
}
else if (initializeResult.code == RankingResultCode.HTTP_EXCEPTION)
{
Debug.Log("통신 에러");
}
}
}
// 랭킹을 업데이트 합니다.
// 운영툴 데이터보다 점수가 높을 경우에만 갱신됩니다. etc 데이터도 동일합니다.
public async void UpdateRank(int score, string etc = "") // etc는 json 형식을 사용합니다.
{
var updateRankResult = await _normalRanking.UpdateRank(score, etc);
if (updateRankResult)
{
Debug.Log("Update complete.");
}
else
{
Debug.Log("Update fail...");
}
}
// pId를 받아와 업데이트 합니다. (COOP)
// 이 메소드는 마스터만 호출되어야 합니다.
// 운영툴 데이터보다 점수가 높을 경우에만 갱신됩니다. etc 데이터도 동일합니다.
// etc는 json 형식을 사용합니다.
public async void UpdateRankWithOthers(int score, string etc = "",
params string[] accountIds)
{
var updateRankResult = await _coopRanking.UpdateRankWithOthers(score, etc, accountIds);
if (updateRankResult)
{
Debug.Log("Update complete.");
}
else
{
Debug.Log("Update fail...");
}
}
// 랭킹을 받아옵니다.
public async void GetRank(int nearCount)
{
var getRankResult = await _normalRanking.GetRank(nearCount);
if (getRankResult.IsSuccess)
{
var data = getRankResult.data;
Debug.Log("Update complete.");
}
else
{
if (getRankResult.code == RankResultCode.JSON_DATA_EXCEPTION)
{
Debug.Log("json 데이터 파싱 에러");
}
else if (getRankResult.code == RankResult.Code.HTTP_EXCEPTION)
{
Debug.Log("통신 에러");
}
Debug.Log("Update fail...");
}
}
// 랭킹 리스트를 받아옵니다.
public async void GetRankList(int limit, int page)
{
var getRankListResult = await _normalRanking.GetRankList(limit, page);
if (getRankListResult.IsSuccess)
{
var data = getRankListResult.data;
Debug.Log("Update complete.");
}
else
{
if (getRankListResult.code == RankResultCode.JSON_DATA_EXCEPTION)
{
Debug.Log("json 데이터 파싱 에러");
}
else if (getRankListResult.code == RankResult.Code.HTTP_EXCEPTION)
{
Debug.Log("통신 에러");
}
Debug.Log("Update fail...");
}
}
// 랭킹 리스트를 받아옵니다.
public async void GetTopRankList(int limit)
{
var getTopRankListResult = await _normalRanking.GetTopRankList(limit);
if (getTopRankListResult.IsSuccess)
{
var data = getTopRankListResult.data;
Debug.Log("Update complete.");
}
else
{
if (getTopRankListResult.code == RankResultCode.JSON_DATA_EXCEPTION)
{
Debug.Log("json 데이터 파싱 에러");
}
else if (getTopRankListResult.code == RankResult.Code.HTTP_EXCEPTION)
{
Debug.Log("통신 에러");
}
Debug.Log("Update fail...");
}
}
}
에러코드
Error | Error Code | Description |
---|---|---|
FATAL | -1 | unknown |
SUCCESS | 0 | 성공 |
INVALID_TOKEN | 100 | 토큰을 갱신해야 하는 경우 |
NOT_FOUND_RANK | 200 | rankID가 없는 경우 |
NOT_FOUND_PID | 210 | 랭킹 조회했을 때 해당하는 PID가 없는 경우 |
INVALID_ENV | 300 | 랭킹의 환경(env, gameID) 설정이 유효하지 않습니다. |
HTTP_EXCEPTION | 400 | 성공 |
JsonSerializationException | ? | 전달된 etc의 데이터가 잘못된 Json 포맷입니다. |