1
0
Fork 0
mirror of synced 2024-05-20 04:22:58 +12:00
Rare/rare/main.py
loathingKernel 88b6e91530 BrowserLogin: Add dedicated application mode to Rare for the webview login page
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.
2024-02-12 21:51:42 +02:00

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())