Last active
April 3, 2022 08:08
-
-
Save NanoAi/cbc79b2fa694a079bdc2588c46746681 to your computer and use it in GitHub Desktop.
A Python Script that uses League APIs to attempt to close the process when the game ends, without playing out the ending animation. Because alt+f4 is now disabled... READ THE FIRST COMMENT!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from lcu_driver import Connector | |
import requests, webbrowser, psutil, asyncio, re | |
# This will automatically open porofessor & League of Graphs in champ select. | |
# -- ALSO -- | |
# This will poll the League In-Game API, and watch the GameFlow sockets | |
# to automatically end the process of your game when the game ends. | |
### Comment out as you see fit! | |
## However: I still think using autohotkey to just kill the process with a key | |
## press is better... | |
# Set your League Directory Here. | |
LEAGUE_DIR = 'C:\\Riot Games\\League of Legends\\' | |
# Make sure to escape your backslashes by doubling them up `\` = `\\`. | |
# There must be a `\\` at the end of the path. | |
# Set this to `False` if you don't want the game to try to autoclose when it ends. | |
ENABLE_AUTOCLOSE = True | |
# This will also fix any issues with process hanging. | |
# I think pressing alt+f4 or using autohotkey is faster. | |
LOCALHOST = 'localhost' | |
GAME_STATUS = '' | |
GOT_LOBBY = False | |
HAS_PICKED = False | |
GAME_PROCESS_ID = False | |
GET_TASK = False | |
lolLock = open(LEAGUE_DIR + 'lockfile', 'r') | |
GAMEAPI_LOCK = lolLock.read().rsplit(':') | |
GAMEAPI_PORT = GAMEAPI_LOCK[2] | |
lolLock.close() | |
print('Detected Port: ' + GAMEAPI_PORT) | |
def killProcessId(): | |
global GAME_PROCESS_ID | |
if GAME_PROCESS_ID: | |
proc = psutil.Process(GAME_PROCESS_ID) | |
proc.terminate() | |
proc.kill() | |
GAME_PROCESS_ID = False | |
return | |
async def getInGameAPI(): | |
global GAME_PROCESS_ID, GAMEAPI_PORT | |
while( GAMEAPI_PORT == '' ): | |
await asyncio.sleep(5) | |
for proc in psutil.process_iter(['pid', 'name']): | |
try: | |
if proc.is_running and 'League of Legends' in proc.name(): | |
for connection in proc.connections(): | |
if connection.status == psutil.CONN_LISTEN: | |
GAMEAPI_PORT = str(connection.laddr.port) | |
GAME_PROCESS_ID = proc.pid | |
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): | |
pass | |
return GAMEAPI_PORT | |
async def getInGameEvents(): | |
global GAME_PROCESS_ID | |
while( True ): | |
await asyncio.sleep(0.5) | |
try: | |
response = requests.get(f'https://{LOCALHOST}:{GAMEAPI_PORT}' + '/liveclientdata/eventdata', verify=False) | |
print("REQ_STATUS: " + str(response.status_code), flush=True) | |
if response.status_code == requests.codes.ok: | |
for event in response.json()['Events']: | |
if event['EventName'] == 'GameEnd': | |
print(event, flush=True) | |
killProcessId() | |
GET_TASK.cancel() | |
break | |
except (ConnectionRefusedError): | |
print("\n!!!!!CLOSING!!!!", flush=True) | |
GET_TASK.cancel() | |
return | |
conn = Connector() | |
# fired when League Client is closed (or disconnected from websocket) | |
@conn.close | |
async def disconnect(_): | |
await conn.stop() | |
quit() | |
# START - LeagueOfGraphs | |
@conn.ws.register('/lol-champ-select/v1/session', event_types=('UPDATE',)) | |
async def champSelectSession(connection, event): | |
global GOT_LOBBY, HAS_PICKED, BROWSER | |
lolGraphsURL = 'https://www.leagueofgraphs.com/champions/probuilds/' | |
teamSearchURL = 'https://na.op.gg/multi/query=' | |
allyNames = '' | |
if not HAS_PICKED: | |
pick = await connection.request('get', '/lol-champ-select/v1/summoners/' + str(event.data['localPlayerCellId'])) | |
if pick.status == 200: | |
outputJson = await pick.json() | |
if outputJson['isDonePicking'] == True: | |
print('CHAMPION PICKED: ' + outputJson['championName'], flush=True) | |
webbrowser.open( lolGraphsURL + re.sub(r'[^\w]', '', outputJson['championName']).strip().lower(), new=0, autoraise=False ) | |
HAS_PICKED = True | |
if GOT_LOBBY == True: return | |
userIds = [] | |
summonerNames = [] | |
for player in event.data['myTeam']: | |
GOT_LOBBY = True | |
userIds.append(str(player['summonerId'])) | |
userIdsStringify = ','.join(map(str, userIds)) | |
summoner = await connection.request('get', f'/lol-summoner/v2/summoner-names?ids=[{userIdsStringify}]') | |
if summoner.status == 200: | |
for summonerInfo in await summoner.json(): | |
summonerNames.append(summonerInfo['displayName']) | |
allyNames = ','.join(map(str, summonerNames)) | |
print( 'TEAM:', allyNames, flush=True ) | |
# webbrowser.open( 'https://porofessor.gg/pregame/na/' + allyNames ) | |
webbrowser.open( teamSearchURL + allyNames, new=1, autoraise=False ) | |
# END - LeagueOfGraphs | |
@conn.ws.register('/lol-gameflow/v1/gameflow-phase', event_types=('UPDATE',)) | |
async def gameFlowStateChange(connection, event): | |
global GAME_STATUS, GET_TASK, GAME_PROCESS_ID, GOT_LOBBY, HAS_PICKED | |
global ENABLE_AUTOCLOSE | |
GAME_STATUS = event.data | |
print('GAME STATE: ' + event.data, flush=True) | |
# Waits for the game to be in progress and starts the InGameAPI polling | |
# Comment set `ENABLE_AUTOCLOSE` to `False` to disable. | |
if ENABLE_AUTOCLOSE and GAME_STATUS == "InProgress": | |
await asyncio.sleep(10) | |
GAMEAPI_PORT = await getInGameAPI() | |
print('GAMEAPI_PORT: ' + GAMEAPI_PORT, flush=True) | |
print('LISTENER: Starting Tasks', flush=True) | |
GET_TASK = asyncio.create_task(getInGameEvents()) | |
if GAME_STATUS == 'WaitingForStats' or GAME_STATUS == 'None': | |
GOT_LOBBY = False | |
HAS_PICKED = False | |
if GAME_PROCESS_ID: | |
killProcessId() | |
if GET_TASK and GET_TASK.done(): | |
print('\nLISTENER: Closing Tasks', flush=True) | |
GET_TASK.cancel() | |
# starts the connector | |
conn.start() |
Has this ever worked?
response = requests.get(f'https://{LOCALHOST}:{GAMEAPI_PORT}' + '/liveclientdata/eventdata', verify=False)
Because nowadays the ingame client is hardset to port 2999, but I was trying to use this code in hopes that you were somehow able to communicate with the league ingame client on a different port @NanoAi
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As soon as the the ingame client starts I only keep getting
REQ_STATUS: 404
@NanoAi