# 브롤스타즈 API 전적 사이트 : 플레이어 전투 기록 불러오기

- Author: @laetipark
- Published: 2023-07-23
- Updated: 2023-07-23
- Source: http://blex.me/@laetipark/%EB%B8%8C%EB%A1%A4%EC%8A%A4%ED%83%80%EC%A6%88-api-%EC%A0%84%EC%A0%81-%EC%82%AC%EC%9D%B4%ED%8A%B8-%ED%94%8C%EB%A0%88%EC%9D%B4%EC%96%B4-%EC%A0%84%ED%88%AC-%EA%B8%B0%EB%A1%9D-%EB%B6%88%EB%9F%AC%EC%98%A4%EA%B8%B0
- Tags: javascript, nodejs, 포트폴리오, express, api, 브롤스타즈, react

---

## 목차
- [개요 및 개발 환경](https://blex.me/@laetipark/%EB%B8%8C%EB%A1%A4%EC%8A%A4%ED%83%80%EC%A6%88-api-%EC%A0%84%EC%A0%81-%EC%82%AC%EC%9D%B4%ED%8A%B8-%EA%B0%9C%EC%9A%94-%EB%B0%8F-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD)
- [토큰 키 발급 및 클럽 플레이어 정보 불러오기](https://blex.me/@laetipark/%EB%B8%8C%EB%A1%A4%EC%8A%A4%ED%83%80%EC%A6%88-api-%EC%A0%84%EC%A0%81-%EC%82%AC%EC%9D%B4%ED%8A%B8-%ED%86%A0%ED%81%B0-%ED%82%A4-%EB%B0%9C%EA%B8%89-%EB%B0%8F-%ED%81%B4%EB%9F%BD-%ED%94%8C%EB%A0%88%EC%9D%B4%EC%96%B4-%EC%A0%95%EB%B3%B4-%EB%B6%88%EB%9F%AC%EC%98%A4%EA%B8%B0)
- **플레이어 전투 기록 불러오기(현재 글)**

## Battle API 문서 확인
![](https://static.blex.me/images/content/2023/7/19/202371919_LqIBsMYPDeAf13fy7Yle.png)
![](https://static.blex.me/images/content/2023/7/19/202371919_Dv21tFyNsHHhYjlrGaAg.png)
`/players/{playerTag}/battlelog`를 통해 플레이어 전투 정보를 불러올 수 있으며, 플레이어 태그를 입력하면 `요청 URL`과 `응답 결과`를 확인할 수 있다.

## Player BattleLog json 요소
주로 사용되는 BattleLog json의 items 배열 내 요소들을 정리해보았다.
브롤스타즈의 전투 API의 경우 3vs3 매치와 쇼다운 매치에 따라 다르다.
- battleTime : 전투 시작 시간
- event : 전투 맵 정보(맵 ID, 게임 모드, 맵 이름)
- battle : 전투 정보
	- mode : 게임 모드
	- type : 전투 유형("ranked", "friendly", "soloRanked", "teamRanked", "challenge", "championshipChallenge")
	- result`(3vs3 매치)` : 전투 결과("victory", "draw", "defeat")
	- duration`(3vs3 매치)` : 전투 지속 시간
	- starPlayer`(3vs3 매치)` : 스타 플레이어 플레이어와 사용한 브롤러 정보
	- rank`(쇼다운 매치)` : 쇼다운 순위
	- trophyChange : 트로피 변화량
	- teams`(3vs3 또는 듀오 쇼다운 매치)` : 전투 팀 플레이어와 사용한 브롤러 정보 **배열**
	- players`(솔로 쇼다운 또는 듀얼 매치)` : 전투 플레이어와 사용한 브롤러 정보 **배열**

**플레이어 전투 목록으로 이루어진 배열**을 아래와 같이 불러올 수 있다. 전투 기록은 `최근으로부터 25개 전투`를 불러올 수 있다.
```javascript
await fetch(`https://api.brawlstars.com/v1/players/%23태그/battlelog`, {
    method: "GET",
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + 토큰 값
    }
}).then(res => res.json())
	 .catch(err => console.error(err));
```

### 게임 모드 전투 정보 통일
배열 내 전투 정보가 3vs3 모드, 듀오 쇼다운 모드와 솔로 쇼다운 모드, 듀얼 모드에 따라 JSON 구조가 다르다. **3vs3 모드와 솔로 쇼다운 모드의 경우 아래와 같이 구성된다.**
- 3vs3 모드
	```javascript
	{
		"battleTime": "20230101T000000.000Z",
		"event": {
			"id": 15000051,
			"mode": "brawlBall",
			"map": "Super Beach"
		},
		"battle": {
			"mode": "brawlBall",
			"type": "ranked",
			"result": "victory",
			"duration": 101,
			"trophyChange": 8,
			"starPlayer": {
				"tag": "#000000",
				"name": "laetipark1",
				"brawler": {
					"id": 16000001,
					"name": "COLT",
					"power": 10,
					"trophies": 500
				}
			},
			"teams": [
				[
					{
						"tag": "#000000",
						"name": "laetipark1",
						"brawler": {
							"id": 16000019,
							"name": "PENNY",
							"power": 10,
							"trophies": 500
						}
					},
					{
						"tag": "#RRRRRR",
						"name": "laetipark2",
						"brawler": {
							"id": 16000045,
							"name": "STU",
							"power": 11,
							"trophies": 500
						}
					},
					{
						"tag": "#VVVVVV",
						"name": "laetipark3",
						"brawler": {
							"id": 16000010,
							"name": "EL PRIMO",
							"power": 11,
							"trophies": 500
						}
					}
				]
				...
			]
		}
	}
	```
- 솔로 쇼다운 모드
	```javascript
	{
		"battleTime": "20230101T000000.000Z",
		"event": {
			"id": 15000033,
			"mode": "soloShowdown",
			"map": "Cavern Churn"
		},
		"battle": {
			"mode": "soloShowdown",
			"type": "ranked",
			"rank": 1,
			"trophyChange": 10,
			"players": [
				{
					"tag": "#OOOOOO",
					"name": "laetipark",
					"brawler": {
						"id": 16000070,
						"name": "CORDELIUS",
						"power": 11,
						"trophies": 500
					}
				}
				...
			]
		}
	}
	```
**여러 형태의 JSON을 하나의 데이터베이스 테이블에 넣는 중, 솔로/듀오 쇼다운 모드에서의 브롤러 승률 통계를 내기 위해서는 전투 결과 값을 따로 만들어주어야 했다.**
그래서 3vs3 모드 `result` 요소를 **모든 전투 결과 값으로 통일**시켜 솔로/듀오 쇼다운 모드의 `rank` 요소에 따라 값을 넣어주기로 했다.

**솔로 쇼다운**과 **듀오 쇼다운** `rank` 값마다 `result`의 승(victory)/무(draw)/패(defeat) 개념을 나누었다.
**솔로 쇼다운** : 승 1~4등 / 무 5~6등 / 패 7~10등  
**듀오 쇼다운** : 승 1~2등 / 무 3등 / 패 4~5등

**프로젝트 코드**에는 아래와 같은 방식으로 솔로 쇼다운(10팀) 또는 듀오 쇼다운(5팀)의 순위에 따라  `rankResult`값으로 다시 계산하여 승/무/패를 구분해주었다.
```javascript
// 2 / (10 / teams) => 솔로 쇼다운 : 2 / 듀오 쇼다운 : 1
const rankResult = rank / (2 / (10 / teams));
if (rankResult < 2) { // 승리
	return -1;
} else if (rankResult < 3) { // 무승부
	return 0;
} else { // 패배
	return 1;
}
```

### 전투 유형 세분화
**API에서 제공하는 전투 유형(type) 요소 값은 아래와 같다.**
ranked : 트로피 리그 맵, 유저 맵 전투
friendly : 친선 전투
soloRanked : 파워 리그(솔로)
teamRanked : 파워 리그(팀)
challenge : 챌린지
championshipChallenge : 챔피언십 챌린지

**클럽 리그**의 경우 현재 API에서 위에 전투 유형과는 다른 방식으로 제공한다.
```javascript
// 일반 모드로 플레이 할 경우
{
		...
    "battle": {
        "type": "ranked",
        "trophyChange": 4,
    },
    "teams": [
        [
            {
                "tag": "#RRRRRR",
                "name": "laetipark2",
                "brawler": {
                    "id": 16000030,
                    "name": "EMZ",
                    "power": 11,
					// 파워 리그 또는 클럽 리그로 플레이 할 경우 "trophies" 값은 각각의 랭크로 표기 된다.
					// 다이아 1 == 10
                    "trophies": 18
                }
            }
			...
		]
		...
	]
}
// 파워 매치로 플레이 할 경우
{
		...
    "battle": {
        "type": "teamRanked",
				"trophyChange": 9,
    }
		...
}
```

트로피 리그와 파워 리그, 그리고 클럽 리그를 따로 구분하고 싶었으며, 관련한 내용을 검색하거나 공식 API에서의 응답을 확인해보니 **클럽 리그**는 아래와 같이 구분할 수 있음을 알 수 있었다.
```javascript
if (type === "teamRanked" && [3, 5, 7, 9].includes(trophyChange)) {
	// 파워 매치
	comparePlayers.teams = currentPlayers;
	type = "clubLeague";
}
if (type === "ranked" && [1, 2, 3, 4].includes(trophyChange) && trophies < 20 && !["duoShowdown", "soloShowdown"].includes(mode)) {
	// 일반 모드
	// trophies는 트로피 리그 맵에서 플레이할 경우 브롤러 트로피 개수가 1100개 이상인 것을 제외하기 위함
	type = "clubLeague";
}
```
**파워 매치의 경우 파워 리그와 같은 3판 2선승제**로 **같은 팀으로 두 번 이상의 전투가 진행**되기 때문에, **프로젝트 코드**에서는 해당 전투에서 파워 매치인 것이 확인되면 팀 정보를 저장하여 다음 전투에서의 팀 정보와 비교하여 클럽 리그인지 여부를 확인해주는 코드 또한 작성하였다.

## 참고
- [How to track your club's Club League performance using the official Brawl Stars API, Reddit](https://www.reddit.com/r/Brawlstars/comments/upm12b/how_to_track_your_clubs_club_league_performance/)
