Skip to content

Commit

Permalink
Merge pull request #455 from loathingKernel/develop
Browse files Browse the repository at this point in the history
Locate and use anticheat runtimes from Steam with Proton
  • Loading branch information
loathingKernel authored Sep 19, 2024
2 parents 57ca61f + 997dc23 commit a24f190
Show file tree
Hide file tree
Showing 25 changed files with 82 additions and 17 deletions.
2 changes: 1 addition & 1 deletion rare/components/tabs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from rare.utils.misc import qta_icon, ExitCodes
from .account import AccountWidget
from .downloads import DownloadsTab
from .games import GamesLibrary
from .library import GamesLibrary
from .settings import SettingsTab
from .store import StoreTab
from .tab_widgets import MainTabBar, TabButtonWidget
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@
)
from rare.shared import RareCore
from rare.models.options import options
from .game_info import GameInfoTabs
from .game_widgets import LibraryWidgetController, LibraryFilter, LibraryOrder, LibraryView
from .game_widgets.icon_game_widget import IconGameWidget
from .game_widgets.list_game_widget import ListGameWidget
from .details import GameInfoTabs
from .widgets import LibraryWidgetController, LibraryFilter, LibraryOrder, LibraryView
from .head_bar import LibraryHeadBar
from .integrations import IntegrationsTabs

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
from rare.shared.workers.wine_resolver import WinePathResolver
from rare.ui.components.tabs.games.integrations.egl_sync_group import Ui_EGLSyncGroup
from rare.ui.components.tabs.games.integrations.egl_sync_list_group import Ui_EGLSyncListGroup
from rare.utils.compat import utils as compat_utils
from rare.widgets.elide_label import ElideLabel
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
QPushButton,
)

from rare.utils.misc import qta_icon, widget_object_name
from rare.utils.misc import qta_icon
from rare.widgets.elide_label import ElideLabel


Expand Down
2 changes: 2 additions & 0 deletions rare/components/tabs/settings/rare.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ def __init__(self, parent=None):
self.ui.confirm_start.stateChanged.connect(
lambda: self.settings.setValue(options.confirm_start.key, self.ui.confirm_start.isChecked())
)
# TODO: implement use when starting game, disable for now
self.ui.confirm_start.setDisabled(True)

