88b6e91530
Add a sub-application to Rare to launch the webview for logging into EGS. The sub-application operates similatly to the `laucher` sub-application and it is autonomous. After a successful login in returns the exchange code to the standard output to be parsed and used by the login dialog. The reason this implementation was chosen is because when pywebview uses pyqtwebengine as the GUI library, we cannot launch it through Rare as it tries to spawn a QMainWindow inside an existing event loop, which is prohibited by Qt. Despite that, EGS login page doesn't work correctly with QtWebEngine, so on linux default to the GTK backend for pywebview, and this change helps keeping applications using different toolkits separate. At this moment, spawning the sub-application blocks the execution of the main application. This change should make it easier to authenticate through Rare inside a gamescope session, such as the steam deck.
134 lines
5 KiB
Python
Executable file
134 lines
5 KiB
Python
Executable file
import multiprocessing
|
|
import os
|
|
import pathlib
|
|
import sys
|
|
from argparse import ArgumentParser
|
|
|
|
|
|
def main() -> int:
|
|
# If we are on Windows, and we are in a "compiled" GUI application form
|
|
# stdout (and stderr?) will be None. So to avoid `'NoneType' object has no attribute 'write'`
|
|
# errors, redirect both of them to devnull
|
|
if os.name == "nt" and (getattr(sys, "frozen", False) or ("__compiled__" in globals())):
|
|
# Check if stdout and stderr are None before redirecting
|
|
# This is useful in the case of test builds that enable console
|
|
if sys.stdout is None:
|
|
sys.stdout = open(os.devnull, 'w')
|
|
if sys.stderr is None:
|
|
sys.stderr = open(os.devnull, 'w')
|
|
|
|
os.environ["QT_QPA_PLATFORMTHEME"] = ""
|
|
if "LEGENDARY_CONFIG_PATH" in os.environ:
|
|
os.environ["LEGENDARY_CONFIG_PATH"] = os.path.expanduser(os.environ["LEGENDARY_CONFIG_PATH"])
|
|
|
|
# fix cx_freeze
|
|
multiprocessing.freeze_support()
|
|
|
|
# CLI Options
|
|
parser = ArgumentParser()
|
|
parser.add_argument(
|
|
"-V", "--version", action="store_true", help="Shows version and exits"
|
|
)
|
|
parser.add_argument(
|
|
"-S",
|
|
"--silent",
|
|
action="store_true",
|
|
help="Launch Rare in background. Open it from System Tray Icon",
|
|
)
|
|
parser.add_argument("--debug", action="store_true", help="Launch in debug mode")
|
|
parser.add_argument(
|
|
"--offline", action="store_true", help="Launch Rare in offline mode"
|
|
)
|
|
parser.add_argument(
|
|
"--test-start", action="store_true", help="Quit immediately after launch"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--desktop-shortcut",
|
|
action="store_true",
|
|
dest="desktop_shortcut",
|
|
help="Use this, if there is no link on desktop to start Rare",
|
|
)
|
|
parser.add_argument(
|
|
"--startmenu-shortcut",
|
|
action="store_true",
|
|
dest="startmenu_shortcut",
|
|
help="Use this, if there is no link in start menu to launch Rare",
|
|
)
|
|
subparsers = parser.add_subparsers(title="Commands", dest="subparser")
|
|
|
|
launch_parser = subparsers.add_parser("start", aliases=["launch"])
|
|
launch_parser.add_argument("app_name", help="AppName of the game to launch",
|
|
metavar="<App Name>", 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='<wine binary>',
|
|
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='<wine pfx path>',
|
|
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="<EGL Version>", action="store")
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.desktop_shortcut or args.startmenu_shortcut:
|
|
from rare.utils.paths import create_desktop_link
|
|
|
|
if args.desktop_shortcut:
|
|
create_desktop_link(app_name="rare_shortcut", link_type="desktop")
|
|
|
|
if args.startmenu_shortcut:
|
|
create_desktop_link(app_name="rare_shortcut", link_type="start_menu")
|
|
|
|
print("Link created")
|
|
return 0
|
|
|
|
if args.version:
|
|
from rare import __version__, __codename__
|
|
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)
|
|
|
|
from rare.utils import singleton
|
|
|
|
try:
|
|
# this object only allows one instance per machine
|
|
|
|
me = singleton.SingleInstance()
|
|
except singleton.SingleInstanceException:
|
|
print("Rare is already running")
|
|
from rare.utils.paths import lock_file
|
|
|
|
with open(lock_file(), "w") as file:
|
|
file.write("show")
|
|
file.close()
|
|
return -1
|
|
|
|
from rare.components import start
|
|
return start(args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# insert source directory if running `main.py` as python script
|
|
# Required by AppImage
|
|
if "__compiled__" not in globals():
|
|
sys.path.insert(0, str(pathlib.Path(__file__).parents[1].absolute()))
|
|
|
|
sys.exit(main())
|