LOLのゲームクライアントAPIから情報を受け取る

# 概要
最近、League of legendsというゲームに熱中しています。

> 『リーグ・オブ・レジェンド』（League of Legends、略称: LoL（ロル））は、ライアットゲームズが開発した基本プレイ無料のマルチプレイヤーオンラインバトルアリーナゲーム（MOBA）。
-- Wikipediaより引用

先日APIドキュメントを眺めていたら、ゲームクライアントから情報を受け取れると記載があり試してみました。

# 使い方
前提としてクライアントAPIを叩く際には、以下のようにゲームクライアントを起動してください。
![スクリーンショット 2024-12-03 0.04.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/6b40a093-664a-80f1-e40d-dc57020b824b.png)

### クライアントAPIドキュメント
https://127.0.0.1:2999/swagger/v2/swagger.json
https://127.0.0.1:2999/swagger/v3/openapi.json
APIドキュメントを用意してくれています。
この記事では記載していませんが、RPCによるイベント監視用のAPIもドキュメントに含まれています。

### クライアントが起動しているかを確かめる
クライアントが起動すると`127.0.0.1:2999`が使われるので、これを監視する。
```py
def life_check() -> bool:
    # ゲームクライアントが立ち上がると127.0.0.1:2999が使われるため、それを検知するためのメソッド

    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((HOST, PORT))
        s.close()

        return True
    except socket.error as e:
        return False

if life_check():
    print("ゲームを確認しました. life_check ok")
else:
    print("ゲームが起動していません. life_check failed")        
```

### ゲーム情報取得 - Get All Game Data
```
GET https://127.0.0.1:2999/liveclientdata/allgamedata
```

このAPIではゲーム内に関する情報をほとんど取得でき、基本的にこのAPIで完結します。

<br>
<br>

https://github.com/OR-Sasaki/LeagueOfLegendsClientAPIWrapper

取得用のラッパーを作成しました
上記リポジトリクローン後、sample.pyを実行してみてください。
データの形式は data_typesフォルダ内にあります。

```py:取得例
import lol_game_client_api_wrapper as lw
result = lw.all_game_data()

# 取得したゲームデータ
print(result.data)
```
このようにAPIを簡単に叩くことができます

```
# サモナーネームなどを取得できる
print("サモナー名: " + result.active_player.summoner_name)
print("現在のHP: " + result.active_player.champion_stats.current_health)
```
型も宣言しておいたので、参照も簡単です

<br>
jsonのサンプルがあると理解が早いので、そのまま貼っておきます

