Closed zany130 closed 3 months ago
What about a double backslash? I'll check when I'm back on my PC as well.
For example, Z:\\home\\zany130\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe
I don't know about this specific case, but sometimes Wine can handle forward-slashes (ModOrganizer 2 I think has some /
paths). Might be worth trying that and seeing how it goes too.
Double backslash appears to work for me, but has this problem:
--launch "Z:\\your\\custom\\path"
--launch Z:\your\custom\path
a. Note the striped quotes. I'm not sure how we handle paths that have spaces in this way. For example if your path was Z:\\run\\media\\gaben\\Games Drive\\steamapps\\common\\Half-Life 3\\InYourDreams.exe
, would it interpret this path properly? I guess that depends on how we pass the arguments. If we try to split it up into an array, this is probably bad news as it would break everything up with a space.
b. This quote stripping is a general problem with how Yad handles inputs, it happens even with a simple Yad project. You can't even escape them. There's no solution I'm aware of to get around this for Yad.
c. For GameScope, some flags can take paths (such as the cursor image). There is a crazy workaround in place for flags that take paths. It basically tries to infer when a space is part of a path and when it denotes the beginning of a new flag. This might work for this specific use-case, but I'm not sure if it's worthwhile investigating implementing generally. I have no idea what kinds of arguments custom commands may take, and it may have unintended side-effects if no paths are provided. We may end up incorrectly breaking up custom commands, or we may not. I have no idea.Essentially when you save you go from Z:\\your\\custom\\path"
-> Z:\your\custom\path
-> Z:yourcustompath
. This means we have two issues we may have to deal with:
\
in CUSTOMCMD_ARGS
with \\
. I wonder if we can use parameter expansion to do this when we pass the variable to Yad... We already do a bit of parameter expansion but maybe we could do some whacky chaining in a $()
.Z:\run\media\zany130\Spaced Path Name\Oh No This Is Probably Broken\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe
- From looking at the code I'm pretty sure custom commands are solely split up based on spaces, so each space is a different argument (meaning it would only pass Z:\run\media\zany130\Spaced
as the path to the custom command...)
a. Escaping the spaces probably doesn't work because of how mapfile
breaks at the space, but it might be worth trying. In a quick local test in a Bash prompt it didn't work though.In the short-term though for a workaround, double-escaping each time you go to the Game Menu should work. Alternatively, forward-slashes may also work, it just depends on each program I think. It might be worth testing Proton 9.0 Beta, Proton Experimental, GE-Proton9, or anything else based on Wine 9 just to see.
In the longer-term, we have some considerations about how better to handle custom command paths, such as those with spaces.
What about a double backslash? I'll check when I'm back on my PC as well.
For example,
Z:\\home\\zany130\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe
yup that writes out the path correctly like you said above. though I having trouble getting it to atchually run , but don't know if that's just with reloded II....
Ah, there's a missing backslash in my example after \.local
. It should be Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe
If this still doesn't work, you can try pasting it manually into the game config file, and loading without touching the Game Menu, so STL will read it directly from the config file and there should be no risk of Yad mangling it. Hopefully if I can figure out some parameter expansion/sed to replace single backslashes, Yad will hopefully not mangle the path anymore, so this should be temporary and just for testing. I'm sure there's some sed -E regex for it if all else fails, but as they say, once you start using regex to solve a problem, you now have two problems. :sweat_smile:
If this still doesn't work, you can try quadruple-escapes! Same again, just paste this into your game config and launch without touching the Game Menu: Z:\\\\home\\\\zany130\\\\.local\\\\share\\\\Steam\\\\steamapps\\\\common\\\\P3R\\\\P3R\\\\Binaries\\\\Win64\\\\P3R.exe
.
If both of these still don't work, you can once again try these in your config file, once again avoiding the Game Menu (Yad will always mangle these because it hates quotes for some reason):
CUSTOMCMD_ARGS=\"Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe\"
CUSTOMCMD_ARGS=\"Z:\\\\home\\\\zany130\\\\.local\\\\share\\\\Steam\\\\steamapps\\\\common\\\\P3R\\\\P3R\\\\Binaries\\\\Win64\\\\P3R.exe\"
If none of these work, it will be very sad times. Perhaps if they all fail you can try manually from terminal with Wine and see if passing the same command fails, that would help narrow down if it's an STL problem or not. I am foolishly optimistic that one of these will yield a result though :wink:
Ah interesting, it seems like using printf
to feed the option to Yad, correctly preserves the backslashes.
Because this is a bug, I created a new branch to test the fix. For some reason, using printf
prevents the backslash mangling. No idea why...
You can check out the branch here and see if it fixes your backslash woes over at customcmd-args-backslash-fix
. Before testing, remove /dev/shm/steamtinkerlaunch
. When fiddling with any UI fixes it's always good to remove that, and I forgot about that until now when I was banging my head against the wall :sweat_smile:
I don't know if Reloaded II will work, but this should at least fix the issue of the paths going from Z:\this\is\text
-> Z:\thisistext
. Or at least in my testing it has :-)
This won't fix paths with spaces, though, that one's another beast...
Oh cool Ill give that a try when I get the chance rn I'm trying to troubleshoot why nothing loads when I try to run Reloaded II with P3R exe as a arg.
for testing purposes I was able to get this to work as a separate steam shortcut by adding Reloaded II as a custom steam game then in the launch options adding
STEAM_COMPAT_DATA_PATH=/home/zany130/.steam/steam/steamapps/compatdata/2161700/ %command% --launch "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
this launches P3R with mods but I can't get this to work on the P3R steam entry with STL for some reason...
BTW: I tried using forward slashes in the above steam launch option and it didn't work it need to be backslashes apparently
looking at my log I see its running
'/home/zany130/mods/Persona 3 Reload/Release/Reloaded-II.exe' '--launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe'
If you use quotes for the STL option, in the game config, does that work?
If not, if you change your non-STL command to these, does it work?
STEAM_COMPAT_DATA_PATH=/home/zany130/.steam/steam/steamapps/compatdata/2161700/ %command% "--launch" "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
STEAM_COMPAT_DATA_PATH=/home/zany130/.steam/steam/steamapps/compatdata/2161700/ %command% "--launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
STEAM_COMPAT_DATA_PATH=/home/zany130/.steam/steam/steamapps/compatdata/2161700/ %command% --launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe
This will help work out the following:
My guess is that 1 and 3 will work though.
Did a bit of hardcoded logging in extProtonRun
.
With this I can see each element in the RUNPROGARGS
array. I'm not using Reloaded II, just P3R with some nonsense argument for testing :-) I can see STL is splitting the arguments as I expected in the first example above: Fri 22 Mar 03:32:09 GMT 2024 INFO - extProtonRun - RUNPROGARGS values are:
'--launch' 'Z:\not\real\path'- So here, the first element is
"--launch"and the second element is
"Z:\not\real\path"`. Which is, usually, the correct way to pass paths to a launch command array (putting them as one string or with an empty string between can cause crashes).
I'm not sure why Reloaded II would be having troubles picking up the path. I may have to get it set up over the weekend for troubleshooting if we can't figure it out!
hmm, intresting when adding those commands to my R2 steam shortcut (that's what I'm going to call the mod loader now lol) the following happens
--launch "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
quotes and everything because that's how it knows what mod profile to use (because that mod profile has "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
set as its "game") when I pass
--launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe
or
"--launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
.... I'm tired I don't want to see another f*ck \
`
or any other weird character 😅
So if it's looking specifically for a mod profile with quotes in the name, does editing the ~/.config/steamtinkerlaunch/gamecfgs/title/P3R.conf
file (I think that's the path to the config file) to have CUSTOMCMD_ARGS
as the following work?
CUSTOMCMD_ARGS="--launch \"Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe\""
Then try launching the game without touching the game menu (because Yad will mangle it), that is, just let the wait requester time out when you launch P3R. That should hopefully then show in your log that the launch args are --launch "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
(without the backslashes, because Bash should escape it properly when reading the config).
I'm tired I don't want to see another f*ck
\
`
or any other weird character 😅
Mood, I will probably be heading to bed shortly and will pick this up tomorrow (probably gonna explore R2 myself because I am quite interested!))
Parsing with Yad is fun :woozy_face:
launching the game without touching the game menu (because Yad will mangle it)
Good idea don't want to add yad shanagiens into the mix lol
Mood, I will probably be heading to bed shortly and will pick this up tomorrow (probably gonna explore R2 myself because I am quite interested!))
same lol. this prob isn't really even a stl bug per se (well other than yad stuff) so no worries if you want to prioritize something else.
I prob be trying this a bit on my end to just cuz I'm ocd like that (prob would just be easier to use the r2 shortcut and then add stl as a compat tool for that or something)
anyway if you do want to check r2 out I recommend using this guide https://gamebanana.com/tuts/17166 its written for the deck but can be adapted to desktop Linux fairly easily
The escaped quotes (\"
) in the config didn't seem to log properly on my end. I'm not using R2 but just if you're curious andwant to try some more:
CUSTOMCMD_ARGS="--launch \"Z:\\double\\escaped\\path\""
CUSTOMCMD_ARGS="--launch "Z:\this\is\an\unescaped\abomination""
anyway if you do want to check r2 out I recommend using this guide
This should be handy. Thanks!
Let me know if you find anything out in the meantime. I'll keep this open as it is interesting, I wonder what is going wrong with the path being sent to R2.
Random thought before falling asleep:
What if you set the following as your launch options for Persona 3 Reload (not R2), still using STL as the compatibility tool: --launch "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
- This is part of the working launch option for R2.
After doing this, go to the STL main menu and then check your log to see if it logs anything interesting for incoming commands from Steam. Likewise it might be interesting to check the Game Menu as this may be read in and displayed somewhere (although the Game Menu may mangle quotes).
The purpose of this is: STL I believe has a facility to read launch commands coming in from Steam. So, this might give us some insight into what Steam "sees".
Then again, this might be a sleep-deprived nonsense idea. Only one way to find out :-) I would experiment but my PC is off now.
What if you set the following as your launch options for Persona 3 Reload (not R2), still using STL as the compatibility tool:
--launch "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
- This is part of the working launch option for R2.
EDIT: to answer your question it appears like this
Fri Mar 22 08:38:44 PM EDT 2024 INFO - main - Checking command line: incoming arguments 'waitforexitandrun /home/zany130/.local/share/Steam/steamapps/common/P3R/P3R/Binaries/Win64/P3R.exe --launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe'
so no "
even though I did have them around the path part in the steam launch command
hmm that gave me an idea to run my R2 shortcut in steamtinkerlaunch and see what happens... well it crashes but the log is somewhat interesting
in that it seems STL is receiving the arguments mangled as you can see here
'waitforexitandrun /home/zany130/mods/Persona 3 Reload/Release/Reloaded-II.exe --launch Z:homezany130.localshareSteamsteamappscommonP3RP3RBinariesWin64P3R.exe'
Huh now that is interesting, because coincidentally, I just tried as well. I tried with regular P3R (don't have R2 installed) but the principle should be the same, even though the launch options of course won't do anything here, it's just to see what they look like.
For P3R I set the launch command as exactly this: %command% --launch "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
(even though this path ofc doesn't exist for me heh)
And in SteamTinkerLaunch, I can see:
INFO - getCurrentCommandline - No Proton in command line arguments 'waitforexitandrun /run/media/emma/Steiner/Games/steamapps/common/P3R/P3R/Binaries/Win64/P3R.exe --launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe'
INFO - getCurrentCommandline - No Proton in command line arguments 'waitforexitandrun /home/zany130/mods/Persona 3 Reload/Release/Reloaded-II.exe --launch Z:homezany130.localshareSteamsteamappscommonP3RP3RBinariesWin64P3R.exe'
So, I tried a Non-Steam Game just to see if the results were different, and they were not.
I did a Ctrl+F for --launch
to see if the paths get mangled elsewhere for me and the backslashes disappear, just in case for some reason for me they were passed correctly but for messed up later on. But all occurances of the incoming command line options from Steam were correct.
If the launch option is given without quotes, such as --launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe
, then the backslashes will be removed. Maybe this is the problem. The log then looks like this: --launch Z:homezany130.localshareSteamsteamappscommonP3RP3RBinariesWin64P3R.exe
As an aside: There is a part of the SteamTinkerLaunch Game Menu UI that I thought was supposed to display the incoming launch options from Steam, that is, the ones we're passing here. I thought this was the "Game command arguments (Steam Launch Option) (SLOARGS)
" item, but this is hardcoded to "none". I wanted to use this to try and see how the options were being passed, but the log worked fine.
I am going to do some tests to see what Steam sees when it launches a game with launch options, to get some insight into any escaping it might do.
Steam doesn't do any wrapping, its launch command is just this:
home/emma/.local/share/Steam/ubuntu12_32/reaper SteamLaunch AppId=2161700 -- /home/emma/.local/share/Steam/ubuntu12_32/steam-launch-wrapper -- '/home/emma/.local/share/Steam/compatibilitytools.d/SteamTinkerLaunch'/steamtinkerlaunch waitforexitandrun '/run/media/emma/Steiner/Games/steamapps/common/P3R/P3R/Binaries/Win64/P3R.exe' --launch "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
Which is what, ideally, SteamTinkerLaunch would also pass. Let me see what it'll pass if I give some escaped quotes in the config file and launch without going to the game menu... If the launch command can use quotes and if that can resolve the problem, then probably we need a way to internally wrap paths from the Game Menu.
Or, as another simpler solutiion, an option to pass a game's launch options to custom commands. Then we don't have to worry about Yad destroying the string.
Oh interesting also, on the Main Menu, the launch option path not displayed properly.
This could probably be fixed with printf
instead of echo...
Hmm, I just discovered printf
has a %q
option. If we use this when parsing the incoming game commandline options, it will display backslashes properly. But I don't know if this causes other issues when actually using them.
For now, maybe using this solely for display purposes is fine. It still won't display quotes for some reason, though. It will escape it internally, though: --launch\ Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\ Spaced\\Binaries\\Win64\\P3R.exe
I'm going to look into this %q
option some more. I will have to refactor a little how custom command arguments are passed but it shouldn't be too bad. Then, if things look promising from the log, I'll push a branch where the arguments array is built using printf "%q"
and you can see if the custom command receives the launch option correctly.
The path will probably have to be entered with a double-escape on the Game Menu, pending a branch that fixes this. I'll give example data if I get anywhere with this investigation path, no worries :-)
nice!!
I been trying to see exactly how steam sees the launch options for r2 shortcut.
I got the following by adding PROTON_LOG=1
to the beginning of the launch commands so
PROTON_LOG=1 STEAM_COMPAT_DATA_PATH=/home/zany130/.steam/steam/steamapps/compatdata/2161700/ %command% --launch "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
gets written out on the proton log as
Command: ['/home/zany130/mods/Persona 3 Reload/Release/Reloaded-II.exe', '--launch', 'Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe']
so that's what its supposed to look like when it gets launched correctly at least according to the proton log...
running steam in a terminal and then running the R2 shortcut also gives this
/bin/sh\0-c\0PROTON_LOG=1 STEAM_COMPAT_DATA_PATH=/home/zany130/.steam/steam/steamapps/compatdata/2161700/ /home/zany130/.local/share/Steam/ubuntu12_32/reaper SteamLaunch AppId=3829416151 -- /home/zany130/.local/share/Steam/ubuntu12_32/steam-launch-wrapper -- '/home/zany130/.local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper'/_v2-entry-point --verb=waitforexitandrun -- '/home/zany130/.local/share/Steam/compatibilitytools.d/GE-Proton9-2'/proton waitforexitandrun "/home/zany130/mods/Persona 3 Reload/Release/Reloaded-II.exe" --launch "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"\0
chdir "/home/zany130/mods/Persona 3 Reload/Release"
EDIT: interesting without the "
around Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe
steam apparently passes
Z:homezany130.localshareSteamsteamappscommonP3RP3RBinariesWin64P3R.exe
which is why I need the "
however double escaping like this
PROTON_LOG=1 STEAM_COMPAT_DATA_PATH=/home/zany130/.steam/steam/steamapps/compatdata/2161700/ %command% --launch Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe
actually works :eyes:
So the double escaping is required! Very interesting! That probably won't work with spaces though.
Could you do the following?
CUSTOMCMD_ARGS
in your P3R config to CUSTOMCMD_ARGS="--launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
With that branch, the custom command args passed looks like this: '--launch\ Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe
which seems promising based on your above!
interesting without the
"
around [path] steam apparently passes [path without backslashes]
Yup, this is what I suspected was causing for me, the path had backslashes in my STL log but for you was removing backslashes. This confirms it then :-)
I GOT IT WORKING quadrple escaping was the answer :eyes:
in the menu
this wrote out
CUSTOMCMD_ARGS="--launch Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe"
to the config which I could of sworn I tried but it works!!!
That is awesome news!
Can you try the branch here and see if it also works? Change your CUSTOMCMD_ARGS to only use single backslashes before testing: https://github.com/sonic2kk/steamtinkerlaunch/tree/extProtonRun-printf-q
CUSTOMCMD_ARGS="--launch Z:\home\zany130\\local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
printf "%q"
will hopefully handle the double-escaping for you, so you won't have to do it manually!The config file will only store single backslashes, but when generating the custom command argument array, backslashes should be double-escaped. This should do the same as what you're doing manually.
Also, the caveat to what you're doing is that going to the Game Menu and saving will result in the double-backslashes being removed, meaning they'd have to be re-entered each time. If the branch above works, then this won't be an issue :-)
Finally, if all of this works, then the final bit we need is this branch: https://github.com/sonic2kk/steamtinkerlaunch/tree/customcmd-args-backslash-fix (be sure to remove /dev/shm/steamtinkerlaunch
after installing it).
This branch fixes the issue of the path becoming Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe
-> Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe
-> Z:homezany130.localshareSteamsteamappscommonP3RP3RBinariesWin64P3R.exe
.
So with both of those branches together, assuming they work, we'll end up with this behaviour:
CUSTOMCMD_ARGS
will always preserve backslashes in argument pathsCUSTOMCMD_ARGS
will be parsed and its single backslashes will be properly escaped with print "%q"
Which should allow you to get an out-of-box experience with R2 profile commands by just passing --launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe
into the textbox on the Game Menu. Then when you save, the path will be preserved. And when you finally launch, it should be passed correctly to R2 and give you the same behaviour that you're doing now :-)
I just realised that's kinda a lot and you probably want to get stuck into actually playing, but I hope it makes sense :sweat_smile: Both in terms of what the branches do and why I want them tested. The ideal is that both of these branches will allow what you're doing manually to "just work"
Finally, if all of this works, then the final bit we need is this branch:
customcmd-args-backslash-fix
(be sure to remove/dev/shm/steamtinkerlaunch
after installing it).
just tested this part seems to work fine (intrestingly it still mangles "
but we already established we don't need (and prob don't want )"
wrapping around the path here)
I just realised that's kinda a lot and you probably want to get stuck into actually playing, but I hope it makes sense 😅 Both in terms of what the branches do and why I want them tested. The ideal is that both of these branches will allow what you're doing manually to "just work"
no worries I want to see this through the whole way lol. I already know I'm prob not playing to much today (ah well so is the life of an eternal tinkerer :sweat_smile: )
just tested this part seems to work fine
Hell yeah! So it can be merged then.
intrestingly it still mangles
"
but we already established we don't need
Yup, plus it looks like Proton doesn't take this anyway (https://github.com/sonic2kk/steamtinkerlaunch/issues/1072#issuecomment-2016276706) from the Proton log arguments you provided.
So assuming the branch that should contain the launch fix works, I think we are good! That branch should double-escape the single-backslashes in CUSTOMCMD_ARGS
, so the first branch will correctly save the paths, and the second branch will then fix launching by double escaping the fixed strings from the first branch.
I already know I'm prob not playing to much today
If it's any consolation, your troubleshooting is super appreciated (and putting up with my rambly explanations :sweat_smile:)
PRs are up for each branch:
If both branches work for you, I will merge both of these PRs tonight.
If it's any consolation, your troubleshooting is super appreciated (and putting up with my rambly explanations 😅)
haha no worries it was your rambling that made me think "maybe I should look at how to command is supposed to look once its passed" lol
my guess from comparing my log from the successful run and this one is its the
extra \
after --launch
Fri Mar 22 10:27:29 PM EDT 2024 INFO - extProtonRun - Starting '/home/zany130/mods/Persona 3 Reload/Release/Reloaded-II.exe' with arguments '--launch\ Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe' regularly
EDIT for reference this log had CUSTOMCMD_ARGS
set to "--launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
and this one had CUSTOMCMD_ARGS
set to "--launch Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe"
Hmm! Good catch. Yeah, I could see this being a problem.
Maybe using %q
is not the right path then. We may have to resort to something a little more "hacky" where we only use "%q"
for paths... I'l investigate
There's a workaround with sed (sed 's/\\\\/\\/g'
), but in testing, I found that paths with spaces are totallly broken here, so I'm looking into a separate fix.
Okay, dear god, I came up with a bit of an abomination to handle spaces, and in the end we can stick with printf "%q"
.
Basically, extProtonRun
takes in a string representing the arguments to pass to custom commands as PROGARGS
. For us here, this is CUSTOMCMD_ARGS
.
We have to break this into an array of strings to pass it to an executable. This is equivalent to the Proton log's Commands
block, where it has a Python list for each command given. For our example, this would mean we have a Bash array like this: ( "--launch" "Z:\\path\\to\\exe" )
.
The problem is, we use mapfile
to do this, and it splits on spaces. This is fine for everything except paths with spaces. mapfile
sadly cannot handle escaped spaces. So if a path has spaces, you end up with an array like this: ( "--launch" "Z;\\path\\to" "a_spaced" "path\\location\\game.exe" )
- Every element in the array is split on a space. This is important to separate things like flags from paths, but becomes a problem when the paths themselves have spaces.
Steam doesn't have a problem with this, because it can handle quotes. Over here in STL, PROGARGS
will never have quotes.
Even if you escape the paths yourself, mapfile
will give you something like this: ( "--launch" "Z;\\path\\to\\" "a_spaced\\" "path\\location\\game.exe" )
So our problem is that paths with spaces are treated as separate arguments, meaning they can't be read.
I think I have come up with a solution for this though, with a couple of caveats.
If we assume PROGARGS
has spaced but that they are escaped, we can always assume that when mapfile
splits the string, a split path will end with a backslash. However, this will forbid paths from ending in a backslash! I think this is acceptable though.
Z:\\home\\zany130
Z:\\home\\zany130\\
So, we can use a for loop to check the current and track the previous elements to see if the previous element has a backslash. If the previous element ended in a backslash, we can update the current array element to be ${previous_element} ${current_element}
, basically modifying the array to contain the joined strings.
This has the problem of the existing array that is being modified containing null strings, but we can workaround this by generating a new array based on this modified one, with null strings filtered out. We can do this in mapfile by printf
ing the array and using grep -v "^$"
, where "^$" pattern matches all empty elements, and -v
inverts this to print everything that is not blank.
The reason we can't have paths ending in a backslash, is that anything after the path would be assumed to be part of the path, since the previous element ended in a backlash. For example, --launch Z:\\home\\gaben\\ RELEASE_HALF_LIFE_THREE=1
would result in the code seeing RELEASE_HALF_LIFE_THREE
as part of the path. But leaving off the ending \\
would result in RELEASE_HALF_LIFE_THREE=1
correctly being added as a separate element to the arguments array.
The final caveat, and one that I would like to fix, is that this does not work for paths using forward slashes, so traditional unix paths will still be split.
Anyway, here's the code snippet I've been testing with. It's a bit of a Pepsi-fuelled sleep-deprived nightmare, so bear with me:
# Play around with this one, I've commented some other test strings
PROGARGS="--launch Z:\home\zany130 spaced\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe" # Expected length: 2
#PROGARGS="--launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe" # Expected length: 2
# PROGARGS="--launch Z:\\home\\zany130\\ is\\ spaced\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe MYVAR=1" # Expected length: 3
# Create initial args array
mapfile -d " " -t -O "${#RUNPROGARGS[@]}" RUNPROGARGS < <( printf "%q" "$PROGARGS" )
FINAL_RUNPROGARGS=()
for i in "${!RUNPROGARGS[@]}"; do
# Remove trailing backslash, i.e. turn `--launch\` into `--launch`
RUNPROGARGS[i]="${RUNPROGARGS[i]%\\}"
# If the last seen element in the array ended with a backslash, assume
# this is an incomplete path and join them
#
# This is not perfect as valid paths that just end with backslashes will not work,
# but we can document this on the wiki
#
# i.e. "Z:\this\is\a\path\ MY_VAR=2" will not work, but "Z:\this\is\a\path MY_VAR=2" will work
if [[ $LASTRUNPROGARG = *"\\" ]]; then
# Remove 'i-1' (previous element), because 'i' (current element) will contain 'i-1'
unset RUNPROGARGS[i-1]
RUNPROGARGS[i]="${LASTRUNPROGARG} ${RUNPROGARGS[i]}"
fi
LASTRUNPROGARG="${RUNPROGARGS[i]}"
done
# Generate new array with null strings removed.
mapfile -t -O "${#FINAL_RUNPROGARGS[@]}" FINAL_RUNPROGARGS < <( printf "%s\n" "${RUNPROGARGS[@]}" | grep -v "^$" )
# Print verification
echo "${FINAL_RUNPROGARGS[0]}"
echo "${FINAL_RUNPROGARGS[1]}"
# Print length to verify it is correct, i.e. a flag and a path with spaces should only have 2 elements
# since the path with spaces will only count as one element
echo "${#FINAL_RUNPROGARGS[@]}"
I'm going to push this up to the branch but I will probably only minimally test this against STL tonight and will give it another looking over tomorrow. Wow, that was a journey lol.
Sorry, I totally missed your note that #1074 seems to work. It works for me too, so I'll merge it as-is. That means I can rebase #1073 on it which will make testing a little easier.
If issues come up we'll deal with them then :-)
On that note, #1073 has the changes pushed. In my tests, the launch command looks good: --launch Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe
- It has the trailing \
in --launch\
stripped. Paths with spaces should work but if you can't test this don't worry about it too much.
With the newly pushed changes, hopefully #1073 now works for you. I've verified that the argument array should be correct, looking like this: ("--launch" "Z:\\home\\zany130\\.local\\share\\Steam\\steamapps\\common\\P3R\\P3R\\Binaries\\Win64\\P3R.exe")
- Based on our understanding from all the discussion in this issue, that should match what Steam passes, and thus should work.
If that above use-case works for you, then awesome! I will focus after that on taking a look at fixing spaced paths for paths with forward slashes. I may not get anywhere and if not, and the rest of the PR works, I will just merge it as-is. There is already a TODO to note that paths with forward slashes don't work yet.
Okay, #1073 has been rebased. It is now ready for testing whenever you're able (could just git pull extProtonRun-printf-q
to pull the latest changes in as you probably already have the branch :-))
No major hurry on testing or anything, just letting you know the changes are ready now.
Yup it boots with just setting CUSTOMCMD_ARGS
to --launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe
though on further testing it seems the path still sometimes gets mangled in the GUI.
it seems if I save CUSTOMCMD_ARGS="--launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
directly into the ini and then load the game menu it is rendered correctly
If I hit save when it comes back, it still renders correctly (before a save would overwrite the good path with a mangled one).
However,if I make CUSTOMCMD_ARGS=
(blank) and then save it. When I later add --launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe
it gets mangled again
So it seems like the "fix" only prevents an already correctly saved path with \
from getting mangled.
Which is still an improvement :sweat_smile:
Well this is still good news! The path saving issue is probably more related to #1074.
Did you try with CUSTOMCMD_ARGS=""
(with quotes)? The config shouldn't ever have CUSTOMCMD_ARGS=
(without quotes). I'll give it a try on my end, too.
Hmm! Okay, I can reproduce the problem. Double-escaping on initial save will work, but when saving a path with single backslashes, it gets saved to the config like this: --launch Z:homezany130 estpath
- My path was Z:\home\zany130\testpath
. Note that the spacing in the mangled path is actually a tab character, which lines up with \t
.
It seems something is wrong with saving elements which have backslashes still, but only the first time.
So I have a suspicion that, wherever we're saving the updated elements into the config file, we're using echo
instead of printf
. Example:
CUSTOMCMD_ARGS="--launch Z:\home\zany130\testpath"
echo "${CUSTOMCMD_ARGS}" # Prints Z:\home\zany130 estpath
printf "%s\n" "${CUSTOMCMD_ARGS}" # Prints Z:\home\zany130\testpath
I'll have to figure out where the saving magic happens, but I think this is a safe assumption to make that this is the problem.
Changing to using printf
if we're not already is probably safe to do, because no text options in the menus should be formatted in echo
, i.e. we would never want strings with \t
on the Game Menu to be escaped as a tab character. We want them saved as string literals.
EDIT: The part we're looking for is updateConfigEntry
. This uses echo
instead of printf
for new entries, and should be a straightforward fix. The less-straightforward fix comes from updating existing entries (and re-activating commented-out entries) which uses sed
. I'll need to experiment to see how sed
treats escape sequences...
We may be able to edit the sed
command to be like this:
# Old command, expands escape sequences
sed -i "/^${CFGCAT}=/c$CFGCAT=\"$CFGVALUE\"" "$CFGFILE"
# Updated command, surrounds the variables in double quotes
# but keeps the sed syntax in single quotes.
sed -i '/^'"${CFGCAT}"'=/c\'"${CFGCAT}=\"$CFGVALUE\"" "$CFGFILE"
This is changing a VERY core part of STL, though, and will need tested thoroughly. I also haven't ran this past ShellCheck yet,
As this will need a lot of testing, as a workaround in the interim, double-escaping new strings before saving should resolve the problem. You shouldn't need to double-escape after that. After investigation, it sems the echo
in updateConfigEntry
is actually safe, so my guess is that this is why subsequent saves are fine, but newly-added paths get mangled.
Actually, I'm dumb, that doesn't work. The testing example I was using in my Bash shell spelled CFGCAT
wrong when giving it to sed.
There may be an alternative solution though, if we just escape CFGVALUE
when we pass it to updateConfigEntry
.
CFGVALUE="$( echo "$2" | sed 's/\\/\\\\/g' )"
And then just use our existing sed command.
This probably isn't fool-proof per-se, since this is all escaping, but should prevent problems if the user only enters valid paths. I.e. paths with single or double backslashes should work fine. If a user deliberately tries to break things, it'll probably be possible to make it fall apart. But the only thing they have to gain there is their own config file getting messed up :sweat_smile:
There is a WIP PR up at #1076, it's still WIP though (it may be very broken so I don't recommend testing yet). I'll ping when there's more work done on it.
Also, based on https://github.com/sonic2kk/steamtinkerlaunch/issues/1072#issuecomment-2016674914, do you think #1073 can be merged? If so, I'll get that in and rebase #1076 against it so it gets the spaced launch option fix.
EDIT: Yeah, #1076 does not work. It saves checkbox values as "TRUE"
instead of as 0
/1
values. Not sure why.
EDIT2: Oh, duh, because we map TRUE
/FALSE
to 1
/0
later on. Just gotta move where we set ESCAPED_CFGVALUE
I guess.
Okay, #1076 should be in a working state now. It should allow you to go from a blank CUSTOMCMD_ARGS
, to having --launch Z:\this\is\sparta
and being able to save it appropriately to the game config.
However, before testing, please either:
~/.config/steamtinkerlaunch
, if it is not unreasonably huge, orglobal.conf
.
b. default_template.conf
.
c. your entire gamecfgs
folder.I mangled mine by accident during testing :sweat_smile:
With #1073 and #1076, if they both work, we should be out of the woods with this issue. #1076 in particular if it works should be good at more widely fixing issues saving values with backslashes. So this has been a very helpful issue, the scope of what it fixes extends beyond just custom commands!
Yeah, I think #1073 can be merged. I have been using it since yesterday, and I have been able to boot P3R with my mods by first setting CUSTOMCMD_ARGS="--launch Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe"
in my game config file. Afterward, I can save it with the GUI, and everything will be fine.
can you merge #1073 and then rebase #1076 on that? I'll then test #1076 if I can set the CUSTOMCMD_ARGS
from an empty state to the backslashed path without restoring to editing the config or escaping the slashes.
Back up your entire ~/.config/steamtinkerlaunch
no worries there I always backup my .config
folder don't know how many times I broke something and had to restore lol
Thanks! #1073 has been merged, #1076 has been rebased :-)
Testing #1076 now everything seems like its working as it should. I decided to delete (after backing up ofc) the P3R config file and see if I could set it all up from scratch... everything worked. I was able to set the custom command to the mod loader and then pass the arguments to launch P3R, and everything worked. I didn't have to escape or do anything like that.
so seems like its working perfectly and I even haven't been able to find any regressions in writing the config file out so that's also good
Awesome, thank you so much for testing that branch and all the others :-)
I will do a bit more testing and if there are no issues I will merge it. If I encounter any problems from then on running on master we can revert the merge and re-visit this issue.
Once #1076 is merged I will close this issue. I'll link the PR to this issue now so it can be done automatically on merge.
This issue should be fixed now that #1073, #1074, and #1076 have been merged.
Thanks for all your patience testing this and helping to get it resolved! Hope it helps :-)
System Information
Issue Description
Sometimes you may need to pass a windows path(meaning using
\
instead of/
) to a custom command (For example to load Persona 3 reloaded with mods from Reloaded II you would use--launch "Z:\home\zany130\.local\share\Steam\steamapps\common\P3R\P3R\Binaries\Win64\P3R.exe
)however STL seems to store these paths incorrectly (For example
CUSTOMCMD_ARGS="--launch "Z:homezany130.localshareSteamsteamappsmmonP3RP3RBinariesWin64P3R.exe""
in my case)Logs
31337.log