[Shield Android TV General] spauldhaliwal:
We all know that we can add custom games to Geforce Experience in order to stream games to our Shields that are not officially supported by Nvidia. Last year, Nvidia added the ability to display Gamestream game shortcuts directly on our home screens. Unfortunately, for whatever reason, they did not carry this ability forward for custom games that have been added to Geforce Experience, but only to the officially supported ones. After a lot of digging around, here’s a way to circumvent this limitation. It’s important to note that this method bypasses the ‘Add Custom Games’ function in Geforce Experience, in order to have our games appear as officially supported ones. And now, a warning: this guide is long. It’s long because the process is long, but it’s also long because I’ve never been good at concisely explaining things. ¯\_(ツ)_/¯.

Now, navigate to:

\Users\YourUserName\AppData\Local\Nvidia\NvBackend\ApplicationOntology\data\

Here you will find a file called fingerprint.db. This is an XML file that contains information on all of Nvidia’s officially supported games. Inside you will find entries such as the following:

<Fingerprint name='the_witcher_3'>
<DisplayName>The Witcher 3: Wild Hunt</DisplayName>
<Version name='steam'>
<CMSID>10534111</CMSID>
<CMSVersion>1</CMSVersion>
<Distributor>Steam</Distributor>
<Files>
<File name='bin\x64\witcher3.exe' />
<File name='bin\ddi\Steam.dll' />
</Files>
<Hypersampling>0</Hypersampling>
<HypersamplingFactors>2;4</HypersamplingFactors>
<Icon>bin\x64\witcher3.exe</Icon>
<Image>bin\x64\witcher3.exe</Image>
<IsAutomatable>1</IsAutomatable>
<IsStreamingSupported>1</IsStreamingSupported>
<Launch>start steam://rungameid/292030</Launch>
<SteamAppIds>
<id>292030</id>
<id>124923</id>
</SteamAppIds>
<StreamingAutomatedLaunch>0</StreamingAutomatedLaunch>
<StreamingCaption>The Witcher 3: Wild Hunt</StreamingCaption>
<StreamingClassName>W2ViewportClass</StreamingClassName>
<StreamingCmdLine>start steam://rungameid/292030</StreamingCmdLine>
<WhisperModePopsFactor>0.588</WhisperModePopsFactor>
</Version>
</Fingerprint>

It’s fairly obvious what most of the tags inside this entry are for. The most important one, however, is the CMSID tag. This is the id number that Nvidia identifies your game with and uses to launch in GameStream. Also take note of the Files tag. In here you will find the files that Nvidia is looking for when scanning for new games.

I’ll also point out here that when you launch an officially supported GameStream game on your Shield, the shortcuts that are created on the homescreen are actual self contained apps.

The method of this guide is fairly straightforward:

1) We make an new entry in fingerprint.db with a custom CMSID, and fill out the rest of the information inside our entry to ensure that our game is detected and launched properly.

2) We extract one of the apks for the GameStream shortcut apps that are on our Shield’s homescreen, and copy this apk to our pcs.

3) We replace every instance of the old CMSID in the apk with our newly created CMSID, then recompile the apk and install it on our Shields.

Once this is done your newly installed shortcut app will launch your game as defined in the new entry you made in fingerprint.db. One thing to point out is that Geforce Experience overwrites fingerprint.db frequently (how frenquently, I don’t know.) I’ve changed this file to be read-only (via the security tab) on my system, which I hope will stop it from being overwritten. As a backup, I keep all of my custom entries in fingerprint.db backed up in a separate file, which I will simply append to the original database if the above method doesn’t work. (not sure how Window’s permission policies work.)

I’m not going to write a step-by-step guide here, but rather describe the game I’m launching and go from there. I like playing games on the WiiU emulator, Cemu, through GameStream. What I did here is create a shortcut in Steam to launch Mario Kart 8 directly in Cemu (if you have questions on how to do this, you can Google it.) I then used the option in Steam to make a desktop shortcut for this Steam shortcut, which creates a .url file that launches the game. Looking at this file’s properties shows that it runs the command: steam://rungameid/9898741384892907520. This is the command that I have GameStream launch. Note that your command will differ depending on what you are launching.

Now, here’s my entry for Mario Kart 8 in fingerprint.db:

<Fingerprint name='mario_kart_8'>
<DisplayName>Mario Kart 8</DisplayName>
<Version name='generic'>
<CMSID>500000001</CMSID>
<CMSVersion>1</CMSVersion>
<Distributor>Nintendo</Distributor>
<Icon>Mario Kart 8.url</Icon>
<Image>Mario Kart 8.url</Image>
<Launch>start steam://rungameid/9898741384892907520</Launch>
<IsAutomatable>1</IsAutomatable>
<IsStreamingSupported>1</IsStreamingSupported>
<StreamingAutomatedLaunch>1</StreamingAutomatedLaunch>
<StreamingCmdLine>start steam://rungameid/9898741384892907520</StreamingCmdLine>
<StreamingCaption>Mario Kart 8</StreamingCaption>
<StreamingClassName>W2ViewportClass</StreamingClassName>
<Files>
<File name='Mario Kart 8.url' />
</Files>
</Version>
</Fingerprint>

