본문 바로가기
  • CobsLab upgrades your company value by AI technology
HTML

리그오브레전드(LOL) 게임정보 불러오기(Riot Apis)

by 콥스랩 2023. 6. 13.

 

안녕하세요 여러분 콥스랩 기술블로그입니다!

 

여러분들은 혹시 여가시간에 무얼 하며 보내시나요?

저같은 경우엔 보통 운동이나 게임, 혹은 친구들을 만나서 식사(를 빙자한음주)를 하며 시간을 보내는데요😆, 그 중 게임에 대한 이야기를 조금 해보려고합니다.

 

저는 최근에 리그오브레전드(이하 롤)라는 게임을 다시 시작했습니다. 아마 여러분들 중에 꽤 많은 분들이 이 게임을 하실테고, 하시지않더라도 게임 이름 자체를 안들어본 분들은 없을 거라고 예상합니다.

 

롤을 해보신 분들은 아시겠지만, 롤을 하다보면 가장 많이 이용하는 사이트가 하나 있죠?

 

바로 롤 전적 검색 사이트인데요. 내 전적을 검색한다든지 혹은 내 친구의 전적을 검색한다든지 아니면 내가 좋아하는 프로게이머의 전적을 검색할 때 자주 사용하죠.

 

그렇다면 이러한 전적 검색사이트들은 어떻게 플레이어의 전적을 갖고 오는 것일까요? 나아가 우리도 이러한 전적 검색 사이트를 만들어볼 수 있을까요? 그래서 오늘 준비한 내용은 리그오브레전드 게임정보 불러오기입니다. 다음은 오늘의 목차입니다.

 

  1. Riot Developer - APIS 둘러보기
  2. API Key 발급받기
  3. 정보 불러와보기
  4. 전적 검색 해보기

 

 

1. Riot Developer 둘러보기

 

1) Riot Developer란?

Riot Developer 사이트는 Riot Games가 제공하는 개발자 포털입니다. Riot Games는 앞서 설명한 롤 등의 게임을 개발하고 운영하는 회사로, 본 사이트를 통해 개발자들이 Riot Games의 게임 API와 관련된 도구, 문서, 리소스에 접근할 수 있습니다.

Riot Games API는 Riot Games의 게임 데이터 및 기능에 액세스할 수 있는 공식적인 인터페이스입니다. 이 API를 통해 개발자들은 League of Legends의 게임 데이터, 유저 정보, 매치 히스토리, 리그 정보 등 다양한 데이터를 가져오고 활용할 수 있습니다. API를 사용하여 게임 관련 앱, 웹사이트, 도구 등을 개발할 수 있습니다.

Riot Developer 사이트에서는 다음과 같은 기능과 정보를 제공합니다:

 


  1. API 문서: Riot Games API의 상세한 문서가 제공됩니다. API의 엔드포인트, 요청 및 응답 형식, 인증 방법 등에 대한 설명과 예제를 확인할 수 있습니다.
  2. API 키 발급: Riot Games API를 사용하기 위해서는 개발자 계정을 생성하고 API 키를 발급받아야 합니다. Riot Developer 사이트에서 개발자 계정을 만들고, 프로젝트를 등록하고 API 키를 생성할 수 있습니다.
  3. 도구 및 SDK: Riot Games API와 통합할 수 있는 도구, 라이브러리 및 SDK가 제공됩니다. 이러한 도구들은 개발 프로세스를 단순화하고 API와의 상호 작용을 용이하게 해줍니다.
  4. 토론 및 커뮤니티: Riot Games 개발자 커뮤니티에 참여할 수 있는 공간이 제공됩니다. 다른 개발자들과 의견을 공유하고 질문을 할 수 있으며, Riot Games 개발자와 다른 개발자들 간의 소통이 가능합니다.

 


이 중 우리가 둘러볼 부분은 API 문서입니다

 

Riot Developer Portal

