diff --git a/rare/components/dialogs/login/browser_login.py b/rare/components/dialogs/login/browser_login.py index 8b10296f..136d1876 100644 --- a/rare/components/dialogs/login/browser_login.py +++ b/rare/components/dialogs/login/browser_login.py @@ -2,14 +2,15 @@ import json from logging import getLogger from typing import Tuple -from PyQt5.QtCore import pyqtSignal, QUrl +from PyQt5.QtCore import pyqtSignal, QUrl, QProcess, pyqtSlot from PyQt5.QtGui import QDesktopServices from PyQt5.QtWidgets import QFrame, qApp, QFormLayout, QLineEdit -from legendary.core import LegendaryCore from legendary.utils import webview_login +from rare.lgndr.core import LegendaryCore from rare.ui.components.dialogs.login.browser_login import Ui_BrowserLogin from rare.utils.misc import icon +from rare.utils.paths import get_rare_executable from rare.widgets.indicator_edit import IndicatorLineEdit, IndicatorReasonsCommon logger = getLogger("BrowserLogin") @@ -43,6 +44,7 @@ class BrowserLogin(QFrame): self.ui.open_button.clicked.connect(self.open_browser) self.sid_edit.textChanged.connect(self.changed.emit) + @pyqtSlot() def copy_link(self): clipboard = qApp.clipboard() clipboard.setText(self.login_url) @@ -79,12 +81,24 @@ class BrowserLogin(QFrame): except Exception as e: logger.warning(e) + @pyqtSlot() def open_browser(self): if not webview_login.webview_available: logger.warning("You don't have webengine installed, you will need to manually copy the authorizationCode.") QDesktopServices.openUrl(QUrl(self.login_url)) else: - if webview_login.do_webview_login(callback_code=self.core.auth_ex_token): + cmd = get_rare_executable() + ["login", self.core.get_egl_version()] + proc = QProcess(self) + proc.start(cmd[0], cmd[1:]) + proc.waitForFinished(-1) + out, err = ( + proc.readAllStandardOutput().data().decode("utf-8", "ignore"), + proc.readAllStandardError().data().decode("utf-8", "ignore") + ) + proc.deleteLater() + + if out: + self.core.auth_ex_token(out) logger.info("Successfully logged in as %s", {self.core.lgd.userdata['displayName']}) self.success.emit() else: diff --git a/rare/main.py b/rare/main.py index 5263db28..ac173cfc 100755 --- a/rare/main.py +++ b/rare/main.py @@ -57,22 +57,26 @@ def main() -> int: ) subparsers = parser.add_subparsers(title="Commands", dest="subparser") - launch_minimal_parser = subparsers.add_parser("start", aliases=["launch"]) - launch_minimal_parser.add_argument("app_name", help="AppName of the game to launch", - metavar="", action="store") - launch_minimal_parser.add_argument("--dry-run", help="Print arguments and exit", action="store_true") - launch_minimal_parser.add_argument("--offline", help="Launch game offline", - action="store_true") - launch_minimal_parser.add_argument('--wine-bin', dest='wine_bin', action='store', metavar='', - default=os.environ.get('LGDRY_WINE_BINARY', None), - help='Set WINE binary to use to launch the app') - launch_minimal_parser.add_argument('--wine-prefix', dest='wine_pfx', action='store', metavar='', - default=os.environ.get('LGDRY_WINE_PREFIX', None), - help='Set WINE prefix to use') - launch_minimal_parser.add_argument("--ask-sync-saves", help="Ask to sync cloud saves", - action="store_true") - launch_minimal_parser.add_argument("--skip-update-check", help="Do not check for updates", - action="store_true") + launch_parser = subparsers.add_parser("start", aliases=["launch"]) + launch_parser.add_argument("app_name", help="AppName of the game to launch", + metavar="", action="store") + launch_parser.add_argument("--dry-run", help="Print arguments and exit", action="store_true") + launch_parser.add_argument("--offline", help="Launch game offline", + action="store_true") + launch_parser.add_argument('--wine-bin', dest='wine_bin', action='store', metavar='', + default=os.environ.get('LGDRY_WINE_BINARY', None), + help='Set WINE binary to use to launch the app') + launch_parser.add_argument('--wine-prefix', dest='wine_pfx', action='store', metavar='', + default=os.environ.get('LGDRY_WINE_PREFIX', None), + help='Set WINE prefix to use') + launch_parser.add_argument("--ask-sync-saves", help="Ask to sync cloud saves", + action="store_true") + launch_parser.add_argument("--skip-update-check", help="Do not check for updates", + action="store_true") + + login_parser = subparsers.add_parser("login", aliases=["auth"]) + login_parser.add_argument("egl_version", help="Epic Games Launcher User Agent version", + metavar="", action="store") args = parser.parse_args() @@ -93,6 +97,10 @@ def main() -> int: print(f"Rare {__version__} Codename: {__codename__}") return 0 + if args.subparser in {"login", "auth"}: + from rare.webview import launch + return launch(args) + if args.subparser in {"start", "launch"}: from rare.launcher import launch return launch(args) diff --git a/rare/webview/__init__.py b/rare/webview/__init__.py new file mode 100644 index 00000000..7ad586c4 --- /dev/null +++ b/rare/webview/__init__.py @@ -0,0 +1,13 @@ +import sys +from argparse import Namespace + +from legendary.utils import webview_login + + +def launch(args: Namespace) -> int: + if webview_login.do_webview_login( + callback_code=sys.stdout.write, user_agent=f'EpicGamesLauncher/{args.egl_version}' + ): + return 0 + else: + return 1 diff --git a/requirements-webview.txt b/requirements-webview.txt index 0ba5b7fc..27c76260 100644 --- a/requirements-webview.txt +++ b/requirements-webview.txt @@ -1,5 +1,6 @@ -pywebview[qt]; platform_system == "Linux" -pywebview[qt]; platform_system == "FreeBSD" +# pywebview with QtWebEngine backend has issues with EGS login form, so use GTK +pywebview[gtk]; platform_system == "Linux" +pywebview[gtk]; platform_system == "FreeBSD" pythonnet>=3.0.0rc4; platform_system == "Windows" cefpython3; platform_system == "Windows" pywebview[cef]; platform_system == "Windows"