self.ui.auto_sync_cloud.setChecked(self.settings.value(*options.auto_sync_cloud))
self.ui.auto_sync_cloud.stateChanged.connect(
Expand Down
6 changes: 3 additions & 3 deletions rare/models/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from rare.shared.image_manager import ImageManager
from rare.utils.paths import data_dir, get_rare_executable
from rare.utils.steam_grades import get_rating
from rare.utils.config_helper import set_envvar
from rare.utils.config_helper import set_envvar, get_option

logger = getLogger("RareGame")

Expand Down Expand Up @@ -567,9 +567,9 @@ def launch(
cmd_line = get_rare_executable()
executable, args = cmd_line[0], cmd_line[1:]
args.extend(["launch", self.app_name])
if offline:
if offline or get_option(self.app_name, "offline", fallback=None):
args.append("--offline")
if skip_update_check:
if skip_update_check or get_option(self.app_name, "skip_update_check", fallback=None):
args.append("--skip-update-check")
if wine_bin:
args.extend(["--wine-bin", wine_bin])
Expand Down
2 changes: 1 addition & 1 deletion rare/resources/static_css/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x1a\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01\x906&\x0a\x17\
\x00\x00\x01\x92\x09g[\xe6\
"

def qInitResources():
Expand Down
8 changes: 4 additions & 4 deletions rare/resources/static_css/stylesheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def css_name(widget: Union[wrappertype, QObject, Type], subwidget: str = ""):


# ProgressLabel
from rare.components.tabs.games.game_widgets.library_widget import ProgressLabel
from rare.components.tabs.library.widgets.library_widget import ProgressLabel
css.QLabel[css_name(ProgressLabel)].setValues(
borderWidth="1px",
borderRadius="5%",
Expand All @@ -93,7 +93,7 @@ def css_name(widget: Union[wrappertype, QObject, Type], subwidget: str = ""):


# IconGameWidget
from rare.components.tabs.games.game_widgets.icon_widget import IconWidget
from rare.components.tabs.library.widgets.icon_widget import IconWidget
icon_background_props = {
"backgroundColor": "rgba(0, 0, 0, 65%)",
}
Expand Down Expand Up @@ -135,7 +135,7 @@ def css_name(widget: Union[wrappertype, QObject, Type], subwidget: str = ""):


# ListGameWidget
from rare.components.tabs.games.game_widgets.list_widget import ListWidget
from rare.components.tabs.library.widgets.list_widget import ListWidget
css.QLabel[css_name(ListWidget, "TitleLabel")].fontWeight.setValue("bold")
list_status_label_props = {
"color": "white",
Expand All @@ -155,7 +155,7 @@ def css_name(widget: Union[wrappertype, QObject, Type], subwidget: str = ""):


# SelectViewWidget
from rare.components.tabs.games.head_bar import SelectViewWidget
from rare.components.tabs.library.head_bar import SelectViewWidget
css.QPushButton[css_name(SelectViewWidget, "Button")].setValues(
border="none",
backgroundColor="transparent",
Expand Down
70 changes: 68 additions & 2 deletions rare/utils/compat/steam.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,32 @@ def appid(self) -> str:
return self.appmanifest["AppState"]["appid"]


@dataclass
class SteamAntiCheat:
steam_path: str
tool_path: str
steam_library: str
appmanifest: Dict

def __eq__(self, other):
return self.tool_path == other.tool_path

def __hash__(self):
return hash(self.tool_path)

@property
def name(self) -> str:
return self.appmanifest["AppState"]["name"]

@property
def appid(self) -> str:
return self.appmanifest["AppState"]["appid"]


@dataclass
class ProtonTool(SteamRuntime):
runtime: SteamRuntime = None
anticheat: Dict[str, SteamAntiCheat] = None

def __bool__(self) -> bool:
if appid := self.required_tool:
Expand All @@ -121,6 +144,7 @@ def command(self, verb: SteamVerb = SteamVerb.DEFAULT) -> List[str]:
class CompatibilityTool(SteamBase):
compatibilitytool: Dict
runtime: SteamRuntime = None
anticheat: Dict[str, SteamAntiCheat] = None

def __bool__(self) -> bool:
if appid := self.required_tool:
Expand All @@ -147,6 +171,33 @@ def find_appmanifests(library: str) -> List[dict]:
return appmanifests


ANTICHEAT_RUNTIMES = {
"eac_runtime": "1826330",
"battleye_runtime": "1161040",
}


def find_anticheat(steam_path: str, library: str):
runtimes = {}
appmanifests = find_appmanifests(library)
common = os.path.join(library, "common")
for appmanifest in appmanifests:
if appmanifest["AppState"]["appid"] not in ANTICHEAT_RUNTIMES.values():
continue
folder = appmanifest["AppState"]["installdir"]
runtimes.update(
{
appmanifest["AppState"]["appid"]: SteamAntiCheat(
steam_path=steam_path,
steam_library=library,
appmanifest=appmanifest,
tool_path=os.path.join(common, folder),
)
}
)
return runtimes


def find_runtimes(steam_path: str, library: str) -> Dict[str, SteamRuntime]:
runtimes = {}
appmanifests = find_appmanifests(library)
Expand Down Expand Up @@ -257,7 +308,7 @@ def get_runtime(
return runtimes.get(required_tool, None)


def get_ulwgl_environment(
def get_umu_environment(
tool: Optional[ProtonTool] = None, compat_path: Optional[str] = None
) -> Dict:
# If the tool is unset, return all affected env variable names
Expand Down Expand Up @@ -287,6 +338,8 @@ def get_steam_environment(
environ["STEAM_COMPAT_LIBRARY_PATHS"] = ""
environ["STEAM_COMPAT_MOUNTS"] = ""
environ["STEAM_COMPAT_TOOL_PATHS"] = ""
environ["PROTON_EAC_RUNTIME"] = ""
environ["PROTON_BATTLEYE_RUNTIME"] = ""
return environ

environ["STEAM_COMPAT_CLIENT_INSTALL_PATH"] = tool.steam_path
Expand All @@ -299,6 +352,11 @@ def get_steam_environment(
if tool.runtime is not None:
tool_paths.append(tool.runtime.tool_path)
environ["STEAM_COMPAT_TOOL_PATHS"] = ":".join(tool_paths)
if tool.anticheat is not None:
if (appid := ANTICHEAT_RUNTIMES["eac_runtime"]) in tool.anticheat.keys():
environ["PROTON_EAC_RUNTIME"] = tool.anticheat[appid].tool_path
if (appid := ANTICHEAT_RUNTIMES["battleye_runtime"]) in tool.anticheat.keys():
environ["PROTON_BATTLEYE_RUNTIME"] = tool.anticheat[appid].tool_path
return environ


Expand All @@ -317,6 +375,10 @@ def _find_tools() -> List[Union[ProtonTool, CompatibilityTool]]:
for library in steam_libraries:
runtimes.update(find_runtimes(steam_path, library))

anticheat = {}
for library in steam_libraries:
anticheat.update(find_anticheat(steam_path, library))

tools = []
for library in steam_libraries:
tools.extend(find_protons(steam_path, library))
Expand All @@ -325,6 +387,8 @@ def _find_tools() -> List[Union[ProtonTool, CompatibilityTool]]:
for tool in tools:
runtime = get_runtime(tool, runtimes)
tool.runtime = runtime
if tool.layer == "proton":
tool.anticheat = anticheat

tools = list(filter(lambda t: bool(t), tools))

Expand Down Expand Up @@ -353,10 +417,12 @@ def find_umu_launcher() -> Optional[CompatibilityTool]:
from pprint import pprint

tools = find_tools()
pprint(tools)
for tool in tools:
pprint(tool)
umu = find_umu_launcher()
pprint(umu)


for tool in tools:
print(get_steam_environment(tool))
print(tool.name)
Expand Down

0 comments on commit a24f190

Please sign in to comment.