solaire / glc Goto Github PK
View Code? Open in Web Editor NEWLightweight, console-based, tool which automatically detects installed games and displays them to the user.
License: GNU General Public License v3.0
Lightweight, console-based, tool which automatically detects installed games and displays them to the user.
License: GNU General Public License v3.0
There should be a nice piece of documentation describing the overall app functionality, some technical stuff for more complex pieces of code as well as the usage (so the supported commands and key-bindings).
We should probably use GitHub's wiki feature
One example would be to prompt the user, e.g., with the provided command-line "mame.exe {?}", the user would be prompted to enter a rom name.
EDIT: Now that there's a file browser, perhaps "mame.exe {%}" would allow the user to choose a file from the filesystem as a parameter. In this case you'd want it without an extension; maybe another symbol, e.g., {*} includes the extension. And we'd want to have a default rom path in the database for such uses. (I think we already covered that in the SQLite db).
Capturing the one issue I had in my fork:
Nutzzz#1
Relying on the Windows Uninstall registry is not ideal when game libraries can be used without it (e.g., after reinstalling Windows, you can just point Steam at an existing library [without reinstalling the games]).
To work around this, we're now ingesting files for Epic, itch, Steam, and Origin. The first 3 seem to be fairly complete solutions at this point, but Origin must currently rely on FindGameBinaryFile() to find the .exe (though if it is in the uninstall registry, it should be able to get it from there).
I've done some research for other platforms which I'll add in the comments.
Since launchers are currently required to install games and perform maintenance tasks, allow launching Steam, Epic Game Store, etc. directly.
With Epic games, we're currently launching straight from the game's .exe. This is great because (at least on my system) Epic takes forever to load and start a game. However, cloud saves aren't synchronized in this case, and I believe some games have issues with online multiplayer with this method [note to self: check whether this affects Origin, etc.].
Obviously we could (optionally) switch to using the Epic protocol to do the launching (com.epicgames.launcher://).
Another solution that addresses the slow response and games requiring Epic for online play is to allow users to (optionally) use Legendary, a lite command-line Epic client written in Python and compiled to .exe. However, note that syncing isn't automatic there either, and requires a separate command, i.e., you'd need to (optionally) run sync-saves, launch, then sync-saves again.
Not sure how this would be implemented as we move to the 2.0 plugin model (i.e., a separate Legendary plugin and/or plugin-specific configuration options [PlatformAttribute]).
I can't figure out a consistent way (i.e., without guessing URLs from titles) to get images from Epic. We could get them from another source (e.g., #53 ), but similar inexact title-matching applies.
For the proposed GLC2 (cmus-like) interface, since there's some extra unused real estate if images are enabled (assuming the image doesn't just overlay text in the pane), I'm thinking there's perhaps some room to spread out information instead of just using a single-line infobar (I'm imagining that the infobar would be hidden when the infopane is shown).
As pictured in the mock-up below, this could also include info pulled from igdb (for which I'll create a separate issue if we decide to do this).
e.g., in the pic above see "*Venetica - Gold Edition" and "*Sanitarium" (the two not-installed games, which should all be listed at the bottom with the other non-installed games. I believe I only see this behavior when new games are added to an existing set of games. After quitting and going back in, sorting appears to be OK again.
The insert mode should probably look similar to vim's minibuffer at the bottom of the page. When the user is in navigation mode, the buffer could show important information about the game or platform.
The insert mode should support the following features:
Should the app be able to connect to online services (such as Humble bundle, Riot games, etc)? I am unsure of the work required and the overall benefit.
Also should the app support signing in into clients such as steam and get a list of all games for the user. This would in theory allow the app to manage all of the user's games and perhaps even allow installation.
Marking this a question since I am unsure what overall benefit there is to this feature as well as the required work (I'm not even 100% sure this is possible with each and every platform, though I think PlayNite does something like that)
Perhaps a game that has not yet been given a user rating should be sorted as a 2.5 out of 5 stars, so that 1 and 2-star games are sorted below them.
This might potentially be accomplished by giving an unsorted item a value of 3, and 1 and 2 star ratings are internally 0 and 1, respectively. Or we could just leave unrated as 0 and have a more complicated sort algorithm.
Using JSON to store information about the games has worked quite well, but I don't feel like it's the best approach. Those are some of the constraints I have observed:
A lightweight database implementation will bring the following benefits:
The best candidate for this feature is liteDB which apparently only requires a small DLL
The following features will need to be implemented:
Refer to the 'Database migration' projects page for bugs and user stories
Requires a move to unique ID if title can be changed (finishing #6 should be sufficient)
It looks like EA is finally deprecating the Origin app/branding in favor of EA Desktop which has been in beta for some time. IIRC, this may only be a cosmetic change for us.
Each game should be able to support N number of tags and aliases.
An alias is:
A tag is:
This extension of the existing functionality should probably be implemented after the database implementation is done (otherwise it would have to be implemented twice)
This seems to be a sort issue. Since we have the info bar now, we can see when the highlighted game doesn't match up with the actual selection. It's possible this is the cause of #36.
This is really just a reminder for myself, I'll take a look when I get a chance.
I had a platform selected, but the behavior does not appear to be consistent.
Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
at GameLauncher_Console.CConsoleHelper.HandleNavigationMenu(Int32 nStartY, Int32 nStopY, ConfigVolatile cfgv, Hotkeys keys, Colours cols, Boolean setup, Boolean browse, String& game, String[] options) in C:\Users\enuss\source\repos\GLC\GameLauncher_Console\GameLauncher_Console\ConsoleHelper.cs:line 0
at GameLauncher_Console.CConsoleHelper.DisplayMenu(ConfigVolatile cfgv, Hotkeys keys, Colours cols, String& game, String[] options) in C:\Users\enuss\source\repos\GLC\GameLauncher_Console\GameLauncher_Console\ConsoleHelper.cs:line 511
at GameLauncher_Console.CDock.MenuSwitchboard(ConfigVolatile cfgv, Hotkeys keys, Colours cols, Boolean& setup, Boolean& browse, String& path, String& gameSearch, Int32& nSelectionCode) in C:\Users\enuss\source\repos\GLC\GameLauncher_Console\GameLauncher_Console\Dock.cs:line 1021
at GameLauncher_Console.CDock.MainLoop(String[] args) in C:\Users\enuss\source\repos\GLC\GameLauncher_Console\GameLauncher_Console\Dock.cs:line 283
at GameLauncher_Console.Program.Main(String[] args) in C:\Users\enuss\source\repos\GLC\GameLauncher_Console\GameLauncher_Console\Program.cs:line 34
Yet another launcher. It's interesting and controversial what they're doing, but it's finally available in the U.S., and it looks easy enough to do. Again, I'll be adding it to GameCollector first. EDIT: See GameCollector4 branch.
Recently I started seeing this exception:
ERROR: Could not convert string to DateTime: 1977-**-**. Path 'pid.dob', line 9, position 24. | Newtonsoft.Json
at Newtonsoft.Json.JsonReader.ReadDateTimeString(String s)
at Newtonsoft.Json.JsonReader.ReadAsDateTime()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)
at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType)
at Newtonsoft.Json.Linq.JToken.ToObject[T]()
at PureOrigin.API.OriginAPI.GetInternalUser()
at PureOrigin.API.OriginAPI.LoginAsync()
at GameLauncher_Console.PlatformEA.GetOwnedGames(String email, SecureString password, String id) | API error for EA owned games.
The exception is in PureOrigin.API, a NuGet package that I added originally to get owned not-installed Origin games, but after #66 was resolved, it's now only used to get the proper game titles for EA Desktop. However, it looks like EA just altered their API slightly so now the user's birthdate shows ** for month and day, and since this is no longer a valid value for a DateTime, PureOrigin.API is hitting an Exception (and yes, I'm 45 years old). It's an easy fix to comment out the birthdate field or change it to a string (and I've done the latter in a fork). Unfortunately, PureOrigin.API was recently archived by its author, so I can't submit a pull request.
Of the various methods of how to proceed from here, I think I'm leaning towards adding PureOrigin.API as a subtree and a dependent project of the solution. I'll make a separate PR [ #70 ].
Would be nice to get a unit test project going so that bugs and new features could be tested more efficiently.
Not sure how this interacts with shortcuts in customGames. I assume these will be added to the database after #6 .
Suggestions:
done:
If, e.g., the user changes a game's rating while in rating-sort mode, the selection should move to the game's new position.
Thanks for posting v1.2.0, @Solaire !
Note, however, that we don't need all of the stuff you've included in the .rar, as the .exe that is the result of the dotnet publish is all that's necessary for a release (since we're setting PublishSingleFile and IncludeNativeLibrariesForSelfExtract in the .csproj to True). The downside of this approach is that a RuntimeIdentifier must be specified so you don't get the "AnyCPU" possibility (and I've set it to win-x86 instead of -x64 for... reasons).
Note that I've played with these related settings and SelfContained, PublishTrimmed, and PublishReadyToRun need to be set to false.
IncludeAllContentForSelfExtract could be set to true for release but it makes debugging harder.
I've also set EnableCompressionInSingleFile to true, which isn't supported in .NET 5, but looks like a nice feature in .NET 6.
While I'm looking at this, it looks like we should probably remove the BootstrapperPackage includes for .NET Framework 4.7.2 and 3.5.
Should the app be re-implemented in C++?
Pros:
Cons:
As described in #18 we sometimes need to rely on FindGameBinaryFile() for icons at least, e.g.:
Pretty much all of the major features have been implemented into the console version. Work could be started on a GUI version - this version would use most of the existing backend logic while adding support for things such as:
In the description of 1.1.0 release, it mentions "/" is the default key to switch to insert mode. Actually, "\" switches to insert mode, while "/" (or F3) does a search (the latter being much better at the moment since it does fuzzy searches).
Tested on the version 1.1.0.0
I'm sorry for not testing it on a newer version but the 1.2.0.0 is no more standalone (#58) and don't work on my machine anymore
Is your feature request related to a problem? Please describe.
Steam allows to use multiple folders for installing & storing games.
If I'm not mistaking, GLC scan only for the first one so games from the second (or third, ...) location are never found.
In the Steam UI, you can find it in settings > Download :
In the system file, the information can be found (and parse) here :
C:\Program Files (x86)\Steam\config\libraryfolders.vdf
Describe the solution you'd like
I would like that GLC scan all Steam folders so no games are left behind :)
EDIT :
Reading this file :
When looking for the logs, I saw that :
06/11/2022 18:00:49 : ERROR: La clé donnée était absente du dictionnaire. | mscorlib à System.ThrowHelper.ThrowKeyNotFoundException()
à System.Collections.Generic.Dictionary`2.get_Item(TKey key)
à GameLauncher_Console.CRegScanner.GetSteamGames(List`1 gameDataList, Boolean expensiveIcons) | ERROR: Malformed STEAM file: C:\Program Files (x86)\Steam\steamapps\libraryfolders.vdf
Might be another issue then... don't hesitate to close this one if not appropriate.
Many thanks for your hard work! 🙌
After user-initiated scan is complete, the app should display all newly added games in a separate category 'New Games' to allow the user to see which games have been discovered and modify aliases, tags and flags without having to manually seek them out.
The 'New Games' category should be temporary, only shown after scanning and should disappear when the application is launched next time
I have been porting the platform game detection to separate plugin projects (plus refactoring to improve overall code quality), and it got me thinking about support for non-installed games?
As far as I'm aware many platforms don't support installing games outside of their client (a quick google search for Steam got me nothing). Even if the big ones (Steam, Gog, Epic) offer some way, we can't guarantee that all will.
That brings me to my question. Should be support non-installed games? Given the above, I don't see the benefit of showing them to the user, since they can't really do anything with them. In version 2 of the app, uninstalled games will be kept in the database to preserve the statistics and the settings, but won't be shown in the app until the user installs them again.
At the moment, any code with access to the CGame class is able to increment and decrement the frequency counters of an instance. While it's not something urgent, it would be a safe and good practice to encapsulate the two functions 'IncrementFrequency()' and 'DecimateFrequency()' so that they can only be called from the outer CGameData class (similarly to how the class can only instantiated from CGameData)
Some suggestions:
I'd like to start working on version 2.0 of GLC. The reason it's 2.0 and not 1.x is mostly due to a brand new TUI and moving from .NET framework to .NET core (more details below). I will be doing some research into it but I think I would like to basically re-write GLC as a new .NET core project (obviously the original project will remain here until we are happy with 2.0) - also I think I have been away from the project for so long that I'm finding it quite difficult to actually implement new features. So here is my proposal for version 2.0 features and changes:
In terms of the work required, I don't think it'll be too much since a lot of the features have been implemented and can be copied over (as much as .NET core will allow it that is) and some stuff will not be needed due to the SQL handling searching and sorting.
@Nutzzz Let me know what do you think about the idea as a whole. I might have missed some important features
Steam's website now requires a login or API key to view public user profiles.
My solution in GameCollector's Steam handler was to (optionally) use SteamWebAPI2, but this requires the user to create an API key. Note that I previously tried this in GLC, and the code is still there but commented out.
As you, @Solaire , have mentioned a few times, the idea for GLC 2.0 is to separate platforms into plugins. I've got a couple of questions:
What will this look like in practice, i.e., do you have the idea that this will be like Playnite or GOG Galaxy, where these are going to be maintained in separate repositories (potentially by separate individuals)? How will users discover these plugins? Would the user have to download each separately, and copy them to their plugin folder? We could have various built-in automation methods and/or websites to handle these things, but that seems like it adds a lot of work for both us and our users for minimal benefit.
Note that the EA Desktop fix for #66 was based mostly on GameFinder's wiki, but not so much on its code. After examining it further, however, I found there were a lot of aspects that I liked, and thought it would be nice to use its various NuGet packages as references (there are separate ones for each store handler). I thought this would simplify things for us, and it would be nice to share the burden of discovering/fixing breaking changes for the various launchers/APIs. But the current implementation is rather limited for our purposes, and it only supports a few platforms. In this issue, I asked to what extent @erri120 would be interested in--with my help--increasing the scope of his project for uses like ours, and he was, quite understandably, loath to do so. So I've been toying with a rebranded fork (with attribution) of his project here: GameCollector. I'm learning some new tricks from examining his code, and I've started by moving to a generic record type with more fields, and adding additional handlers. However, at this point I'm wondering how well this might or might not dovetail with your plans for GLC2.
Even though the .json shows the appropriate escaped code (e.g., \u00AE or \u2122), when titles are displayed, ® (R) becomes "r", ™ (TM) becomes "T".
This is despite "Console.OutputEncoding = System.Text.Encoding.UTF8;" in Program.cs.
IIRC, prior to 1.1.0 these characters were displayed correctly.
Though games that had been installed with Origin continue to work in the EA app, it looks like EA has changed the method of storing data so GLC is now not detecting newly installed games as installed.
GameFinder's wiki offers a couple of solutions.
I'm not sure whether it's OK to leave it as-is, but It seems a little strange to use, e.g., only two letters on the command-line and automatically start a game that may or may not be the expected one.
The app should allow the user to export multiple games as shortcuts to a given location. Initially, the implementation would only work on single games or a folder (eg. steam) but in the future it could handle selecting multiple games a a time (would need additional features in navigation mode)
This prevents confusion with the Linux launcher. Also, for what it's worth, you can point the "Social preview" to GLC_Social.png (was meant as a stand-in, but it works for now).
Making sure this issue is captured from my fork (Nutzzz#1):
Relying on the Windows Uninstall registry is not ideal when game libraries can be used without it (e.g., after reinstalling Windows, you can just point Steam at an existing library [without reinstalling the games]).
EDIT: I managed to come up with solutions by ingesting files/databases for Steam, Epic, itch, Amazon, Origin, and Indiegala (though Origin is currently only a partial solution since I'm not currently getting the .exe name unless the uninstall entry also exists, and FindGameBinaryFile(), especially in its current state, gets the wrong .exe a lot of the time. And Indiegala currently always relies on FindGameBinaryFile().
Investigations into the other platforms are in the comment below.
This is really just a reminder for myself, I'll take a look when I get a chance.
This feature is partly implemented. To test the current state, set num_list_icons_max_size_in_characters to 2, and flag_single_column_list_is_default to True (for the latter, you can also use the ] or [ keys to switch between grid and list).
Unfortunately, it seems we need to redraw all icons below the currently chosen position when moving up and down the list. It can take a while for Windows to cache all the icons, but given that it (sometimes) works pretty well.
Current issues:
Hi,
Might be a little bit related to this issue : #44
As a developer, I want to build a frontend based on games detected by GLC and stored on glc-games.json which display games metadatas (mostly images but why not rating, ...).
Add a command line support to launch a new process "fetchForGameMetadata"
This process would do the following:
NB : the DB dump don't give image urls, however, we can guess it with ID.
God of War => id = 96733
Image => https://cdn.thegamesdb.net/images/thumb/boxart/front/96733-1.jpg
Based on this page https://thegamesdb.net/stats.php it will work 98.54% of the time (boxart-front).
Thanks a lot for your awesome work, you guys rocks! I've a small personnal project to build a light TV frontend to launch games which support game pad controller, touch inputs,... I could not do it without your works. FYI, not finished, need to be opensourced.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.