이 웹 사이트는 쿠키와 같은 데이터를 저장하여 필수 사이트 기능은 물론 마케팅, 개인화 및 분석을 가능하게합니다. 언제든지 설정을 변경하거나 기본 설정을 그대로 사용할 수 있습니다. 필수 쿠키만 계속 사용하려면 이 배너를 닫을 수 있습니다. 개인정보 공지 저장 환경 설정 마케팅 개인화 분석 저장 모두 동의 모두 거부 Stats straight from the source Active games, match history, ranked statistics, and much more at your fingertips. Sign Up N...

developer.riotgames.com

2) API 문서 둘러보기

위 링크에 접속하신 후, 상단에 있는 APIS를 클릭하게되면 아래와 같은 화면이 나옵니다.

좌측 메뉴를 보시면 여러가지 API문서들이 존재하는데요, 롤뿐만 아니라 발로란트나 TFT 등 라이엇 게임즈에서 운영중인 게임들에 대한 정보가 존재합니다.

이 중 롤과 관련된 몇가지 문서만 소개해드리겠습니다.


  1. account-v1: 이 API는 사용자 계정에 대한 정보와 관련된 엔드포인트를 제공합니다. 사용자 계정에 대한 정보, 계정 ID, PUUID, 계정명 등을 확인할 수 있습니다.
  2. champion-mastery-v4: 이 API는 플레이어의 챔피언 숙련도에 관련된 정보를 제공합니다. 챔피언 숙련도 점수, 최고 숙련도 등을 조회할 수 있습니다.
  3. league-v4: 이 API는 리그 정보와 관련된 엔드포인트를 제공합니다. 리그, 리그 항목, 리그 참가자 등의 정보를 확인할 수 있습니다.
  4. match-v5: 이 API는 게임 매치 정보에 관련된 엔드포인트를 제공합니다. 매치 정보, 플레이어의 게임 기록, 팀 정보, 승패 여부 등을 조회할 수 있습니다.
  5. spectator-v4: 이 API는 실시간 게임 관전과 관련된 엔드포인트를 제공합니다. 현재 진행 중인 게임 정보, 참가자 정보, 팀 구성 등을 확인할 수 있습니다.
  6. summoner-v4: 이 API는 소환사 정보와 관련된 엔드포인트를 제공합니다. 소환사의 프로필, 랭크 정보, 매치 기록 등을 조회할 수 있습니다.

2. API 키 발급받기

본격적으로 API 문서들을 사용하기 위해서는 라이엇에서 제공하는 API 키를 발급받아야합니다.

따로 어떠한 조치를 취하지 않으셔도 되며, 그냥 로그인을 하시면됩니다.

로그인 이후에는 다음의 그림과 같이 내 API Key를 확인할 수 있습니다.

 

DEVELOPMENT API KEY라고 되어 있는 항목에 보안 처리된 부분을 복사해서 사용하시면 됩니다.

되게 간단하죠? 이후에 API Key 사용 권한이 만료가된다면 사진 기준 최하단에 있는 REGENERATE API KEY를 클릭하시면됩니다.

 

3. 정보 불러와보기

자 그러면 본격적으로 코드를 짜볼까요?

그 전에 우선 SUMMONER - V4문서를 살펴보도록 하겠습니다.

리턴값을 보시면 소환사DTO를 리턴해주는 것을 알 수 있습니다.

또한 본 소환사DTO를 불러올 수 있는 방법은 아래와 같이 여러가지가 있는데요.

보통 우리는 게임 닉네임을 검색해서 정보를 받아오기 때문에

/lol/summoner/v4/summoners/by-name/{summonerName}”를 이용하도록 하겠습니다.

 

 

 

  1. summonerName : 우리가 검색할 게임 닉네임.
  2. INCLUDE API KEY : api key를 쿼리 param으로 보낼건지, header param으로 보낼건지
  3. EXECUTE REQUEST : 한 번 실행해보고 그 결과를 볼 수 있음.

 

