LeagueCustomLobby
英雄联盟创建5V5训练模式,及 LCU-API 探索笔记。
Install / Use
/learn @XHXIAIEIN/LeagueCustomLobbyREADME
LeagueCustomLobby
英雄联盟创建5V5训练模式
如何安装
- Python 3
- lcu-driver
按下 Windows + R 打开运行窗口,输入 cmd ,在控制台输入指令:pip install lcu-driver - 部分用户可能会遇到 psutil.AccessDenied 错误提示,需要额外执行安装:
pip install -U psutil==5.6.5
如何使用
将 create_custom_lobby.py 下载到本地任意地方,运行脚本即可。
<br><br>
新增备注:
- 官方已经更改了 lockfile 的方式,目前无法用以前的方法找到密钥了。
现在需要通过读取进程数据来找到。
用管理员权限打开终端,并运行以下指令
wmic PROCESS WHERE name='LeagueClientUx.exe' GET commandline
会得到类似这样的输出日志。当然,具体参数什么的,每次启动客户端看到的都不一样。
注意,一定要使用管理员权限运行CMD,否则你什么看不到。
Microsoft Windows [版本 10.0.19044.1865]
(c) Microsoft Corporation。保留所有权利。
C:\Users\XHXIAIEIN>wmic PROCESS WHERE name='LeagueClientUx.exe' GET commandline
CommandLine
"D:/Game/league of legends cn/英雄联盟/LeagueClient/LeagueClientUx.exe"
"--riotclient-auth-token=PVBsuiBiaNdAdIAnDoNg7yisxg"
"--riotclient-app-port=63381"
"--riotclient-tencent"
"--no-rads"
"--disable-self-update"
"--region=TENCENT"
"--locale=zh_CN"
"--t.lcdshost=hn1-sz-feapp.lol.qq.com"
"--t.chathost=hn1-sz-ejabberd.lol.qq.com"
"--t.lq=https://hn1-sz-login.lol.qq.com:8443"
"--t.storeurl=https://hn1-sr.lol.qq.com:8443"
"--t.rmsurl=wss://sz-rms-bcs.lol.qq.com:443"
"--rso-auth.url=https://prod-rso.lol.qq.com:3000"
"--rso_platform_id=HN1"
"--rso-auth.client=lol"
"--t.location=loltencent.sz.HN1"
"--tglog-endpoint=https://tglogsz.datamore.qq.com/lolcli/report/"
"--t.league_edge_url=https://ledge-hn1.lol.qq.com:22019"
"--ccs=https://cc-hn1.lol.qq.com:8093"
"--dradis-endpoint=http://some.url"
"--remoting-auth-token=lgxHX-LuAnDaXbyzA08w" <---⭐ 找到这个参数 `--remoting-auth-token=XXX`
"--app-port=63405" <---⭐ 找到这个参数 `--app-port=XXX`
"--install-directory=d:\game\league of legends cn\鑻遍泟鑱旂洘\LeagueClient"
"--app-name=LeagueClient"
"--ux-name=LeagueClientUx"
"--ux-helper-name=LeagueClientUxHelper"
"--log-dir=LeagueClient Logs"
"--crash-reporting=none"
"--crash-environment=HN1"
"--app-log-file-path=d:/game/league of legends cn/英雄联盟/LeagueClient/../Game/Logs/LeagueClient Logs/2022-08-03T14-38-37_8368_LeagueClient.log"
"--app-pid=8368"
"--output-base-dir=d:/game/league of legends cn/鑻遍泟鑱旂洘/LeagueClient/../Game"
"--no-proxy-server"
C:\Users\XHXIAIEIN>
主要需要找的信息就是
--remoting-auth-token=XXXXX
--app-port=XXX
然后,你就可以通过本地打开这个地址了
https://127.0.0.1:<app-port>/lol-summoner/v1/current-summoner
账号密码分别是
riot <remoting-auth-token>
如果直接在浏览器控制台发送HTTP请求,也可以这样:
// ========== 配置 ==========
const HOST = '127.0.0.1';
const PORT = XXXXX;
const USERNAME = 'riot';
const AUTH_TOKEN = 'XXXXX';
const METHOD = 'GET';
const PATH = '/lol-summoner/v1/current-summoner';
// ==========================
const url = `https://${HOST}:${PORT}${PATH}`;
const auth = btoa(`${USERNAME}:${AUTH_TOKEN}`);
fetch(url, {
method: METHOD,
headers: {
'Authorization': `Basic ${auth}`
}
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
- 这份笔记使用的是 lcu-driver,但我推荐你使用 Willump 作为连接器会更方便。(因为当时 Willump 还没有出现)
Willump 快速上手
import asyncio
import willump
async def get_summoner_data():
summoner = await (await wllp.request("GET", "/lol-summoner/v1/current-summoner")).json()
print(f"summonerName: {summoner['displayName']}")
print(f"summonerLevel: {summoner['summonerLevel']}")
print(f"profileIconId: {summoner['profileIconId']}")
print(f"summonerId: {summoner['summonerId']}")
print(f"puuid: {summoner['puuid']}")
print(f"---")
async def main():
global wllp
wllp = await willump.start()
await get_summoner_data()
await wllp.close()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
<br><br>
<br>参考资料
- Riot 开发者文档
- 版本英雄游戏数据
- 游戏数据资源列表
- LCU API 速查手册(需代理访问,来自 @mingweisamuel)
- 创建自定义训练模式房间数据
- 掌盟战迹击杀记录地图 | 游戏事件监听 | 战迹地图实现示例
- LCU websocket
对了,别忘了看 Wiki,这里也有一部分笔记哦
<br><br>
笔记
如果你像我一样,突然对英雄联盟 API 感兴趣,可以继续阅读下方的内容。
这里我使用了 lcu-driver 来对客户端进行通信,关于它的资料可以阅读 lcu-driver 开发文档 了解。
- lol-lobby
- lol-lobby-bots
- lol perks
- lol-champ-select
- lol-ranked
- lol collections
- champion profile
- champion spells
- game-client
快速上手
from lcu_driver import Connector
connector = Connector()
@connector.ready
async def connect(connection):
print(connection.address)
print('LCU API is ready to be used.')
@connector.close
async def disconnect(connection):
print('The client was closed')
await connector.stop()
@connector.ws.register('/lol-lobby/v2/lobby', event_types=('CREATE',))
async def icon_changed(connection, event):
print(f"The summoner {event.data['localMember']['summonerName']} created a lobby.")
connector.start()
<br>
获取召唤师数据
from lcu_driver import Connector
connector = Connector()
async def get_summoner_data(connection):
summoner = await connection.request('GET', '/lol-summoner/v1/current-summoner')
data = await summoner.json()
print(f"summonerName: {data['displayName']}")
print(f"summonerLevel: {data['summonerLevel']}")
print(f"profileIconId: {data['profileIconId']}")
print(f"summonerId: {data['summonerId']}")
print(f"puuid: {data['puuid']}")
print(f"---")
@connector.ready
async def connect(connection):
await get_summoner_data(connection)
connector.start()
<br>
创建房间
根据 queueId 创建常规房间:
async def createLobby(connection):
queue = {'queueId': 430}
await connection.request('POST', '/lol-lobby/v2/lobby', data=queue)
<br>
5V5自定义训练模式
参数解释:
- mapId: 地图ID。召唤师峡谷:11, 嚎哭深渊:12
- gameMode: 游戏模式。自定义模式为 'CLASSIC', 训练模式为 'PRACTICETOOL' (仅召唤师峡谷)
- lobbyName: 房间名称
- lobbyPassword: 房间密码
- teamSize: 队伍规模
async def creatCustomLabby(connection):
# 房间数据
LobbyConfig = {
'customGameLobby': {
'configuration': {
'gameMode': 'PRACTICETOOL',
'gameMutator': '',
'gameServerRegion': '',
'mapId': 11,
'mutators': {'id': 1},
'spectatorPolicy': 'AllAllowed',
'teamSize': 5
},
'lobbyName': 'PRACTICETOOL',
'lobbyPassword': ''
},
'isCustom': True
}
# 发送创建房间请求
await connection.request('POST', '/lol-lobby/v2/lobby', data=LobbyConfig)
<br>
添加单个机器人
参数解释:
- championId: 英雄ID,可以在下方表格查询。
- botDifficulty: 机器人难度。国服只有 "EASY"
- teamId: 左边蓝队:100, 右边红队:200
bots = {
'championId': 25,
'botDifficulty': 'MEDIUM',
'teamId': '200'
}
await connection.request('POST', '/lol-lobby/v1/lobby/custom/bots', data=bots)
<br>
添加机器人
根据ID添加
async def addBots(connection):
team2 = [122, 86, 1, 51, 25]
for id in team2:
bots = { 'championId': id, 'botDifficulty': 'MEDIUM', 'teamId': '200' }
await connection.request('POST', '/lol-lobby/v1/lobby/custom/bots', data=bots)
<br>
根据名称添加
async def addBots(connection):
# 获取可用的机器人列表
activedata = await connection.request('GET', '/lol-lobby/v2/lobby/custom/available-bots')
champions = { bot['name']: bot['id'] for bot in await activedata.json() }
# 队伍2的机器人
team2 = ['诺克萨斯之手', '德玛西亚之力', '曙光女神', '皮城女警', '众星之子']
for name in team2:
bots = { 'championId': champions[name], 'botDifficulty': 'MEDIUM', 'teamId': '200' }
await connection.request('POST', '/lol-lobby/v1/lobby/custom/bots', data=bots)
<br>
自定义模式可用机器人列表
自定义模式中的电脑机器人是有限的,只能选择列表中这些英雄。
请求此方法的时候,需要先创建房间。
data = await connection.request('GET', '/lol-lobby/v2/lobby/custom/available-bots')
champions = {bots['name']: bots['id'] for bots in await data.json()}
print(champions)
| championId | CN | EN | | :---------- | :--------- | :-------------------- | | 1 | 黑暗之女 | Annie | | 3 | 正义巨像 | Galio | | 8 | 猩红收割者 | Vladimir | | 10 | 正义天使 | Kayle | | 11 | 无极剑圣 | Master Yi | | 12 | 牛头酋长 | Alistar | | 13 | 符文法师 | Ryze | | 15 | 战争女神 | Sivir | | 16 | 众星之子 | Soraka | | 18 | 麦林炮手 | Tristana | | 19 | 祖安怒兽 | Warwick | | 21 | 赏金猎人 | Miss Fortune | | 22 | 寒冰射手 | Ashe
