playnite-non-steam-shortcuts icon indicating copy to clipboard operation
playnite-non-steam-shortcuts copied to clipboard

Playnite 9 Support

Open sapphicwench opened this issue 2 years ago • 26 comments

Could this be updated for Playnite 9 please? One of my most used extensions

sapphicwench avatar Oct 07 '21 04:10 sapphicwench

Playnite 9 dropped python support completely. This plugin thus needs a complete Rewrite in another Coding Language like C#. Maybe I will be on that sometime in the future if I feel inspired enough to fight with APIs again.

NightHammer1000 avatar Oct 10 '21 13:10 NightHammer1000

Yes, a rewrite is needed for this to work in Playnite 9. If you have any current steam shortcuts in your library they should continue to work though.

I found a different solution that I prefer personally. The Special K (wiki, pcgw) software mostly does game patching/modding for better video performance, but it can also manipulate the Steam Overlay. The steps to set it up are:

  1. Ensure Steam is running (it will not be automatically launched)
  2. Manually create an steam_appid.txt in the game's directory with the ID of the equivalent game from the Steam Store
    • If the game isn't available from Steam you can pick a different game's ID or just use 0.
  3. Inject Special K into a game (you can use Special K Injection Frontend (SKIF) to dynamically inject it into all games)
  4. Enable "Load Steam Overlay Early" in Special K's settings. This forces Steam overlay injection, even into non-Steam games.
    • I think you may be able to do this in SpecialK's global settings to avoid configuring each game.
  5. Relaunch the game. The Steam overlay will be present. It will even show correct community controller bindings for the game because the appid is set correctly.

SKIF uses global DLL injection to load the tool. This has some risks (don't use it while playing online games, anti-cheat doesn't like that), but has the significant advantage that you don't need to create non-Steam shortcuts for every game. Also, the overlay is correctly injected even if using a library plugin that launches another store's launcher.

However, there's a bug in "Load Steam Overlay Early" in SpecialK, it doesn't work and fails to load GameOverlayRenderer.dll. I had to patch and fix it to get it to work. I told the dev, but it hasn't been fixed yet. I need to send a pull request to get it fixed I think.

Details on SpecialK bug