저는 e_sports에서 가장 인기가 많은 페이커 선수의 게임 아이디를 검색해보겠습니다.

 

이런 결과를 볼 수 있습니다.

위 summoner DTO에 대한 설명 그대로 데이터가 리턴되는 것을 보실 수 있습니다.

여기서 우리가 나중에 사용할 값은 바로 “puuid입니다. puuid는 플레이어를 고유하게 식별하는 값으로, 플레이어의 계정과 연결된 고유한 식별자역할을 하는 아이디입니다.

위 내용을 그럼 직접 코드로 구현해보겠습니다.

const APIKEY = "여러분들이 발급받은 api키";
const headers = {   
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
    "Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
    "Accept-Charset": "application/x-www-form-urlencoded; charset=UTF-8",
    "Origin": "https://developer.riotgames.com",
    "X-Riot-Token": APIKEY
};
 

우선 우리가 데이터 통신을 할 때마다 반복적으로 사용하게될 APIKEY와 headers를 코드 최 상단에 적어주도록 합니다.

그 다음 게임 내 id를 파라미터로 전달하면 summoner DTO가 리턴되는 함수입니다.

async function getPuuid (id){
    return fetch(`https://kr.api.riotgames.com/lol/summoner/v4/summoners/by-name/${id}`,{
        method: 'GET',
        headers: headers
    })
    .then((res) => res.json())
}

async function run(){
    let data = await getPuuid('Hide on bush');
    console.log(data)   
}
run()
 

run함수를 실행하여 getPuuid란 함수에 “Hide on bush”를 파라미터로 전달한 리턴값을 console해보면 다음과 같습니다.

앞서 우리가 라이엇 디벨로퍼 홈페이지에서 테스트 실행해본 것과 결과가 같습니다.

 

4. 전적 검색해보기

자, 지금까지 API 문서를 어떤 식으로 활용할 수 있는지 알아봤는데요. 이런 식으로 여러분들도 API 문서들을 직접 살펴본 후, 어떤 데이터를 전달해야하는지 그리고 어떤 데이터가 응답으로 오는지를 파악한 후 코드로 작성해보실 수 있습니다.

사실 우리가 궁금한 건 바로 전적 검색이죠?

여러분들의 시간을 절약해드리기 위해, 제가 따로 필요한 api들만 이용하여 작성한 코드를 한 번 같이 살펴보겠습니다.

 

1) 내가 했던 게임 매치의 id값 갖고오기

MATCH-V5에 있는 아래의 API를 이용하면 list of match ids를 갖고올 수 있습니다.

match ids란 내가 했던 매치의 고유값이며, 이를 활용하여 이후 해당 매치의 결과를 알아볼 수 있습니다.

그렇다면 궁금증이 생깁니다. 왜 id가 아니라 ids라고 복수형의 이름을 지정했을까요?

그 이유는 다음과 같습니다.

보시는 것과 같이 내가 보내는 파라미터에 따라 매치 필터링이 가능하기 때문입니다. 따라서 두 개 이상의 값이 나올 수도 있습니다.

저는 일단 type = ranked, start = 0, cont = 10이라는 파라미터를 보내어 데이터를 갖고올건데요.

type은 게임의 형식 즉 일반게임인지, 랭크게임인지, 튜토리얼인지, 칼바람인지 등을 필터링하는 것이고, start는 최근 몇 번째부터 (0번 인덱스니까 1번째 게임이겠죠?) count 몇 개의 게임을 갖고올 건지를 정하는 것입니다.

따라서 제가 보낸 쿼리를 해석하자면,” ‘JUr2nbiY5AM1uNc-mEgenddbyasr84e0UsDC3FFnUmzJmpUdtlJ-GQr0VUcVbTSdzaTZMOkWuenicg’라는 puuid를 갖고 있는 게임 매치를 갖고 올건데, rank게임만 갖고올 것이고, 최근 1번째 게임부터 10개의 게임을 갖고올 것이다.”라는 의미입니다.

