DavidoTek / ProtonUp-Qt

Install and manage GE-Proton, Luxtorpeda & more for Steam and Wine-GE & more for Lutris with this graphical user interface.
https://davidotek.github.io/protonup-qt
GNU General Public License v3.0
1.22k stars 40 forks source link

Improve info dialog for anti-cheat runtimes #186

Closed sonic2kk closed 8 months ago

sonic2kk commented 1 year ago

The ctinfo dialog for anti-cheat runtimes (tested with EasyAntiCheat runtime) displays the column headings as the default 1 and 2, and shows a blank compatibility tool count. This PR fixes that.

image

I'm not sure how the ctinfo dialog works for anti-cheat runtimes and if it can even get an accurate game count (I do not play games that use these anti-cheats), but it couldn't hurt to display consistent headings and show 0 for the game count :-)

DavidoTek commented 1 year ago

Thanks!

displays the column headings as the default 1 and 2, and shows a blank compatibility tool count. This PR fixes that.

That looks a lot cleaner, thanks.

I'm not sure how the ctinfo dialog works for anti-cheat runtimes and if it can even get an accurate game count

It can't detect which games use the runtime at the moment as it is not stored in the default "CompatToolMapping" in config.vdf. Though there probably is some way to determine it.

PS: Not sure if we should add this functionality in this PR or keep it in mind for another PR and already merge it now...

sonic2kk commented 1 year ago

I'm happy to leave this open and we can look into it in #190, then implement it here :-)

sonic2kk commented 1 year ago

One thing that occured to me: We could search in a game's files for easyanticheat_x86.so and easyanticheat_x64.so, at least for EAC. I am not sure what files battlEye uses.

The reason I suggest the .so files specifically is that these are Linux library files, so if a game includes them, there's a good chance it's getting them from the EasyAntiCheat Runtime from Steam. This doesn't guarantee anti-cheat compatibility as various games downloaded the runtime from Steam and included the files without actually enabling support/correctly implementing support (MCC did this).

The issue comes from trying to do this kind of check in a performant way. If there's an anti-cheat runtime installed, for each game we'd have to find its game folder (we can get that from the appmanifest, iirc we do a similar read of this file) and then we'd have to search for these anti-cheat files. This could be slow.

sonic2kk commented 1 year ago

Just noticed this PR apparently has no additions/deletions... I guess I messed something up at one point. Could open a new PR no problem though if we decide on a route to go down, or this could just be left - no one has reported this issue, and it may not be worth a performance penalty. Though perhaps somehow we could add some logic that will fetch the games list for anti-cheat runtimes when the info dialog is opened. That would mitigate a performance penalty on startup.

DavidoTek commented 1 year ago

One thing that occured to me: We could search in a game's files for easyanticheat_x86.so and easyanticheat_x64.so, at least for EAC. I am not sure what files battlEye uses.

What would be an option. But I guess there needs to be some other place where Steam knows from whether a game requires an anti cheat runtime or not.

there's a good chance it's getting them from the EasyAntiCheat Runtime from Steam

Does it get the .so files from the runtime? I thought they need to be included by the publisher, not 100% sure though...

The issue comes from trying to do this kind of check in a performant way

Yeah, I'm not sure whether the files are placed in a fixed folder or not. It may be different depending on the game engine used. Yes, doing a full search would be too slow...

Just noticed this PR apparently has no additions/deletions... [...] Could open a new PR

I think they were removed by commit https://github.com/DavidoTek/ProtonUp-Qt/pull/186/commits/6d56685f81957bf4b1151e4e816057bbf39c2992. We can add the changed again if needed, force push and squash commits will clean that up just fine :smile:

sonic2kk commented 1 year ago

But I guess there needs to be some other place where Steam knows from whether a game requires an anti cheat runtime or not.

This may be set in the depot (afaik depots can tell Steam which files to download, ), but I am not sure. I wonder if there's somewhere this could be asked, or if there is some Steamworks documentation that explains this... I couldn't find any after a quick search.

On SteamDB, Halo MCC's Additional Dependencies section lists AppID 1826330, which is the Proton EasyAntiCheat Runtime (you can also search for this AppID in your Steam library and it will show up.