Inside SK_Steam_LoadOverlayEarly, wszOverlayDLL is being set to "c:/program files (x86)/steam\GameOverlayRenderer.dlll" (yes, that's three ls). I noticed that SK_PathCombineW calls SK_StripLeadingSlashesW on it's argument, so the leading slash in the LR"(\GameOverlayRenderer.dll)" strings is unnecessary. I'm guessing there's a bug somewhere in the SK_StripLeadingSlashesW logic that deletes the slash but doesn't terminate the string properly? This patch fixes the issue by removing the slash in the string literal. Need look into SK_StripLeadingSlashesW and figure out what's wrong though, (I think it's just a missing null termination)

diff --git a/src/steam/steam_api.cpp b/src/steam/steam_api.cpp
index 8ed5ccc8..08a7f62e 100644
--- a/src/steam/steam_api.cpp
+++ b/src/steam/steam_api.cpp
@@ -4103,8 +4103,8 @@ SK_Steam_LoadOverlayEarly (void)

   wchar_t           wszOverlayDLL [MAX_PATH + 2] = { };
   SK_PathCombineW ( wszOverlayDLL, wszSteamPath,
-    SK_RunLHIfBitness ( 64, LR"(\GameOverlayRenderer64.dll)",
-                            LR"(\GameOverlayRenderer.dll)"    ) );
+    SK_RunLHIfBitness ( 64, L"GameOverlayRenderer64.dll",
+                            L"GameOverlayRenderer.dll"    ) );

   hModOverlay =
     SK_Modules->LoadLibrary (wszOverlayDLL);

Personally, I like the SpecialK workflow much better than non-Steam shortcuts. I think a Playnite extension to automatically create the steam_appid.txt file could be useful. @darklinkpower made one, but I don't think it was published. It might be interesting to modify an extension like that to automatically create the steam_appid.txt file right before launching a game in Playnite (OnGameStarting event).

bburky avatar Oct 10 '21 14:10 bburky

Sorry, but I can't recommend SpecialK to anyone. The DRM loving actions and DRM Bullshit the Dev did in the past and the conflicts with almost anything interacting with Overlay Rendering, Like RTSS for example, produce more issues than its worth.

Not everyone uses this Extension for the Overlay. I for myself use it to use In Home Streaming on games not in Steam.

Your Proposed Solution does not solve this problem.

A rewrite in C# is still the Best Solution. The SpecialK Overlay thing can be its own Plugin. But its not a Replacement for this Extension.

NightHammer1000 avatar Oct 10 '21 14:10 NightHammer1000

It's also possible to develop a much simpler DLL (less than everything that SpecialK does) and only does steam overlay injection. Also you should be able all the features in SpecialK besides the Steam settings if it's other features cause trouble.

https://gist.github.com/Andon13/d439d5334d8173e5b959f383f1c49b03

Not everyone uses this Extension for the Overlay.
I for myself use it to use In Home Streaming on games not in Steam.

Ah, sorry. I didn't realize people had other usecases for this extension. I originally developed it for using Steam's controller mapping features in non-Steam games.

I don't think I will be developing an alternative non-Steam shortcut Playnite extension if I find a solution that meets my needs. If a rewrite in C# is done I would look into the code in this LaunchBox extension, it uses some SteamPipe APIs to call (undocumented?) Steam APIs for creating shortcuts. This avoids needing to manually manipulate the shortcuts.vdf file or relaunching Steam after creating shortcuts.

bburky avatar Oct 10 '21 14:10 bburky

Thanks for figuring that out @bburky, I know my way around SK so it's not an issue for me, and hopefully Kal gets back to you about the patch.

People always love to repeat the supposed "drm" of specialk but it all the pirates had to do was disable something in the ini file. I have no issues using SK to inject reshade and 3dmitgo into games and they stream fine on my steam link. There's many a program out there that can import other libraries to steam, then all you have to do is make a desktop shortcut of said game and change the playnite action to the steam url

sapphicwench avatar Oct 10 '21 14:10 sapphicwench

The Steam Overlay issue in Special K is fixed in version 21.10.18 or newer: https://gitlab.special-k.info/Kaldaien/SpecialK/-/merge_requests/5

I also tested creating My Documents\My Mods\SpecialK\Global\default_SpecialK.ini and add the following text to it. This configures "Load the Steam Overlay Early" to be enabled by default when using the Special K SKIF global injector. Otherwise you must manually enable this setting in each game. This allows using the Steam overlay and controller configuration for non-Steam games without creating non-Steam shortcuts.

[Steam.System]
PreLoadSteamOverlay=true

For now you have to manually create steam_appid.txt files, or appid 0 gets used by the overlay (which does work fine, but all your games will share the same config, and it's missing community controller bindings).

bburky avatar Oct 22 '21 03:10 bburky

The Steam overlay loads with SK but it's not the Big Picture overlay required for the Steam Controller. As far as I can tell there is no way to force this either. Your extension was the best solution for the job and worked perfectly, it's understandable that you don't feel like doing a rewrite though.

Iruberiam avatar Oct 25 '21 10:10 Iruberiam

@Iruberiam does checking the "force big picture overlay when using a controller" not work?

sapphicwench avatar Oct 25 '21 11:10 sapphicwench

@CptVeg Sadly not, I always have that checked, I'm guessing that flag only applies if the game is launched through Steam.

Iruberiam avatar Oct 25 '21 11:10 Iruberiam

@Iruberiam Bugger, the only other way I can think of making it work is manually adding the games to steam using things like OSOL or steamsync, making a desktop shortcut from steam with that and then adding that URL to playnite. It's what I've been having to do for Gamepass games as you can't create the appid.txt in their protected folders

sapphicwench avatar Oct 25 '21 12:10 sapphicwench

Using "Load Steam Overlay Early" on Special K 21.10.18+, I have been able to use my Steam Controller with two limitations:

  • The overlay is not in Big Picture mode (it's in desktop mode) and steam/guide button on the controller doesn't launch it. Shift-Tab works though.
  • The Controller Configuration dialog launches in a separate window because it's not in Big Picture mode

I have been able to configure both gamepad and mouse/keyboard bindings this way.

If editing protected folders is an issue for the steam_appid.txt, you configure the AppID in the per-game SK ini file in your Documents\My Mods\SpecialK\Profiles directory:

[Steam.System]
PreLoadSteamOverlay=true
AppID=620

bburky avatar Oct 25 '21 13:10 bburky

The desktop overlay is fine for normal controller input but it removes the ability to use many of the advanced features of steam input such as radial menus, touch menus and hotbars as these all rely on using the overlay for displaying their features.

Iruberiam avatar Oct 25 '21 13:10 Iruberiam

Ok, thanks for the info. I tested that it is possible to force the Steam overlay into Big Picture mode if you set a SteamTenfoot=1 environment variable. This change would need to be done inside Special K. However it crashes if Steam isn't in Big Picture mode, so I'd need to find a good way to detect the current Steam mode during early startup of the game .

bburky avatar Oct 25 '21 13:10 bburky

Are you aware of this extension by darklinkpower https://playnite.link/forum/thread-659.html

Iruberiam avatar Oct 25 '21 13:10 Iruberiam

The actual implementation needs to be on the Special K side, but yes an extension like that can make sure Steam is already in the right mode. An extension can handle the appid configuration too, and maybe even enable/disable SKIM.

Maybe an extension that provides a top toolbar button that functions as an on/off button for SKIM, and an OnGameStarted hook that ensures that Big Picture is running and the appid is set up correctly. Need to make sure this method actually works well enough before starting any of that though.

bburky avatar Oct 25 '21 16:10 bburky

I have a personal script that handles the start or close of Special K that may be of use.

function Start-SpecialkService
{
    param(
        $cpuArchitecture,
        $skifPath
    )
    
    $dllPath = [System.IO.Path]::Combine($skifPath, "SpecialK" + $cpuArchitecture + ".dll")
    if ([System.IO.File]::Exists($dllPath) -eq $false)
    {
        $__logger.Info("Special K dll not found in $dllPath")
        return $false
    }

    $serviceParams = @{
        FilePath = "rundll32.exe"
        ArgumentList = "`"$dllPath`",RunDLL_InjectionManager Install"
        WorkingDirectory = $skifPath
        Wait = $false
    }
    Start-Process @serviceParams

    $eventName = "Local\SK_GlobalHookTeardown" + $cpuArchitecture
    $i = 0
    do
    {
        try {
            Start-Sleep -Milliseconds 100
            $eventWaitHandle = [System.Threading.EventWaitHandle]::OpenExisting($eventName)
            $eventWaitHandle.Close()
            $eventWaitHandle.Dispose()
            $__logger.Info("Special K process and event for $dllPath started")
            return $true
        } catch {
            $i++
            Start-Sleep -Milliseconds 300
        }
    } while ($i -lt 10)

    $__logger.Info("Special K event `"$eventName`" could not be opened")
    return $false
}

function Stop-SpecialkService
{
    param(
        $cpuArchitecture,
        $skifPath
    )
    
    $dllPath = [System.IO.Path]::Combine($skifPath, "SpecialK" + $cpuArchitecture + ".dll")
    if ([System.IO.File]::Exists($dllPath) -eq $false)
    {
        $__logger.Info("Special K dll not found in $dllPath")
        return $false
    }
    
    try {
        $serviceParams = @{
            FilePath = "rundll32.exe"
            ArgumentList = "`"$dllPath`",RunDLL_InjectionManager Remove"
            WorkingDirectory = $skifPath
            Wait = $false
        }
        Start-Process @serviceParams
        $__logger.Info("Special K $cpuArchitecture service has been removed")
        return $true
    } catch {
        $__logger.Info("Special K $cpuArchitecture service could not be removed")
        return $false
    }
}

function OnGameStarting
{
    param(
        $OnGameStartingEventArgs
    )
    
    $game = $OnGameStartingEventArgs.Game
    
    $skifPath = [System.IO.Path]::Combine([Environment]::GetFolderPath("MyDocuments"), "My Mods", "SpecialK")
    $cpuArchitectures = @("32", "64")

    $disableSpecialK = $false
    if ($game.Features)
    {
        foreach ($feature in $game.Features)
        {
            if ($feature.Name -eq "Disable Special K")
            {
                $disableSpecialK = $true
                $__logger.Info("`"Disable Special K`" feature found. Special K will be disabled.")
                break
            }
        }
    }

    foreach ($cpuArchitecture in $cpuArchitectures)
    {
        if ($disableSpecialK -eq $true)
        {
            # Check if leftover service is running and close it
            Stop-SpecialkService $cpuArchitecture $skifPath
        }
        else
        {
            Start-SpecialkService $cpuArchitecture $skifPath
        }
    }
}

function OnGameStopped
{
    param(
        $OnGameStoppedEventArgs
    )
    
    $game = $OnGameStoppedEventArgs.Game

    $skifPath = [System.IO.Path]::Combine([Environment]::GetFolderPath("MyDocuments"), "My Mods", "SpecialK")
    $cpuArchitectures = @("32", "64")
    foreach ($cpuArchitecture in $cpuArchitectures)
    {
        Stop-SpecialkService $cpuArchitecture $skifPath
    }
}

darklinkpower avatar Oct 25 '21 16:10 darklinkpower

And found the extension I shared on the Playnite discord to generate the steam_appid.txt files, although it only works for P9. https://cdn.discordapp.com/attachments/699577276571975760/880682115086319686/Steam_AppId_Generator_1_0.pext

But I think something like this should be better done as a C# extension.

darklinkpower avatar Oct 25 '21 16:10 darklinkpower

And found the extension I shared on the Playnite discord to generate the steam_appid.txt files, although it only works for P9. https://cdn.discordapp.com/attachments/699577276571975760/880682115086319686/Steam_AppId_Generator_1_0.pext

But I think something like this should be better done as a C# extension.

The extension doesn't work for me on Playnite 9

fIows avatar Mar 05 '22 17:03 fIows

And found the extension I shared on the Playnite discord to generate the steam_appid.txt files, although it only works for P9. https://cdn.discordapp.com/attachments/699577276571975760/880682115086319686/Steam_AppId_Generator_1_0.pext But I think something like this should be better done as a C# extension.

The extension doesn't work for me on Playnite 9

That one is for Playnite 8. Try with this, it should work https://cdn.discordapp.com/attachments/929214602200379392/929217657100697642/Steam_AppId_Generator_1_0.pext

darklinkpower avatar Mar 05 '22 17:03 darklinkpower

That one is for Playnite 8. Try with this, it should work https://cdn.discordapp.com/attachments/929214602200379392/929217657100697642/Steam_AppId_Generator_1_0.pext

Thank you very much for the quick response and the help! Also, how would I use this script? https://github.com/bburky/playnite-non-steam-shortcuts/issues/26#issuecomment-951104938

fIows avatar Mar 05 '22 17:03 fIows

That one is for Playnite 8. Try with this, it should work https://cdn.discordapp.com/attachments/929214602200379392/929217657100697642/Steam_AppId_Generator_1_0.pext

Thank you very much for the quick response and the help! Also, how would I use this script? #26 (comment)

It needs to be made as an extension. Here it is for Playnite 9 with a newer version of the script.

SpecialKHelper.zip

It can also automatically configure a game specific reshade preset when you launch a game https://wiki.special-k.info/en/SpecialK/ReShade

For this you need to extract this file to this location

image

ReShadePresetEmpty.zip


Just be aware that I don't provide support for this extension, that's why I decided not to publish it. Also make sure to disable the extension for games that use anticheat or you'll probably be banned. To disable it for specific games add a feature named [SW] Disable Special K to them.

If you need help or have questions you can contact me in the Playnite discord server.

darklinkpower avatar Mar 05 '22 20:03 darklinkpower

I just realized that this thread didn't have a link to @darklinkpower's excellent Special K Helper add-on in it. You can install the add-on inside Playnite by searching the add-on browser. It has some great features like easily toggling Special K on and off, and automatically detecting the Steam ID to make injecting the Steam overlay very simple.

Just leaving a link here in case anyone still finds this old playnite-non-steam-shortcuts on GitHub and finds this thread.

bburky avatar Aug 07 '22 04:08 bburky

Since no one mentioned it yet, I want to point out BoilR, which automatically creates non-Steam shortcuts from other launchers in Steam (and even optionally adds images from SteamGridDB).

I don't think there is a way to automatically import those non-Steam shortcuts into Playnite, so the Special K method is the easier solution if you want to primarily use Playnite. Nontheless, it might help someone who mainly wants steam input or easy Steam Link streaming for non-steam games.

Fivefold avatar Dec 31 '22 19:12 Fivefold

https://github.com/PhilipK/BoilR/issues/200

NightHammer1000 avatar Dec 31 '22 23:12 NightHammer1000

BoilR now has Playnite Support for those who still want to import everything into Steam

NightHammer1000 avatar Jan 05 '23 21:01 NightHammer1000

I'd love to have this extension working again :

so we could be able to have steam overlay in all games (i know there is workarounds but it's really not as practical and it's hit or miss)

AND we could have all playnite's games aviable to stream via steam link (wich is now VR compatible), so all our library on steam deck and meta quest :D

Drakalinou avatar Dec 02 '23 01:12 Drakalinou