위의 puuid는 조금 전 페이커 선수의 puuid였습니다. 따라서 다음과 같은 코드진행이 가능합니다.

async function fetchGameListData(puuid,start,count) {
    const response = await fetch(`https://asia.api.riotgames.com/lol/match/v5/matches/by-puuid/${puuid}/ids?type=ranked&start=${start}&count=${count}`, {
        method: 'GET',
        headers: headers
    });
    if (!response.ok) {
        throw new Error('Network response was not ok');
    }
    const data = await response.json();
    return data;
}

async function run(){
    let {puuid} = await getPuuid('Hide on bush');
    let matchIds = await fetchGameListData(puuid,0,10);
    console.log(matchIds) 
}
run()
 

matchIds를 console해보면

 

이런 식으로 매치 id들을 불러옵니다.

그러면 이제 matchId 하나하나를 검색해보면서 해당 매치의 결과 정보를 알 수 있겠죠?

matchId를 통해 해당 매치의 결과 정보를 얻는 API는 방금 전 우리가 사용했던 API 바로 아래에 있습니다.

이 부분인데요.

클릭해서 들어가보시면 엄.청.나.게 긴 Dto를 보실수 있습니다.

여러분들의 시간을 절약해드리기 위해, 필요한 key값만 좀 살펴보겠습니다.

summonerName : 유저 닉네임
individualPosition : 내가 선택한 포지션(탑 미드 정글 바텀 서폿)
totalDamageDealtToChampions : 해당 게임 내 총 딜량
win : 이겼는지 여부
kills : 몇 킬을 달성했는지
assists : 어시스트를 몇 개 했는지
deaths : 몇 번 죽었는지
championName : 내가 선택한 챔피언 이름
 

자, 우리는 조금 전 10개의 matchId를 가지고 왔었죠? 그렇다면 각 matchId별로 정보를 불러와야합니다. 따라서 다음과 같은 코드진행이 가능합니다.

async function fetchMatchDataList(gameList) {
    const fetchPromises = gameList.map(element =>
        fetch(`https://asia.api.riotgames.com/lol/match/v5/matches/${element}`, {
            method: 'GET',
            headers: headers
        })
            .then(response => {
                if (!response.ok) {
                    throw new Error('Network response was not ok');
                }
                return response.json();
            })
    );
    const matchDataList = await Promise.all(fetchPromises);
    return matchDataList;
}

async function run(){
    let {puuid} = await getPuuid('Hide on bush');
    let matchIds = await fetchGameListData(puuid,0,10);
    let matchInformations = await fetchMatchDataList(matchIds);
    
}
run()
 

fetchMatchDataList는 matchIds를 보내 각 게임별 정보를 담아줍니다.

그 이후, 우리는 필요한 정보들만 따로 저장을 해야겠죠? 위에서 살펴본 key값을 가지고 다음과 같은 진행을 합니다.

const info = [];  // 내가 따로 저장할 value만 담을 배열
matchInformations.forEach(data => { // 참여인원이 10명이면, 한 게임당 10개의 개인 기록이 있겠죠? 그 중, 소환사이름이 내가 찾고 싶은 id인 경우에만 데이터를 저장합니다.
                const d = data.info.participants;
                d.forEach(e => {
                    let temp = {};
                    if (e.summonerName == id) { // 이 부분이 바로 내가 찾고자하는 id와 
                        if (e.individualPosition == 'Invalid') {
                            e.individualPosition = '칼바람나락'
                        }
                        temp = {
                            position: e.individualPosition,
                            dealt: e.totalDamageDealtToChampions,
                            win: e.win,
                            kda: e.challenges.kda,
                            kills: e.kills,
                            assists: e.assists,
                            deaths: e.deaths,
                            champion: e.championName
                        }
                        info.push(temp);
                    }
                });
            });
 