I have looked around the game files for Halo MCC (the only game with EAC that I own, as it lets you run the game without EAC) and couldn't find anything in any manifest files referring to EAC either by the library name or AppID. appmanifest files also don't seem to list any information about anticheat runtimes.

This information may be solely stored in a game's depots. There may be an API to access this - though I couldn't find it on xPaw's Steam Web API, maybe it's just fetched from general depot information? Regardless, this may not be "ideal" and may also end up being slow.

Does it get the .so files from the runtime? I thought they need to be included by the publisher, not 100% sure though...

Initially, back when EAC support was announced, I assumed the files would be included by the publisher. But games that require EAC and have the support enabled for Linux, as far as I understand, will always download the EAC runtime from Steam. But since the library files aren't symlinked, either the files are copied (which would be... strange) or the games which have support enabled explicitly look in the runtime folder for the libraries it needs, and for some reason some games (at least MCC) bundle the EAC .so libraries with the game.


If all else fails we could potentially just use areweanticheatyet to mark installed games on its supported list. I thought ProtonUp-Qt downloaded a JSON of information from areweanticheatyet, but I couldn't find it (it's 2am though :bed:). Doing this may be faster than doing a lookup on the Steam web API, but may also not be a great solution, as we're not really fetching from the game files. We're just making an assumption based on a third-party database.

Maybe that's fine if we put a disclaimer somewhere, but it runs the risk of being out-of-date. We don't really need to worry if a game is "supported" as the games list should just list games which are set to use the EAC runtime, rather than games that use it properly (an important distinction compared to the Games List dialog). Doing the Steam Web API lookup on the other hand, if it's possible to do at all, should always be up-to-date because we're getting the game's listed dependencies right from the Steam depot. But doing an API call would be slower than parsing a JSON file...


Also, I'm talking about EAC here, but I assume the same idea would apply for battlEye. ARK: Survival Evolved lists 1161040 under its Additional Dependencies section, which corresponds to the Proton BattlEye Runtime. Unlike MCC, whose comment is "EAC runtime", ARK's is "project D" (project Deck? :wink:), so the comment is probably a field developers can fill out rather than being anything hard to go by.

As far as I know, though other anticheats support Proton, only EAC and battlEye have Proton runtimes on Steam as tools, so we would only need to consider these two no matter which route we go down.

DavidoTek commented 1 year ago

This may be set in the depot (afaik depots can tell Steam which files to download, ), but I am not sure. I wonder if there's somewhere this could be asked

Hmm, I wonder who could know about this.

On SteamDB, Halo MCC's Additional Dependencies section lists AppID 1826330, which is the Proton EasyAntiCheat Runtime

Okay, I guess if it is listed as a dependency, we can also assume it is using it...

Regardless, this may not be "ideal" and may also end up being slow.

Yeah, having a local (cached) file would be great.

Initially, back when EAC support was announced, I assumed the files would be included by the publisher

Oh, I assumed that too. According to https://github.com/Heroic-Games-Launcher/HeroicGamesLauncher/issues/1513, Proton somehow loads the runtime using PROTON_EAC_RUNTIME, interesting.

I thought ProtonUp-Qt downloaded a JSON of information from areweanticheatyet, but I couldn't find it

It's stored in the temporary directory as awacy_games.json

We're just making an assumption based on a third-party database. Maybe that's fine if we put a disclaimer somewhere, but it runs the risk of being out-of-date

It might be missing some games. I don't think it would be that big of a deal since it's only for informational purposes anyway. Not sure.

Unlike MCC, whose comment is "EAC runtime", ARK's is "project D" (project Deck? wink

Interesting choice :smile:

only EAC and battlEye have Proton runtimes on Steam as tools

Yes, I think other anti cheats either don't care (GTA V) or straight up block Linux/use some sort of NT-Kernel module.

sonic2kk commented 9 months ago

Okay, progress!

