@echo off setlocal REM ========================================================================= REM Wuju (wuju.gg) - watch replay NA1_5614364120 REM REM What this file does, in plain English: REM REM 1. Finds YOUR League client on THIS PC and reads the port number and REM one-time password that the client writes into its own "lockfile" REM while it is running. REM 2. Asks that client - at https://127.0.0.1, an address that can only REM ever mean "this computer" - to open replay 5614364120. REM REM That is the whole story. It contacts no server of ours, it downloads REM nothing from the internet, and it never sees your Riot password. The REM lockfile password is a random string the client invents for itself REM every time it starts, and it dies when the client closes. REM REM Everything below is ordinary Windows batch plus curl.exe, which ships REM with Windows. Nothing is encoded, compressed or hidden. Please read it. REM ========================================================================= REM The only two values this file was generated with. set "GAME_ID=5614364120" set "REGION=NA1" title Wuju - replay %REGION%_%GAME_ID% echo. echo Wuju - opening replay %REGION%_%GAME_ID% echo. where curl.exe >nul 2>nul if errorlevel 1 goto no_curl REM --- 1. find the running client ----------------------------------------- REM While League is running it keeps a file called "lockfile" in its install REM folder, and deletes it on exit. The format is one line: REM name:pid:port:password:protocol set "LEAGUE_DIR=" call :find_league if not defined LEAGUE_DIR goto no_client if not exist "%LEAGUE_DIR%\lockfile" goto no_client set "PORT=" set "PASSWORD=" REM The client keeps the lockfile open, so it has to be read through "type" REM rather than opened directly. Fields 3 and 4 are the port and password. for /f "usebackq tokens=3,4 delims=:" %%a in (`type "%LEAGUE_DIR%\lockfile"`) do ( set "PORT=%%a" set "PASSWORD=%%b" ) if not defined PORT goto no_client if not defined PASSWORD goto no_client REM -s: no progress bar. -k: the client signs its own local certificate, so REM curl has nothing to check it against. Nothing here leaves this PC. set "LCU=https://127.0.0.1:%PORT%" set "CURL=curl.exe -s -k -u riot:%PASSWORD%" REM --- 2. right client, right region? ------------------------------------- REM findstr /r treats "." as "any character", which is how these patterns REM match the quote marks in the JSON without fighting batch over quoting. %CURL% "%LCU%/lol-rso-auth/v1/authorization" | findstr /r /c:"currentPlatformId.: *.[A-Z]" >nul if errorlevel 1 goto not_logged_in %CURL% "%LCU%/lol-rso-auth/v1/authorization" | findstr /r /c:"currentPlatformId.: *.%REGION%." >nul if errorlevel 1 goto wrong_region REM --- 3. ask the client to download the replay ---------------------------- REM "download" rather than "watch": asked to watch a replay it has never REM downloaded, the client sometimes quietly does nothing. Asked to download REM it, it always starts. The watching happens in step 5. REM This reply is worthless: the client answers "204 No Content" whether or REM not it can actually get the replay. Step 4 is the real answer. %CURL% -X POST -H "Content-Type: application/json" -d "{}" "%LCU%/lol-replays/v1/rofls/%GAME_ID%/download" >nul REM --- 4. wait for the download -------------------------------------------- echo Asking your client for the replay. This can take up to a minute... set /a TRIES=0 set /a RETRIES=0 :poll %CURL% "%LCU%/lol-replays/v1/metadata/%GAME_ID%" | findstr /r /c:"state.: *.watch." >nul if not errorlevel 1 goto launch %CURL% "%LCU%/lol-replays/v1/metadata/%GAME_ID%" | findstr /r /c:"state.: *.incompatible." >nul if not errorlevel 1 goto old_patch REM Riot's replay service drops downloads mid-transfer now and then. The REM client then reports "retryDownload" and waits to be asked again, so ask REM again - a few times - before concluding the replay is unavailable. %CURL% "%LCU%/lol-replays/v1/metadata/%GAME_ID%" | findstr /r /c:"state.: *.retryDownload." >nul if not errorlevel 1 goto retry_download :poll_wait set /a TRIES+=1 if %TRIES% GEQ 60 goto unavailable REM One second between checks. 2>nul because "timeout" objects when this REM file is run from something other than a normal console window. timeout /t 1 /nobreak >nul 2>nul goto poll :retry_download if %RETRIES% GEQ 3 goto unavailable set /a RETRIES+=1 echo Riot dropped the download partway - asking again (try %RETRIES% of 3)... %CURL% -X POST -H "Content-Type: application/json" -d "{}" "%LCU%/lol-replays/v1/rofls/%GAME_ID%/download" >nul REM Give the client a moment to leave the retryDownload state before the REM next check, or all three retries burn in three seconds. timeout /t 3 /nobreak >nul 2>nul goto poll_wait REM --- 5. downloaded - now play it ----------------------------------------- :launch %CURL% -X POST -H "Content-Type: application/json" -d "{}" "%LCU%/lol-replays/v1/rofls/%GAME_ID%/watch" >nul echo. echo Done - the replay is opening in your League client. echo. exit /b 0 REM --- things that can go wrong ------------------------------------------- :no_curl echo This file needs curl.exe, which is part of Windows 10 from April 2018 echo onwards. It was not found on this PC, so this script cannot run. goto stop :no_client echo Could not find a running League client. echo. echo Start League of Legends, log in, let the client finish loading, then echo run this file again. goto stop :not_logged_in echo Your League client is running but is not logged in yet. echo. echo Finish logging in, then run this file again. goto stop :wrong_region echo This replay was played on %REGION%, and your client is logged in to a echo different region. echo. echo Riot only lets an account download replays from its own region, so echo there is no way to open this one from here. goto stop :old_patch echo This replay is from an older patch and League can no longer play it. echo. echo Riot deletes replay data each patch, so this one cannot be opened. goto stop :unavailable echo Your client could not fetch this replay. echo. echo The game may have aged out of Riot's replay storage, or the client echo may be busy patching. Try again in a few minutes. goto stop :stop echo. pause exit /b 1 REM --- helper: where is League installed? ---------------------------------- :find_league REM Riot keeps its own list of install folders here, so ask that first. set "INSTALLS=%ProgramData%\Riot Games\RiotClientInstalls.json" if not exist "%INSTALLS%" goto default_paths REM The carets are how batch escapes a quote used as a delimiter: split the REM matching line on quote marks and keep the second piece, which is the path. for /f "usebackq delims=" %%L in (`findstr /i /c:"League of Legends" "%INSTALLS%"`) do ( if not defined LEAGUE_DIR for /f tokens^=2^ delims^=^" %%P in ("%%L") do set "LEAGUE_DIR=%%P" ) if not defined LEAGUE_DIR goto default_paths REM That file stores the path with forward slashes on current clients and REM doubled backslashes on older ones. Turn either into a normal path. set "LEAGUE_DIR=%LEAGUE_DIR:\\=\%" set "LEAGUE_DIR=%LEAGUE_DIR:/=\%" if "%LEAGUE_DIR:~-1%"=="\" set "LEAGUE_DIR=%LEAGUE_DIR:~0,-1%" if exist "%LEAGUE_DIR%\lockfile" exit /b :default_paths set "LEAGUE_DIR=C:\Riot Games\League of Legends" if exist "%LEAGUE_DIR%\lockfile" exit /b set "LEAGUE_DIR=%ProgramFiles%\Riot Games\League of Legends" if exist "%LEAGUE_DIR%\lockfile" exit /b set "LEAGUE_DIR=" exit /b