내가 따로 저장할 정보들만 담을 배열 info를 선언한 뒤,

매치들의 정보가 담겨있는 matchInformations배열을 순회하며 내가 필요한 정보들만 따로 담아줍니다.

 

function getNeedData(matches,id){
    let info = [];
    matches.forEach(data => { // 참여인원이 10명이면, 한 게임당 10개의 개인 기록이 있겠죠? 그 중, 소환사이름이 내가 찾고 싶은 id인 경우에만 데이터를 저장합니다.
        const d = data.info.participants;
        d.forEach(e => {
            let temp = {};
            if (e.summonerName == id) { // 이 부분이 바로 내가 찾고자하는 id와 
                if (e.individualPosition == 'Invalid') {
                    e.individualPosition = '칼바람나락'
                }
                temp = {
                    position: e.individualPosition,
                    dealt: e.totalDamageDealtToChampions,
                    win: e.win,
                    kda: e.challenges.kda,
                    kills: e.kills,
                    assists: e.assists,
                    deaths: e.deaths,
                    champion: e.championName
                }
                info.push(temp);
            }
        });
    });
    return info;
}

async function run(){
    let searchId = 'Hide on bush'
    let {puuid} = await getPuuid(searchId);
    let matchIds = await fetchGameListData(puuid,0,10);
    let matchInformations = await fetchMatchDataList(matchIds);
    let finalData = getNeedData(matchInformations,searchId);
    console.log(finalData)
}
run()
 

최종적으로 finalData에 담겨있는 데이터들을 출력하면 다음과 같은 결과가 나옵니다.

이를 좀 더 가공해보면

function makeInfoList(id, data) {
    let position = {};
    let dealt = 0;
    let wins = 0;
    let loses = 0;
    let kda = 0;
    let kills = 0;
    let assists = 0;
    let deaths = 0;
    let champions = {};
    data.forEach(e => {
        if (position[e.position]) {
            position[e.position] += 1;
        } else {
            position[e.position] = 1;
        }
        dealt += e.dealt;
        if (e.win) { wins += 1 }
        else { loses += 1 }
        kda += e.kda;
        kills += e.kills;
        assists += e.assists;
        deaths += e.deaths;
        if (champions[e.champion]) { champions[e.champion] += 1 }
        else { champions[e.champion] = 1 };
    }
    )
    console.log(`${id}님의 최근 10전\n${wins}승 ${loses}패 승률 : ${(wins / 10) * 100}%\n평균 딜량 : ${dealt / 10}\n평균 kda : ${kda / 10}\n킬 : ${kills} 데스 : ${deaths}  어시스트 : ${assists}`)
    for (let key in position) {
        console.log(key, position[key], '회');
    }

}

async function run(){
    let searchId = 'Hide on bush'
    let {puuid} = await getPuuid(searchId);
    let matchIds = await fetchGameListData(puuid,0,10);
    let matchInformations = await fetchMatchDataList(matchIds);
    let finalData = getNeedData(matchInformations,searchId);
    makeInfoList(searchId, finalData)
}
run()
 

이런식으로 최종 출력되는 것을 보실 수 있습니다. (승률이 6할이상이시네요.. 부럽다..)

이런식으로 오늘은 라이엇 디벨로퍼에서 제공하는 API들을 이용하여 내가 찾고자 하는 유저의 게임 전적을 검색해보았습니다. 사실 이 외에도 더 많은 정보들이 제공됩니다. 아이템이라든지 스펠이라든지 등등… 여러분들이 게임 내에서 얻을 수 있는 정보는 웬만하면 다 있다고 생각하시면 될 것 같습니다. 자 그럼 이것으로 오늘의 포스팅을 마치도록 하겠습니다.

글 읽어주신 여러분들 감사합니다 즐겜하세요! :)

 

댓글