diff --git a/games/LoL/linux/README.md b/games/LoL/linux/README.md index 58adc84..eccd73f 100644 --- a/games/LoL/linux/README.md +++ b/games/LoL/linux/README.md @@ -1,6 +1,7 @@ # leagueoflinux scripts ## `sulaunchhelper2.sh` This script is a wrapper for `sulaunchhelper2.py` and `syscall_check.sh`, for use with Lutris pre-game launch script. +### Installation + To install you must have `sulaunchhelper2.py` and `syscall_check.sh` present, if not you can execute these to quickly download them (to current directory): ```sh curl -OL https://gitlab.com/tretrauit/scripts/-/raw/main/games/LoL/linux/sulaunchhelper2.py @@ -14,3 +15,20 @@ chmod +x sulaunchhelper2.sh ``` + After that, copy all these files to the game prefix you want to use, then set pre-launch script in Lutris to where `sulaunchhelper2.sh` is located. + Enjoy your LoL experience :P +## `garena_wrapper.sh` +This script automates the launching of [lol.py](https://github.com/nhubaotruong/league-of-legends-linux-garena-script) (LoL in Garena client) so you don't have to manually do it ;) +### Installation +Because this script is used in Lutris pre-game launch script, it also wrap `syscall_check.sh`. You also need to follow steps in `lol.py` repository to properly config your LoL prefix. ++ To install you must have `lol.py` and `syscall_check.sh` present, if not you can execute these to quickly download them (to current directory): +```sh +curl -OL https://raw.githubusercontent.com/nhubaotruong/league-of-legends-linux-garena-script/main/lol.py +curl -OL https://gitlab.com/tretrauit/scripts/-/raw/main/games/LoL/linux/syscall_check.sh +chmod +x sulaunchhelper2.py syscall_check.sh +``` ++ Then to download `garena_wrapper.sh` itself: +```sh +curl -OL https://gitlab.com/tretrauit/scripts/-/raw/main/games/LoL/linux/garena_wrapper.sh +chmod +x garena_wrapper.sh +``` ++ After that, copy all these files to the game prefix you want to use, then set pre-launch script in Lutris to where `sulaunchhelper2.sh` is located. ++ Enjoy your Garena LoL experience :P diff --git a/games/LoL/linux/garena_wrapper.sh b/games/LoL/linux/garena_wrapper.sh new file mode 100755 index 0000000..1b7dac4 --- /dev/null +++ b/games/LoL/linux/garena_wrapper.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# This script is a wrapper for nhubaotruong/league-of-legends-linux-garena-script and syscall_check.sh +# It automatically execute lol.py to start LoL lutris game from Garena. +# You need lol.py and syscall_check.sh present in game prefix root directory. + +SCC_SH='syscall_check.sh' +LOL_PY='lol.py' + +dialog() { + zenity "$@" --icon-name='lutris' --width="400" --title="Garena LoL to LoL lutris wrapper" +} + +own_dir="$(realpath .)" +# try to call syscall_check.sh +if ! [ -x "${own_dir}/${SCC_SH}" ]; then + dialog "Please place this script into the same directory as '${SCC_SH}'!" +else + sh "${own_dir}/${SCC_SH}" +fi + +echo "Waiting for Garena to start..." +until _=$(pidof Garena.exe) +do + sleep 1 +done + +trap final EXIT + +echo "Entering loop..." +noGarena=0 +lolPyPid="" + +final() { + echo "Exiting..." + if [[ -z $(kill -0 $lolPyPid) ]]; then + echo "Closing lol.py..." + kill -15 $lolPyPid + fi +} + +trap final EXIT + +while : +do + if [[ -z $(pidof Garena.exe) ]]; then + exit + fi + noGarena=0 + if [[ $lolPyPid ]]; then + kill -0 $lolPyPid + if [[ $? -ne 0 ]]; then + echo "Clearing old exited lol.py PID." + lolPyPid="" + fi + fi + if [[ -z $(pidof RiotClientServices.exe) ]] && [[ -z $lolPyPid ]]; then + echo "Launching lol.py" + python3 "${own_dir}/${LOL_PY}" & + lolPyPid=$! + fi + sleep .5 +done +exit + diff --git a/games/LoL/linux/lol.py b/games/LoL/linux/lol.py new file mode 100644 index 0000000..54f03d4 --- /dev/null +++ b/games/LoL/linux/lol.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 + +import psutil +import os +import yaml +import sqlite3 +import re +import time + + +def find_process_id_by_name(processName): + """ + Get a list of all the PIDs of a all the running process whose name contains + the given string processName + """ + # Iterate over the all the running process + while True: + time.sleep(1) + for proc in psutil.process_iter(): + try: + pinfo = proc.as_dict(attrs=["cmdline", "name", "pid"]) + # Check if process name contains the given name string. + if processName.lower() in pinfo["name"].lower(): + return pinfo + except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): + pass + + +def kill_old_league_and_riot_process(): + RIOT_AND_LEAGUE_PROCESS_REGEX = re.compile("(league|riot).*\.exe", flags=re.I) + for proc in psutil.process_iter(): + try: + pinfo = proc.as_dict(attrs=["name", "pid"]) + # Check if process name contains the given name string. + if RIOT_AND_LEAGUE_PROCESS_REGEX.search(pinfo.get("name")): + print( + f"Found old process still running: {pinfo.get('name')}, pid: {pinfo.get('pid')}" + ) + p = psutil.Process(pinfo.get("pid")) + p.kill() + except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): + pass + + +def main(): + riot_service_process_name = "RiotClientServices.exe" + + print( + f"The script will wait for a {riot_service_process_name} process to show up to get it's token. So go to the Garena client and press Play" + ) + kill_old_league_and_riot_process() + + # Get RiotClientServices.exe process + riot_process = find_process_id_by_name(riot_service_process_name) + + # Programmatically get RiotClientServices.exe arguments + try: + riot_argument = " ".join(riot_process.get("cmdline", [])[1:]).strip() + except Exception: + print("Cannot get Garena Token") + + # Exit if no riot_argument is found + if not riot_argument: + quit() + + print(f"Garena token got from {riot_service_process_name}: {riot_argument}") + + # Kill the current RiotClientServices.exe + p = psutil.Process(riot_process.get("pid")) + p.kill() + + # Start game using lutris + HOME = os.getenv("HOME") + + LUTRIS_DB_PATH = HOME + "/.local/share/lutris" + LUTRIS_DB_NAME = "pga.db" + conn = sqlite3.connect(LUTRIS_DB_PATH + "/" + LUTRIS_DB_NAME) + c = conn.cursor() + c.execute("SELECT id,configpath FROM games WHERE slug='league-of-legends'") + try: + game_id, configpath = c.fetchone() + conn.close() + except Exception: + print("No league of legends install from lutris found") + conn.close() + quit() + + LUTRIS_CONFIG_FOLDER = HOME + "/.config/lutris/games/" + LUTRIS_LOL_CONFIG_FILE = LUTRIS_CONFIG_FOLDER + configpath + ".yml" + + with open(LUTRIS_LOL_CONFIG_FILE, "r") as f: + try: + game_config = yaml.load(f, Loader=yaml.FullLoader) + except yaml.YAMLError as exc: + print(exc) + quit() + + with open(LUTRIS_LOL_CONFIG_FILE, "w") as f: + game_config["game"]["args"] = riot_argument + try: + yaml.dump(game_config, f, default_flow_style=False) + except yaml.YAMLError as exc: + print(exc) + quit() + + print("Starting game with current config:") + print(f"- Wine version: {game_config.get('wine',{}).get('version')}") + print(f"- Executable: {game_config.get('game',{}).get('exe')}") + print(f"- Wineprefix: {game_config.get('game',{}).get('prefix')}") + + print( + "If this is your first time running LOL since reboot, a pop up will appear, chose the first or second option then enter your password\n" + ) + print("It's a workaround by the lutris community\n") + print("Ignore the lines below, they are not actually error\n") + launch_command = f"lutris lutris:rungameid/{game_id}" + os.system(launch_command) + + +if __name__ == "__main__": + main()