Coder Social home page Coder Social logo

Comments (2)

erri120 avatar erri120 commented on July 18, 2024 1

Thanks for taking the time to write this up. Let's break this down and start with the big design decisions:

GameFinder history and design

I originally made this library for Wabbajack, but since then, it has been used in various other projects. However, almost all the dependents are modding related. Most of the time, the only thing they are interested in is the installation location. Once they have that, they start doing their own thing. This is why the *Game records only have 3 properties: an identifier, a name, and the installation path.

I did recently add some utility functions like SteamGame.GetManifestPath and EADesktopGame.GetInstallerDataFile which can be helpful for library consumers that need a bit more data.

The development of this library has been heavily influenced by the library consumers. So far, they only require the installation path, which is why GameFinder only returns the bare minimum. I know that a launcher requires more information. I've previously been involved with Playnite and know how much additional information it grabs from the various supported libraries.

More data

The core issue is that GameFinder doesn't know what data the consumer wants. Currently, GameFinder returns the absolute minimum. If you go back in time enough, you will actually find that previous versions of the library extracted almost everything. For Steam, it extracted all values from the .acf file, for EGS it deserialized the entire .json with all values into a class and for GOG it parsed all registry values.

I stopped doing that because it was hell to maintain. The GOG implementation would regularly break, because some registry keys wouldn't exist for some users, and Steam changed their format like three times within a month. Grabbing only the bare essentials makes the library easier to test and maintain.

That being said, what can be done? I would look into adding more utility functions. Provide the bare essentials and have some method that you can use to request more data.

However, it seems rather odd to force the library's client to reinvent the wheel of often re-parsing a file/regkey to get data that could easily have been collected the first time through in this library.

This is true for SteamGame.GetManifestPath which returns the path to the manifest that got parsed beforehand. However, how else should this API be designed? For Steam, it might be possible to deserialize the .acf file and put the deserialized object into the SteamGame object, however this might not work with everything. Take the EA Desktop implementation as an example. The decrypted file is just a JSON file, however I'm deserializing it into an object. If a consumer were to request more data, would the EADesktopGame have the entire JSON contents as a private field or something, that can be used to extract more information?

Also, something I forgot to write down in the docs: all the Store handler functions are pure functions. None of the store handlers have an internal mutable state. They are only classes because it makes configuring stuff easier using constructors. I'm very reluctant on adding state that can be mutated and accessed, if none of the library consumers are using it.

Access APIs or perform web scrapes to collect additional data.

I want to keep the library from accessing the web if possible. Furthermore, I'm considering adding the Origin API as a static helper method, but this won't be the default.

Ensure compatibility for existing clients of this library.

This isn't the Windows API or C++, we don't need a FindGames and FindGamesEx method to not break compatibility or the ABI. Following SemVar and providing good Changelogs with information on how to upgrade is sufficient.

Adding more store handlers

As pointed out before, GameFinder mostly followed the requests of library consumers, which were all modding tools. None of the additional stores, you have listed, have games supported by these tools. I recently marked the Xbox Game Pass implementation as deprecated, because no one was using it and maintaining it had become a chore.

This is another issue: I don't even use all of these stores. If something breaks, or someone requests a new store implementation, I have to install it and start researching. I hate the Epic Games Store and uninstalled it the moment I was done with it. I'm glad the implementation is still working, because I won't be installed the EGS any time soon.

If you want to add more store handlers to GameFinder, I suggest creating individual issues, where we can discuss the store in detail. Just note that I won't allow 20 new implementations any time soon. The current code base is rather small and most implementations are straight forward. Adding more store handlers and more complexity requires more tests and makes the library harder to maintain.

Individual store handler stuff

EA Desktop

Remove or revise the "Use the registry" alternative from the EA Desktop wiki. It seems backwards: are you suggesting to search all the user's disks for "installerdata.xml" files just to find the registry entries?

From the wiki:

Maybe you don't want to find every single game, or you only need a known amount of games. In this case, you can just use the registry key from the installerdata.xml file. Every EA game has a folder called __Installer which contains an installerdata.xml file which can give you the correct registry key [...]

This alternative is for tools that only need to find one or a handful of known games. As an example: let's assume you make a tool for Titanfall 2, and you need to find the installation path programmatically. My method of breaking the encryption might be a bit overkill. Instead, you can, as the tool programmer, open the installerdata.xml file on your machine and extract the registry key. This key can be hardcoded into the tool for a simple registry lookup to find the game installation location.

I'm not suggesting that the tool searches the entire disk for installerdata.xml, but rather the programmer just extracts the required information from their file. This registry key doesn't change.

GOG

Instead of the registry, use the SQLite database (%ProgramData%\GOG.com\Galaxy\storage\galaxy-2.0.db).

I didn't know this file existed, when I created my implementation. However, this an embedded application database, meaning the schema can change with every update. I'm also not so keen on bundling an SQLite client with the store handler. I might consider this, if this were the only method of accessing the required data, but at the moment, I don't see the benefit over using the registry. You can create a separate issue for this, but this would be very low priority.

Other stuff

Add GLC to the Other Implementation sections.

Will do. Also, a quick reminder: GameFinder uses the MIT license, which is very permissive but still requires preservation of copyright and license notices, meaning you have to include the copyright notice and the permission notice in all copies or substantial portions of the Software.

from gamefinder.

Nutzzz avatar Nutzzz commented on July 18, 2024

Thanks very much for the in-depth response. I thought you might feel that way to one extent or another, and I totally understand that point of view. I'll close this issue. Take care!

from gamefinder.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.