Adding this entry will cause GeforceExperience to add the game to GameStream as an officially supported title. However, It won’t do so right away. To get GeforceExperience to use our newly updated fingerprint.db, you can either end the correct nvcontainer.exe process in the Task Manager (there are a few) or just restart your computer. After this, scan for new titles in Geforce Experience and your new entry should be detected, and should appear on your Shield. Sometimes it takes a further restart of your PC for the game to finally appear on the Shield. It won’t, however, create a shortcut on your Shield’s homescreen. That’s the next step: making your custom apk.

I won’t explain all the different ways to extract apks from your Shield and so on. Here’s what I did:

1) Extracted the apk using Total Commander on my Shield.

2) Copied the apk to my desktop

3) Decompiled the apk using EasyApk (available on Xda-Developers)

4) Opened the AndroidManifest file and all the files in the res and smali folders in my code editor. I use Atom. Replaced all instances of the old CMSID with the new CMSID in all these files. (ctrl-f, find all, replace all.)

5) Replaced the banner and icon in the \res\mipmap-xhdpi-v4\ folder with new ones. You can also change the title of the app in strings.xml, as well as the color of the animation that is displayed when the app is launched in colors.xml. These are in \res\values\.

6) Recompiled the apk with EasyApk, and installed it on my Shield.

That’s basically it. The new apk will launch the game as defined in fingerprint.db, directly from the Shield’s homescreen.

Now, there are some drawbacks to using this method. One is that no poster and blurred background will be displayed on the screen as the GameStream stream loads. This can be solved, but only with root. Briefly, here’s how to solve it:

When GeforceExperience detects and adds a new game it creates an entry in the following file:

\Users\YourUserName\AppData\Local\Nvidia\NvBackend\journalBS.main.xml

Here’s the beginning of one of these entries:

<Id_57f8f0c0 Type="1">
<Id Type="2">1475932352</Id>
<CmsId Type="2">500000001</CmsId>
<CmsVersion Type="2">1</CmsVersion>
<DisplayName Type="4">Mario Kart 8</DisplayName>
<ShortName Type="4">mario_kart_8</ShortName>

The important info here is the second Id Tag: 1475932352. Keep it in mind. Now, copying your poster image to tegrazone3’s cache folder, located here:

/data/data/com.nvidia.tegrazone3/cache

on to your Shield will allow the poster to be displayed when the game is loading (and also while inside the Nvidia Games app.) However, a couple of things first:

One is that you must copy this image after the Nvidia Games app decides to move all its images from whatever internal mechanism or database it uses to store them, to the cache folder. This shouldn’t take too long. 5 mins? 10 mins? No idea. However, one way to force it is to clear Nvidia Games cache and data in Android Settings so that it is rebuilt. About 10 minutes afterward you should be good to copy your posters into the cache folder. You’ll know that it is time when you are being asked to overwrite the old files in the cache folder (to which you will reply ‘yes’).

Here’s the other thing, your poster must be named like this: img_s2_g1475932352_t2_i0null. Notice the part in bold. This is the ID taken from journalBS.main.xml. Also notice: there is NO file extension.

And that’s about it! Be aware that the Nvidia Games app may overwrite these cached images at some point, such as when the cache is cleared in Android Settings. I keep all my files in another folder on the Shield to be quickly copied back if and when that happens. Also, this doesn’t break the game’s launching ability anyway, so it’s not such a big deal. I’ve thought about experimenting with the read/write permissions of these files like I did with fingerprint.db. Haven’t tried it yet but it’s a potential solution, and also a potential Nvidia Games crashing error.

I’ll also mention tegrazone3’s database files. I’m not sure what the cause-effect relationship is between these files and Geforce Experience. However, there is the potential to edit this database directly as an alternative to the above guide. I tried editing it with a sqlite editor on my pc and it caused all posters to appear blank in Nvidia Games. And since the above guide worked for my purposes I decided not to spend any more time on the matter.

And now, finally: IS THIS WORTH THE TROUBLE??? Probably not. Not for most people, anyway haha. I don’t play that many different games so doing the above for those handful of games wasn’t a huge deal. I also really hate having to go through the Nvidia Games app and seeing all that tegrazone grid streaming what-have-yous. I don’t use that stuff, and much much rather have everything I do use displayed on my homescreen. But if you have hundreds of games that you would like added to your Shield’s home screen, I’m sure you stopped reading long ago.

That’s it! Hope I didn’t forget anything.