It turns out we can get information about which games are using, at least, the Proton EasyAntiCheat Runtime, from appinfo.vdf. We can access it like this (although we'd probably use .get): steam_app['data']['appinfo']['extended']['additional_dependencies']

For Halo MCC, this is what comes back for me:

{'0': {'src_os': 'windows', 'dest_os': 'linux', 'appid': 1826330, 'comment': 'EAC runtime'}}

The 0 just so happens to be the EAC runtime here. There is likely no reason that it has to be 0, but in a lot of cases, it appears to be. The comment also appears to always be EAC runtime, but we should instead check on the AppID. Looking at SteamDB, it seems many apps use 0, but we should still loop through and fetch on the appid == 1826330. Below are some examples of games using the EAC/battlEye Proton runtime, you can see their additional_dependencies section, all of these using 0.

We could additional_dependencies on our Steam app class, and for our dialog, we can loop through and check if 1826330 is used -- This is the Proton EasyAntiCheat Runtime AppID.

In short, we can loop through all the dictionaries in additional_dependencies in an appinfo.vdf app entry, if it exists, and then determine if it's using EAC etc. We could store all of additional_dependencies on our Steam App object, and/or store a boolean flag to denote if a game is using EAC/battlEye runtimes. These are the only ones relevant to ProtonUp-Qt for now, since we're only listing them because they have dedicated Proton runtimes. So we don't have to care about games which may have other anti-cheats that are supported on Linux unless they ever get their own runtime.

This means we could have three new values on a Steam App object: uses_eac_runtime: bool, uses_battleye_runtime: bool, and additional_dependencies: dict. This is separate to an app which may install Easy Anti-Cheat, since we're checking for the Proton EasyAntiCheat Runtime, so we can be pretty sure any apps using this are ones that are targetting the Proton runtime and not just generally using EAC.

Although it's important to note: This says nothing about app compatibility, a game may mark the Proton EAC Runtime as a dependency but not properly support it yet, or support may break with updates, etc. If we display this information we are solely displaying "This app has marked that it wants to download the EAC runtime", more or less.


I hope this made sense, basically we can get the information about which apps are using which aren't using the appinfo.vdf's additional_dependencies section, and checking for the EAC/battlEye AppIDs. We could do this when the dialog is clicked or, probably better, we could store this information in some way on the Steam app object when we're fetching Steam app information.

For cleanliness I will probably close this PR soon and then work on a new one which had the original UI improvements, and then add information about which games are using which runtimes. But I'd like to hear your thoughts on how we should approach it. I can't remember exactly how we fetch app information but I believe there's a loop somewhere where we already do some checks/filtering, such as filtering out soundtracks, so this check would probably go here. Or maybe we would have to store information about which AppIDs are using the runtime on the runtime compatibility tool itself as a list, I'm not sure, it's been a while :sweat_smile:

DavidoTek commented 9 months ago

We could store these AppIDs as constants in constants.py, and store information about what anti-cheats a Steam app is using on our Steam app objects in some way.

Sounds good. I think there's already a hardcoded App ID somewhere in the source code, but putting it in constants.py seems to be a good idea.

We could additional_dependencies on our Steam app class, and for our dialog, we can loop through and check if 1826330 is used This means we could have three new values on a Steam App object: uses_eac_runtime: bool, uses_battleye_runtime: bool, and additional_dependencies: dict.

I wonder when we should do the looping. There are two options:

I think the second one is way cleaner, but I'm not sure how long it would take for users with thousands of games and how long additional_dependencies might get. Python isn't that slow either so it should be ok.

I can't remember exactly how we fetch app information but I believe there's a loop somewhere where we already do some checks/filtering

This is it: https://github.com/DavidoTek/ProtonUp-Qt/blob/4d6eb493086169a71934903c0400a1f314326097/pupgui2/steamutil.py#L43-L95 The filtering with infos from appinfo.vdf is done here: https://github.com/DavidoTek/ProtonUp-Qt/blob/4d6eb493086169a71934903c0400a1f314326097/pupgui2/steamutil.py#L247-L286

sonic2kk commented 8 months ago

I'm working on an implementation for this which I'll open in a new PR in the near-enough future with some luck. The implementation for it feels a little bit messier than I would like, or at least keeping track of it logically in my own head is a bit tough, so I'll spend some more time on it and open a PR once I have something for review :-)