diff --git a/main.py b/main.py index 3481750d..9cd8e43c 100644 --- a/main.py +++ b/main.py @@ -35,9 +35,12 @@ from src.websocket import Ws from src.os import get_os +from src.account_manager.account_manager import AccountManager +from src.account_manager.account_config import AccountConfig +from src.account_manager.account_auth import AccountAuth + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) -# os.system('cls') os.system(f"title VALORANT rank yoinker v{version}") server = "" @@ -71,10 +74,6 @@ def get_ip(): program_exit(0) else: log(f"Operating system: {get_os()[0]}\n") - - ChatLogging = ChatLogging() - chatlog = ChatLogging.chatLog - try: if len(sys.argv) > 1 and sys.argv[1] == "--config": configure() @@ -82,12 +81,10 @@ def get_ip(): message="Do you want to run vRY now?", default=True ).execute() if run_app: - os.system('mode 150,35') os.system('cls') else: os._exit(0) else: - os.system('mode 150,35') os.system('cls') except Exception as e: print("Something went wrong while running configurator!") @@ -96,12 +93,16 @@ def get_ip(): input("press enter to exit...\n") os._exit(1) + ChatLogging = ChatLogging() + chatlog = ChatLogging.chatLog - ErrorSRC = Error(log) + acc_manager = AccountManager(log, AccountConfig, AccountAuth, NUMBERTORANKS) - Requests = Requests(version, log, ErrorSRC) - Requests.check_version() + ErrorSRC = Error(log, acc_manager) + + Requests.check_version(version, Requests.copy_run_update_script) Requests.check_status() + Requests = Requests(version, log, ErrorSRC) cfg = Config(log) diff --git a/src/account_manager/account_auth.py b/src/account_manager/account_auth.py new file mode 100644 index 00000000..c8504aa0 --- /dev/null +++ b/src/account_manager/account_auth.py @@ -0,0 +1,177 @@ +import requests, time, re, ssl +from secrets import token_urlsafe +from InquirerPy import prompt + +#temporary +import urllib3 +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + + + +FORCED_CIPHERS = [ + 'ECDHE-ECDSA-AES128-GCM-SHA256', + 'ECDHE-ECDSA-CHACHA20-POLY1305', + 'ECDHE-RSA-AES128-GCM-SHA256', + 'ECDHE-RSA-CHACHA20-POLY1305', + 'ECDHE+AES128', + 'RSA+AES128', + 'ECDHE+AES256', + 'RSA+AES256', + 'ECDHE+3DES', + 'RSA+3DES'] + +# pasted TLS from stackoverflow +class TLSAdapter(requests.adapters.HTTPAdapter): + def init_poolmanager(self, *args, **kwargs) -> None: + ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) + ctx.set_ciphers(':'.join(FORCED_CIPHERS)) + kwargs['ssl_context'] = ctx + return super(TLSAdapter, self).init_poolmanager(*args, **kwargs) + + + +class AccountAuth: + def __init__(self, log, NUMBERTORANKS): + self.log = log + + log("Getting versions from valorant-api.com for account auth-ing") + version = self.get_current_version() + + self.session = requests.Session() + self.session.mount("https://", TLSAdapter()) + self.headers = { + "Accept-Encoding": "deflate, gzip, zstd", + "user-agent": f"RiotClient/{version['riotClientBuild']} rso-auth (Windows;10;;Professional, x64)", + "Cache-Control": "no-cache", + "Accept": "application/json", + 'Accept-Language':'en-US,en;q=0.9' + } + self.auth_headers = { + 'X-Riot-ClientPlatform': "ew0KCSJwbGF0Zm9ybVR5cGUiOiAiUEMiLA0KCSJwbGF0Zm9ybU9TIjog" + "IldpbmRvd3MiLA0KCSJwbGF0Zm9ybU9TVmVyc2lvbiI6ICIxMC4wLjE5" + "MDQyLjEuMjU2LjY0Yml0IiwNCgkicGxhdGZvcm1DaGlwc2V0IjogIlVua25vd24iDQp9", + 'X-Riot-ClientVersion': version["riotClientVersion"], + "User-Agent": "ShooterGame/13 Windows/10.0.19043.1.256.64bit" + } + self.puuid = "" + self.content = None + self.region = "" + self.NUMBERTORANKS = NUMBERTORANKS + + def get_current_version(self): + return requests.get("https://valorant-api.com/v1/version").json()["data"] + + + + def auth_account(self, username=None, password=None, cookies=None): + self.session.cookies.clear() + if cookies != None: + for cookie in cookies: + self.session.cookies.set(cookie, cookies[cookie]) + data = { + "acr_values": "", + "claims": "", + "client_id": "riot-client", + "code_challenge": "", + "code_challenge_method": "", + "nonce": token_urlsafe(16), + "redirect_uri": "http://localhost/redirect", + 'response_type': 'token id_token', + "scope": "openid link ban lol_region account", + } + r = self.session.post('https://auth.riotgames.com/api/v1/authorization', json=data, headers=self.headers) + if username == None and password == None: + if r.json().get("response") == None: + return None + if username != None and password != None: + self.log("authing with username and password") + body = { + "language": "en_US", + "password": password, + "region": None, + "remember": True, + "type": "auth", + "username": username, + } + + r = self.session.put("https://auth.riotgames.com/api/v1/authorization", json=body, headers=self.headers) + #check for 2fa + if r.json().get("type") == "multifactor": + self.log("2fa detected") + #get 2fa code + body = { + "type": "multifactor", + "code": self.ask_for_mfa(), + "remember": True + } + r = self.session.put("https://auth.riotgames.com/api/v1/authorization", json=body, headers=self.headers) + if r.json().get("error") == "auth_failure": + return None + pattern = re.compile('access_token=((?:[a-zA-Z]|\d|\.|-|_)*).*id_token=((?:[a-zA-Z]|\d|\.|-|_)*).*expires_in=(\d*)') + data = pattern.findall(r.json()['response']['parameters']['uri'])[0] + access_token = data[0] + id_token = data[1] + expires_in = data[2] + expire_in_epoch = int(time.time()) + int(expires_in) + r_entitlements = self.session.post('https://entitlements.auth.riotgames.com/api/token/v1', headers={'Authorization': 'Bearer ' + access_token} | self.headers, json={}) + entitlements_token = r_entitlements.json()['entitlements_token'] + self.auth_headers.update({ + 'Authorization': f"Bearer {access_token}", + 'X-Riot-Entitlements-JWT': entitlements_token}) + r = requests.put("https://riot-geo.pas.si.riotgames.com/pas/v1/product/valorant", headers={'Authorization': 'Bearer ' + access_token}, json={"id_token": id_token}) + self.region = r.json()["affinities"]["live"] + r = requests.post("https://auth.riotgames.com/userinfo", headers={'Authorization': 'Bearer ' + access_token}) + self.lol_region = r.json()["region"]["tag"] + + self.puuid = self.session.cookies.get_dict()["sub"] + return { + "cookies": self.session.cookies.get_dict(), + "expire_in": expire_in_epoch, + "lol_region": self.lol_region + } + + def get_latest_season_id(self): + self.log("get latest season id") + if self.content is None: + self.content = requests.get(f"https://shared.{self.region}.a.pvp.net/content-service/v3/content", headers=self.auth_headers, verify=False) + for season in self.content.json()["Seasons"]: + if season["IsActive"]: + return season["ID"] + + def get_account_data(self): + #if more advande account data wants to be supported requestsV needs to be edited so it can bue used with custom headers and not lockfile + r_mmr = requests.get(f"https://pd.{self.region}.a.pvp.net/mmr/v1/players/{self.puuid}", headers=self.auth_headers, verify=False) + if r_mmr.json()["QueueSkills"]["competitive"].get("SeasonalInfoBySeasonID") is not None: + season_info = r_mmr.json()["QueueSkills"]["competitive"]["SeasonalInfoBySeasonID"].get(self.get_latest_season_id()) + if season_info is not None: + rank = season_info["CompetitiveTier"] + else: + rank = 0 + else: + rank = 0 + rank = self.escape_ansi(self.NUMBERTORANKS[rank]) + name = requests.put(f"https://pd.{self.region}.a.pvp.net/name-service/v2/players", headers=self.auth_headers, json=[self.puuid]).json() + name = name[0]["GameName"] + "#" + name[0]["TagLine"] + r_account_xp = requests.get(f"https://pd.{self.region}.a.pvp.net/account-xp/v1/players/{self.puuid}", headers=self.auth_headers, verify=False) + level = r_account_xp.json()["Progress"]["Level"] + contracts = requests.get("https://valorant-api.com/v1/contracts") + contracts = [a for a in contracts.json()["data"] if a["content"]["relationType"] == "Season"] + bp = contracts[-1] + r_contracts = requests.get(f"https://pd.{self.region}.a.pvp.net/contracts/v1/contracts/{self.puuid}", headers=self.auth_headers, verify=False) + for contract in r_contracts.json()["Contracts"]: + if contract["ContractDefinitionID"] == bp["uuid"]: + bp_level = contract["ProgressionLevelReached"] + return { + "rank": rank, + "name": name, + "level": level, + "bp_level": bp_level + } + + def escape_ansi(self, line): + ansi_escape = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]') + return ansi_escape.sub('', line) + + def ask_for_mfa(self): + self.log("asking for mfa") + return prompt({"type": "input", "message": "Please enter your MFA/2FA code:", "name": "mfa"})["mfa"] \ No newline at end of file diff --git a/src/account_manager/account_config.py b/src/account_manager/account_config.py new file mode 100644 index 00000000..bc9426eb --- /dev/null +++ b/src/account_manager/account_config.py @@ -0,0 +1,187 @@ +import yaml, json, os, subprocess, time +class AccountConfig: + def __init__(self, log): + self.log = log + self.client_names = ["rc_default", "rc_live", "rc_beta"] + self.pritvate_settings = os.path.join(os.getenv('LOCALAPPDATA'), R'Riot Games\Riot Client\Data\RiotGamesPrivateSettings.yaml') + self.riot_client_path = "" + + def get_riot_client_path(self): + path = os.path.join(os.getenv("ALLUSERSPROFILE"), R'Riot Games\RiotClientInstalls.json') + with open(path, 'r') as f: + data = json.load(f) + for client in self.client_names: + if os.path.exists(data.get(client)): + self.riot_client_path = data.get(client) + return data.get(client) + + def load_accounts_config(self): + try: + os.mkdir(os.path.join(os.getenv('APPDATA'), "vry")) + except FileExistsError: + pass + try: + with open(os.path.join(os.getenv('APPDATA'), "vry/accounts.json"), "r") as f: + self.accounts_data = json.load(f) + except (FileNotFoundError, json.decoder.JSONDecodeError): + self.accounts_data = {} + return self.accounts_data + + def load_current_account_cookies(self): + with open(self.pritvate_settings, 'r') as f: + yaml_data = yaml.safe_load(f) + try: + if len(yaml_data["riot-login"]["persist"]["session"]["cookies"]) != 5: + self.log(f'Account not logged in, incorrect amount of cookies, amount of cookies {len(yaml_data["riot-login"]["persist"]["session"]["cookies"])}') + return None + except (TypeError, KeyError): + self.log("No cookies found in riot games private settings") + return None + cookies = {} + for cookie in yaml_data["riot-login"]["persist"]["session"]["cookies"]: + cookie_name = cookie["name"] + cookie_value = cookie["value"] + cookies.update({cookie_name: cookie_value}) + return cookies + + + def create_yaml_config_file(self, account_data): + + return { + "riot-login": { + "persist": { + "region": f"""{account_data['lol_region'].upper()}""", + "session": { + "cookies": [ + { + "domain": "riotgames.com", + "hostOnly": False, + "httpOnly": True, + "name": "tdid", + "path": "/", + "persistent": True, + "secureOnly": True, + "value": account_data["cookies"]["tdid"] + }, + { + "domain": "auth.riotgames.com", + "hostOnly": True, + "httpOnly": True, + "name": "ssid", + "path": "/", + "persistent": True, + "secureOnly": True, + "value": account_data["cookies"]["ssid"] + }, + { + "domain": "auth.riotgames.com", + "hostOnly": True, + "httpOnly": True, + "name": "clid", + "path": "/", + "persistent": True, + "secureOnly": True, + "value": account_data["cookies"]["clid"] + }, + { + "domain": "auth.riotgames.com", + "hostOnly": True, + "httpOnly": False, + "name": "sub", + "path": "/", + "persistent": True, + "secureOnly": True, + "value": account_data["cookies"]["sub"] + }, + { + "domain": "auth.riotgames.com", + "hostOnly": True, + "httpOnly": False, + "name": "csid", + "path": "/", + "persistent": True, + "secureOnly": True, + "value": account_data["cookies"]["csid"] + }, + ] + } + } + } + } + + def save_account_to_config(self, authdata, data, save_cookies=True): + self.load_accounts_config() + if save_cookies: + cookies_dict = {"cookies": { + "clid": authdata["cookies"].get("clid"), + "csid": authdata["cookies"].get("csid"), + "ssid": authdata["cookies"].get("ssid"), + "sub": authdata["cookies"].get("sub"), + "tdid": authdata["cookies"].get("tdid") + }} + else: + puuid = authdata["cookies"].get("sub") + cookies_dict = { + "cookies": { + "clid": self.accounts_data[puuid]["cookies"].get("clid"), + "ssid": self.accounts_data[puuid]["cookies"].get("ssid"), + "csid": self.accounts_data[puuid]["cookies"].get("csid"), + "sub": self.accounts_data[puuid]["cookies"].get("sub"), + "tdid": self.accounts_data[puuid]["cookies"].get("tdid") + } + } + updated_data = { + authdata["cookies"].get("sub"): { + "rank": data.get("rank"), + "name": data.get("name"), + "level": data.get("level"), + "bp_level": data.get("bp_level"), + "expire_in": authdata.get("expire_in"), + "lol_region": authdata.get("lol_region"), + #convert to base64 maybe in future + } + } + updated_data[authdata.get("cookies").get("sub")].update(cookies_dict) + self.accounts_data.update(updated_data) + with open(os.path.join(os.getenv('APPDATA'), "vry/accounts.json"), "w") as f: + json.dump(self.accounts_data, f) + return updated_data + + def remove_account(self, puuid): + self.load_accounts_config() + del self.accounts_data[puuid] + with open(os.path.join(os.getenv('APPDATA'), "vry/accounts.json"), "w") as f: + json.dump(self.accounts_data, f) + + def add_account_with_client(self): + subprocess.call("TASKKILL /F /IM RiotClientUx.exe", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + with open(self.pritvate_settings, "w") as f: + f.write("") + time.sleep(3) + subprocess.Popen([self.riot_client_path]) + #watchdog wait for login + last_modified = os.path.getmtime(self.pritvate_settings) + while True: + if os.path.getmtime(self.pritvate_settings) != last_modified: + account_cookies = self.load_current_account_cookies() + if account_cookies is not None: + return account_cookies + last_modified = os.path.getmtime(self.pritvate_settings) + time.sleep(0.5) + + def switch_to_account(self, account_data): + subprocess.call("TASKKILL /F /IM RiotClientUx.exe", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + with open(self.pritvate_settings, 'r') as f: + yaml_data = yaml.safe_load(f) + try: + if len(yaml_data["riot-login"]["persist"]["session"]["cookies"]) == 5: + for i, cookie in enumerate(yaml_data["riot-login"]["persist"]["session"]["cookies"]): + yaml_data["riot-login"]["persist"]["session"]["cookies"][i]["value"] = account_data["cookies"].get(cookie["name"]) + except TypeError: + yaml_data = self.create_yaml_config_file(account_data) + else: + self.log(f'Account not logged in, incorrect amount of cookies, amount of cookies {len(yaml_data["riot-login"]["persist"]["session"]["cookies"])}') + yaml_data = self.create_yaml_config_file(account_data) + #need to create riotgamesprivatesettings.yaml file with content in it generated + with open(self.pritvate_settings, "w") as f: + yaml.dump(yaml_data, f) diff --git a/src/account_manager/account_manager.py b/src/account_manager/account_manager.py new file mode 100644 index 00000000..c5123ec0 --- /dev/null +++ b/src/account_manager/account_manager.py @@ -0,0 +1,205 @@ +import InquirerPy, subprocess, re +from InquirerPy import inquirer + + +class AccountManager: + def __init__(self, log, AccountConfig, AccountAuth, NUMBERTORANKS): + self.log = log + self.account_config = AccountConfig(log) + self.auth = AccountAuth(log, NUMBERTORANKS) + self.last_account_data = None + + self.log("Account manager initialized") + + + + def menu_change_accounts(self): + change_accounts_prompt = { + "type": "list", + "name": "menu", + "message": "Please select optional features:", + "choices": [], + } + + add_account_prompt = { + "type": "list", + "name": "menu", + "message": "Please select optional features:", + "choices": [ + "Add account with username & password.", + "Add account by signing into riot client." + ], + } + + self.account_config.load_accounts_config() + account_order_list = [] + accounts_list = [] + for account in self.account_config.accounts_data: + account_order_list.append(account) + acc_string = f"Change to: {self.account_config.accounts_data[account]['name']:<16} | {self.account_config.accounts_data[account].get('rank'):<12} | Level: {self.account_config.accounts_data[account].get('level'):<4} | Battlepass {self.account_config.accounts_data[account].get('bp_level'):<2}/55" + accounts_list.append(acc_string) + change_accounts_prompt["choices"].append(acc_string) + change_accounts_prompt["choices"].append("Add new account") + change_accounts_prompt["choices"].append("Remove account") + change_accounts_prompt["choices"].append("Back") + result = InquirerPy.prompt(change_accounts_prompt) + #Add new account + if result["menu"] == "Add new account": + result = InquirerPy.prompt(add_account_prompt) + option = add_account_prompt["choices"].index(result["menu"]) + #Add account with username & password + if option == 0: + questions = [ + {"type": "input", "message": "Please type username of the account you want to add:", "name": "username"}, + {"type": "password", "message": "Please type password of the account you want to add:", "name": "password"} + ] + try_again = True + while try_again: + result = InquirerPy.prompt(questions) + username = result["username"] + password = result["password"] + current_account_auth_data = self.auth.auth_account(username=username, password=password) + if current_account_auth_data is None: + try_again = inquirer.confirm(message="Invalid username or password! Do you want to try again?", default=True).execute() + else: + try_again = False + if current_account_auth_data is None: + self.menu(self.last_account_data) + else: + current_account_data = self.auth.get_account_data() + #SAVING NEW COOKIES BECAUSE OLD DOESN'T EXIST + self.account_config.save_account_to_config(current_account_auth_data, current_account_data) + #switch to new account with new auth data + self.account_config.switch_to_account(current_account_auth_data) + + self.menu(current_account_data) + #Add account by signing into riot client + elif option == 1: + current_account_cookies = self.account_config.add_account_with_client() + current_account_auth_data = self.auth.auth_account(cookies=current_account_cookies) + if current_account_auth_data is not None: + current_account_data = self.auth.get_account_data() + self.account_config.save_account_to_config(current_account_auth_data, current_account_data) + self.menu(current_account_data) + else: + self.log("Failed to add account with client! (cookies are fetched but auth_data is none)") + self.menu(self.last_account_data) + #Remove account + elif result["menu"] == "Remove account": + remove_account_prompt = { + "type": "list", + "name": "menu", + "message": "Please select account to remove:", + "choices": accounts_list, + } + result = InquirerPy.prompt(remove_account_prompt) + account_option = remove_account_prompt["choices"].index(result["menu"]) + account = account_order_list[account_option] + + + if self.last_account_data["name"] == self.account_config.accounts_data[account]["name"]: + self.account_config.remove_account(account) + self.menu(None) + else: + self.account_config.remove_account(account) + self.menu(self.last_account_data) + #Back + elif result["menu"] == "Back": + self.menu(self.last_account_data) + #Change to: {account_name} + else: + #change to one of saved accounts + #no longer account name but more stats make it better in future + account_option = change_accounts_prompt["choices"].index(result["menu"]) + account = account_order_list[account_option] + + current_account_auth_data = self.auth.auth_account(cookies=self.account_config.accounts_data[account]["cookies"]) + if current_account_auth_data is None: + self.log("Failed to auth account with cookies! (change accounts) ") + print("Cookies are invalid or have expired! Please login again. (Cookies only stays for few days, don't know why :/)") + self.account_config.remove_account(account) + self.menu(self.last_account_data) + else: + #SWITCH TO ACCOUNT WITH OLD COOKIES NOT RENEWED + self.account_config.switch_to_account(self.account_config.accounts_data[account]) + + current_account_data = self.auth.get_account_data() + + + #OVERRIDING ACCOUNT DATA ONLY (Cookies maybe shouldn't be renewed but rather used original data, we'll see) NOT BEING OVERRIDDEN NOW + #Testing with saving cookies, now happens that vry says it is logged in but can't launch valorant because riot client is not logged in + self.account_config.save_account_to_config(current_account_auth_data, current_account_data, save_cookies=True) + self.menu(current_account_data) + + def menu(self, account_data): + self.last_account_data = account_data + if account_data is not None: + menu_prompt = { + "type": "list", + "name": "menu", + "message": "Please select optional features:", + "choices": [ + f"Logged in as {account_data.get('name')} | {account_data.get('rank')} | Level: {account_data.get('level')} | Battlepass {account_data.get('bp_level')}/55", + "Change accounts", + "Start Valorant" + ], + } + else: + print("Not logged in!") + menu_prompt = { + "type": "list", + "name": "menu", + "message": "Please select optional features:", + "choices": [ + "Log in.", + ], + } + + + result = InquirerPy.prompt(menu_prompt) + option = menu_prompt["choices"].index(result["menu"]) + if account_data != None: + #Logged in as.... + if option == 0: + pass + #Change accounts + elif option == 1: + self.menu_change_accounts() + #Start Valorant + elif option == 2: + self.start_valorant() + else: + #Not logged in + if option == 0: + self.menu_change_accounts() + #Log in + # elif option == 1: + # self.menu_change_accounts() + + def start_menu(self): + self.log("Starting menu...") + self.account_config.get_riot_client_path() + current_account_cookies = self.account_config.load_current_account_cookies() + current_account_auth_data = self.auth.auth_account(cookies=current_account_cookies) + if current_account_auth_data is not None: + self.log("Authed with cookies!") + current_account_data = self.auth.get_account_data() + self.account_config.save_account_to_config(current_account_auth_data, current_account_data) + self.log("Opening menu") + self.menu(current_account_data) + else: + self.log("Failed to auth account with cookies! (start menu) ") + self.menu(None) + + def start_valorant(self): + self.log("Starting Valorant...") + subprocess.Popen([self.account_config.riot_client_path, "--launch-product=valorant", "--launch-patchline=live"]) + +# if __name__ == "__main__": + # from account_config import AccountConfig + # from account_auth import AccountAuth + # acc = AccountManager("a", AccountConfig, AccountAuth, NUMBERTORANKS) + # acc.start_menu() + # username = input("Username: ") + # password = input("Password: ") + # acc.add_account_with_user_pass_login(username, password) diff --git a/src/errors.py b/src/errors.py index caa076cc..6e7835ea 100644 --- a/src/errors.py +++ b/src/errors.py @@ -5,9 +5,9 @@ class Error: - def __init__(self, log): + def __init__(self, log, acc_manager): self.log = log - + self.acc_manager = acc_manager def PortError(self, port): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -29,8 +29,9 @@ def LockfileError(self, path): if os.path.exists(path): return True else: - # self.log("Lockfile does not exist, VALORANT is not open") - print("\nVALORANT is not open. Please open valorant\n") + self.log("Lockfile does not exist, VALORANT is not open") + self.acc_manager.start_menu() + while not os.path.exists(path): time.sleep(1) os.system('cls') diff --git a/src/requestsV.py b/src/requestsV.py index 4c48c5d2..2eadb134 100644 --- a/src/requestsV.py +++ b/src/requestsV.py @@ -19,18 +19,20 @@ def __init__(self, version, log, Error): self.headers = {} self.log = log + + self.lockfile = self.get_lockfile() self.region = self.get_region() self.pd_url = f"https://pd.{self.region[0]}.a.pvp.net" self.glz_url = f"https://glz-{self.region[1][0]}.{self.region[1][1]}.a.pvp.net" self.log(f"Api urls: pd_url: '{self.pd_url}', glz_url: '{self.glz_url}'") self.region = self.region[0] - self.lockfile = self.get_lockfile() - + self.puuid = '' #fetch puuid so its avaible outside self.get_headers() - def check_version(self): + @staticmethod + def check_version(version, copy_run_update_script): # checking for latest release r = requests.get("https://api.github.com/repos/zayKenyon/VALORANT-rank-yoinker/releases") json_data = r.json() @@ -39,7 +41,7 @@ def check_version(self): if "zip" in asset["content_type"]: link = asset["browser_download_url"] # link for the latest release break - if float(release_version) > float(self.version): + if float(release_version) > float(version): print(f"New version available! {link}") if sys.argv[0][-3:] == "exe": while True: @@ -47,12 +49,13 @@ def check_version(self): if update_now.lower() == "n" or update_now.lower() == "no": return elif update_now.lower() == "y" or update_now.lower() == "yes" or update_now == "": - self.copy_run_update_script(link) + copy_run_update_script(link) os._exit(1) else: print('Invalid input please response with "yes" or "no" ("y", "n") or press enter to update') - def copy_run_update_script(self, link): + @staticmethod + def copy_run_update_script(link): try: os.mkdir(os.path.join(os.getenv('APPDATA'), "vry")) except FileExistsError: @@ -63,7 +66,8 @@ def copy_run_update_script(self, link): z.extractall(os.path.join(os.getenv('APPDATA'), "vry")) subprocess.Popen([os.path.join(os.getenv('APPDATA'), "vry", "updatescript.bat"), os.path.join(os.getenv('APPDATA'), "vry", ".".join(os.path.basename(link).split(".")[:-1])), os.getcwd(), os.path.join(os.getenv('APPDATA'), "vry")]) - def check_status(self): + @staticmethod + def check_status(): # checking status rStatus = requests.get( "https://raw.githubusercontent.com/zayKenyon/VALORANT-rank-yoinker/main/status.json").json()