```json:sample
{
	"activePlayer": {
		"abilities": {
			"E": {
				"abilityLevel": 0,
				"displayName": "バビューン！",
				"id": "YuumiE",
				"rawDescription": "GeneratedTip_Spell_YuumiE_Description",
				"rawDisplayName": "GeneratedTip_Spell_YuumiE_DisplayName"
			},
			"Passive": {
				"displayName": "ネコはトモダチ",
				"id": "YuumiP",
				"rawDescription": "GeneratedTip_Passive_YuumiP_Description",
				"rawDisplayName": "GeneratedTip_Passive_YuumiP_DisplayName"
			},
			"Q": {
				"abilityLevel": 0,
				"displayName": "きまぐれミサイル",
				"id": "YuumiQ",
				"rawDescription": "GeneratedTip_Spell_YuumiQ_Description",
				"rawDisplayName": "GeneratedTip_Spell_YuumiQ_DisplayName"
			},
			"R": {
				"abilityLevel": 0,
				"displayName": "ファイナルチャプター",
				"id": "YuumiR",
				"rawDescription": "GeneratedTip_Spell_YuumiR_Description",
				"rawDisplayName": "GeneratedTip_Spell_YuumiR_DisplayName"
			},
			"W": {
				"abilityLevel": 1,
				"displayName": "ユー＆ミー！",
				"id": "YuumiW",
				"rawDescription": "GeneratedTip_Spell_YuumiW_Description",
				"rawDisplayName": "GeneratedTip_Spell_YuumiW_DisplayName"
			}
		},
		"championStats": {
			"abilityHaste": 0.0,
			"abilityPower": 9.0,
			"armor": 25.0,
			"armorPenetrationFlat": 0.0,
			"armorPenetrationPercent": 1.0,
			"attackDamage": 49.0,
			"attackRange": 425.0,
			"attackSpeed": 0.706250011920929,
			"bonusArmorPenetrationPercent": 1.0,
			"bonusMagicPenetrationPercent": 1.0,
			"critChance": 0.0,
			"critDamage": 175.0,
			"currentHealth": 565.0,
			"healShieldPower": 0.0,
			"healthRegenRate": 1.0,
			"lifeSteal": 0.0,
			"magicLethality": 0.0,
			"magicPenetrationFlat": 0.0,
			"magicPenetrationPercent": 1.0,
			"magicResist": 25.0,
			"maxHealth": 565.0,
			"moveSpeed": 330.0,
			"omnivamp": 0.0,
			"physicalLethality": 0.0,
			"physicalVamp": 0.0,
			"resourceMax": 440.0,
			"resourceRegenRate": 2.0,
			"resourceType": "MANA",
			"resourceValue": 440.0,
			"spellVamp": 0.0,
			"tenacity": 5.0
		},
		"currentGold": 1850.5054931640626,
		"fullRunes": {
			"generalRunes": [
				{
					"displayName": "リーサルテンポ",
					"id": 8008,
					"rawDescription": "perk_tooltip_LethalTempo",
					"rawDisplayName": "perk_displayname_LethalTempo"
				},
				{
					"displayName": "冷静沈着",
					"id": 8009,
					"rawDescription": "perk_tooltip_PresenceOfMind",
					"rawDisplayName": "perk_displayname_PresenceOfMind"
				},
				{
					"displayName": "レジェンド: 迅速",
					"id": 9104,
					"rawDescription": "perk_tooltip_9104",
					"rawDisplayName": "perk_displayname_9104"
				},
				{
					"displayName": "切り崩し",
					"id": 8017,
					"rawDescription": "perk_tooltip_CutDown",
					"rawDisplayName": "perk_displayname_CutDown"
				},
				{
					"displayName": "ビスケットデリバリー",
					"id": 8345,
					"rawDescription": "perk_tooltip_BiscuitDelivery",
					"rawDisplayName": "perk_displayname_BiscuitDelivery"
				},
				{
					"displayName": "疾駆",
					"id": 8410,
					"rawDescription": "perk_tooltip_ApproachVelocity",
					"rawDisplayName": "perk_displayname_ApproachVelocity"
				}
			],
			"keystone": {
				"displayName": "リーサルテンポ",
				"id": 8008,
				"rawDescription": "perk_tooltip_LethalTempo",
				"rawDisplayName": "perk_displayname_LethalTempo"
			},
			"primaryRuneTree": {
				"displayName": "栄華",
				"id": 8000,
				"rawDescription": "perkstyle_tooltip_7201",
				"rawDisplayName": "perkstyle_displayname_7201"
			},
			"secondaryRuneTree": {
				"displayName": "天啓",
				"id": 8300,
				"rawDescription": "perkstyle_tooltip_7203",
				"rawDisplayName": "perkstyle_displayname_7203"
			},
			"statRunes": [
				{
					"id": 5005,
					"rawDescription": "perk_tooltip_StatModAttackSpeed"
				},
				{
					"id": 5008,
					"rawDescription": "perk_tooltip_StatModAdaptive"
				},
				{
					"id": 5011,
					"rawDescription": "perk_tooltip_StatModHealth"
				}
			]
		},
		"level": 1,
		"riotId": "Hemuichi#JP1",
		"riotIdGameName": "Hemuichi",
		"riotIdTagLine": "JP1",
		"summonerName": "Hemuichi#JP1",
		"teamRelativeColors": true
	},
	"allPlayers": [
		{
			"championName": "ユーミ",
			"isBot": false,
			"isDead": false,
			"items": [
				{
					"canUse": true,
					"consumable": true,
					"count": 3,
					"displayName": "英気満点ビスケット",
					"itemID": 2010,
					"price": 50,
					"rawDescription": "GeneratedTip_Item_2010_Description",
					"rawDisplayName": "Item_2010_Name",
					"slot": 0
				}
			],
			"level": 1,
			"position": "",
			"rawChampionName": "game_character_displayname_Yuumi",
			"rawSkinName": "game_character_skin_displayname_Yuumi_19",
			"respawnTimer": 0.0,
			"riotId": "Hemuichi#JP1",
			"riotIdGameName": "Hemuichi",
			"riotIdTagLine": "JP1",
			"runes": {
				"keystone": {
					"displayName": "リーサルテンポ",
					"id": 8008,
					"rawDescription": "perk_tooltip_LethalTempo",
					"rawDisplayName": "perk_displayname_LethalTempo"
				},
				"primaryRuneTree": {
					"displayName": "栄華",
					"id": 8000,
					"rawDescription": "perkstyle_tooltip_7201",
					"rawDisplayName": "perkstyle_displayname_7201"
				},
				"secondaryRuneTree": {
					"displayName": "天啓",
					"id": 8300,
					"rawDescription": "perkstyle_tooltip_7203",
					"rawDisplayName": "perkstyle_displayname_7203"
				}
			},
			"scores": {
				"assists": 0,
				"creepScore": 0,
				"deaths": 0,
				"kills": 0,
				"wardScore": 0.0
			},
			"skinID": 19,
			"skinName": "ユービィー",
			"summonerName": "Hemuichi#JP1",
			"summonerSpells": {
				"summonerSpellOne": {
					"displayName": "フラッシュ",
					"rawDescription": "GeneratedTip_SummonerSpell_SummonerFlash_Description",
					"rawDisplayName": "GeneratedTip_SummonerSpell_SummonerFlash_DisplayName"
				},
				"summonerSpellTwo": {
					"displayName": "ゴースト",
					"rawDescription": "GeneratedTip_SummonerSpell_SummonerHaste_Description",
					"rawDisplayName": "GeneratedTip_SummonerSpell_SummonerHaste_DisplayName"
				}
			},
			"team": "ORDER"
		}
	],
	"events": {
		"Events": [
			{
				"EventID": 0,
				"EventName": "GameStart",
				"EventTime": 0.015115839429199696
			},
			{
				"EventID": 1,
				"EventName": "MinionsSpawning",
				"EventTime": 65.09434509277344
			}
		]
	},
	"gameData": {
		"gameMode": "PRACTICETOOL",
		"gameTime": 771.88671875,
		"mapName": "Map11",
		"mapNumber": 11,
		"mapTerrain": "Default"
	}
}
```

***
***
***
(要望があれば他のAPIのクラスも作成します)