fix: patch the steamrt3 Steam client
This commit is contained in:
1 parent
3c000b8a6e
commit
6f62c7f21c
3 files changed
+173
-64
No files matched your search
@@ -133,6 +133,12 @@ helper, inside Steam's own installation:
|
|||||||
|
|
||||||
~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
|
|
||||||
|
The steamrt3 client, a beta for now, has a script of its own:
|
||||||
|
|
||||||
|
~/.local/share/Steam/steamrt64/steamwebhelper.sh
|
||||||
|
|
||||||
|
Both are patched where both are there, so switching clients keeps autoscroll.
|
||||||
|
|
||||||
Where that installation is depends on how Steam was installed:
|
Where that installation is depends on how Steam was installed:
|
||||||
_~/.local/share/Steam_ for Valve's own package and Arch's,
|
_~/.local/share/Steam_ for Valve's own package and Arch's,
|
||||||
_~/.steam/debian-installation_ for Debian's, and the private tree of the
|
_~/.steam/debian-installation_ for Debian's, and the private tree of the
|
||||||
@@ -154,11 +160,16 @@ it was given arguments for, and that one carries no arguments of anybody's. One
|
|||||||
wrong length costs the whole client package downloaded, extracted and installed
|
wrong length costs the whole client package downloaded, extracted and installed
|
||||||
again, and a client that quits at the end of it instead of coming up.
|
again, and a client that quits at the end of it instead of coming up.
|
||||||
|
|
||||||
So where the comments cannot pay for the argument, or a client update has
|
The steamrt3 script has no comments to pay with. So it is copied aside as
|
||||||
changed how the helper is started, nothing is written and the status screen
|
_steamwebhelper.sh.orig_, and a stub of the same size takes its place. The stub
|
||||||
says Steam is not patched. Nothing goes on Steam's launcher entry, its
|
runs the copy with the argument added. Steam only checks the files it knows,
|
||||||
autostart entry or the shortcuts it writes for single games either, and Steam
|
and the copy is not one of them.
|
||||||
goes on repairing its own installation.
|
|
||||||
|
So where neither fits, or a client update has changed how the helper is
|
||||||
|
started, nothing is written and the status screen says Steam is not patched.
|
||||||
|
Nothing goes on Steam's launcher entry, its autostart entry or the shortcuts it
|
||||||
|
writes for single games either, and Steam goes on repairing its own
|
||||||
|
installation.
|
||||||
|
|
||||||
An installation patched by an earlier version, which appended where the
|
An installation patched by an earlier version, which appended where the
|
||||||
comments were short, is written again to fit at the next apply, or taken back
|
comments were short, is written again to fit at the next apply, or taken back
|
||||||
|
|||||||
@@ -30,12 +30,17 @@ PathModified=%h/.guix-profile/share/applications
|
|||||||
|
|
||||||
# Steam replaces the script that starts its interface on every client update,
|
# Steam replaces the script that starts its interface on every client update,
|
||||||
# which takes the patch with it. Where that installation lives depends on how
|
# which takes the patch with it. Where that installation lives depends on how
|
||||||
# Steam was installed.
|
# Steam was installed. The steamrt3 client has a script of its own.
|
||||||
PathChanged=%h/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
PathChanged=%h/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
PathChanged=%h/.steam/debian-installation/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
PathChanged=%h/.steam/debian-installation/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
PathChanged=%h/.var/app/com.valvesoftware.Steam/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
PathChanged=%h/.var/app/com.valvesoftware.Steam/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
PathChanged=%h/.var/app/com.valvesoftware.Steam/data/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
PathChanged=%h/.var/app/com.valvesoftware.Steam/data/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
PathChanged=%h/snap/steam/common/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
PathChanged=%h/snap/steam/common/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
|
PathChanged=%h/.local/share/Steam/steamrt64/steamwebhelper.sh
|
||||||
|
PathChanged=%h/.steam/debian-installation/steamrt64/steamwebhelper.sh
|
||||||
|
PathChanged=%h/.var/app/com.valvesoftware.Steam/.local/share/Steam/steamrt64/steamwebhelper.sh
|
||||||
|
PathChanged=%h/.var/app/com.valvesoftware.Steam/data/Steam/steamrt64/steamwebhelper.sh
|
||||||
|
PathChanged=%h/snap/steam/common/.local/share/Steam/steamrt64/steamwebhelper.sh
|
||||||
|
|
||||||
Unit=middleclick-autoscroll.service
|
Unit=middleclick-autoscroll.service
|
||||||
|
|
||||||
|
|||||||
+151
-58
@@ -9,6 +9,10 @@
|
|||||||
#
|
#
|
||||||
# ~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
# ~/.local/share/Steam/ubuntu12_64/steamwebhelper_sniper_wrap.sh
|
||||||
#
|
#
|
||||||
|
# The steamrt3 client, a beta for now, has a script of its own:
|
||||||
|
#
|
||||||
|
# ~/.local/share/Steam/steamrt64/steamwebhelper.sh
|
||||||
|
#
|
||||||
# Steam compares the installed files against its manifest at every start (by
|
# Steam compares the installed files against its manifest at every start (by
|
||||||
# size and timestamp, not by content) and restores whatever differs.
|
# size and timestamp, not by content) and restores whatever differs.
|
||||||
# So the patch is written to look untouched: the bytes the flag costs are taken
|
# So the patch is written to look untouched: the bytes the flag costs are taken
|
||||||
@@ -28,6 +32,10 @@
|
|||||||
# all: no autoscroll in the interface is a smaller thing than a client that
|
# all: no autoscroll in the interface is a smaller thing than a client that
|
||||||
# reinstalls itself.
|
# reinstalls itself.
|
||||||
#
|
#
|
||||||
|
# The steamrt3 script has no comments to give back. So it is copied aside, as
|
||||||
|
# it is, and replaced by a stub of the same size that runs the copy with the
|
||||||
|
# flag. See _mca_steam_stub.
|
||||||
|
#
|
||||||
# The file comes back on every client update, and the watcher re-applies the
|
# The file comes back on every client update, and the watcher re-applies the
|
||||||
# patch when that happens.
|
# patch when that happens.
|
||||||
|
|
||||||
@@ -60,24 +68,28 @@ mca_steam_roots() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# The script to patch inside a Steam installation. Newer clients start the
|
# The scripts to patch inside a Steam installation, one per client. The default
|
||||||
# helper through a wrapper inside the container runtime; older ones exec it
|
# client starts the helper through a wrapper inside the container runtime;
|
||||||
# from steamwebhelper.sh directly, and that one forwards its arguments too.
|
# older ones exec it from steamwebhelper.sh directly, and that one forwards its
|
||||||
mca_steam_script() {
|
# arguments too. The steamrt3 client has its own. Both clients are patched
|
||||||
local root="$1" f
|
# where both are there, so switching between them keeps autoscroll.
|
||||||
|
mca_steam_scripts() {
|
||||||
|
local root="$1" f found=1
|
||||||
for f in \
|
for f in \
|
||||||
"$root/ubuntu12_64/steamwebhelper_sniper_wrap.sh" \
|
"$root/ubuntu12_64/steamwebhelper_sniper_wrap.sh" \
|
||||||
"$root/ubuntu12_64/steamwebhelper.sh"
|
"$root/ubuntu12_64/steamwebhelper.sh"
|
||||||
do
|
do
|
||||||
[[ -f $f && -w $f ]] && { printf '%s\n' "$f"; return 0; }
|
[[ -f $f && -w $f ]] && { printf '%s\n' "$f"; found=0; break; }
|
||||||
done
|
done
|
||||||
return 1
|
f="$root/steamrt64/steamwebhelper.sh"
|
||||||
|
[[ -f $f && -w $f ]] && { printf '%s\n' "$f"; found=0; }
|
||||||
|
return "$found"
|
||||||
}
|
}
|
||||||
|
|
||||||
mca_steam_installed() {
|
mca_steam_installed() {
|
||||||
local root
|
local root
|
||||||
while IFS= read -r root; do
|
while IFS= read -r root; do
|
||||||
mca_steam_script "$root" > /dev/null && return 0
|
mca_steam_scripts "$root" > /dev/null && return 0
|
||||||
done < <(mca_steam_roots)
|
done < <(mca_steam_roots)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@@ -87,13 +99,17 @@ mca_steam_script_patched() {
|
|||||||
grep -q -- "$MCA_FEATURE" "$1" 2>/dev/null
|
grep -q -- "$MCA_FEATURE" "$1" 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Whether every script there is patched. One that is not is a client that
|
||||||
|
# starts without autoscroll.
|
||||||
mca_steam_patched() {
|
mca_steam_patched() {
|
||||||
local root script
|
local root script found=0
|
||||||
while IFS= read -r root; do
|
while IFS= read -r root; do
|
||||||
script="$(mca_steam_script "$root")" || continue
|
while IFS= read -r script; do
|
||||||
mca_steam_script_patched "$script" && return 0
|
mca_steam_script_patched "$script" || return 1
|
||||||
|
found=1
|
||||||
|
done < <(mca_steam_scripts "$root")
|
||||||
done < <(mca_steam_roots)
|
done < <(mca_steam_roots)
|
||||||
return 1
|
(( found ))
|
||||||
}
|
}
|
||||||
|
|
||||||
# _mca_steam_exec_line <script>
|
# _mca_steam_exec_line <script>
|
||||||
@@ -163,6 +179,81 @@ _mca_steam_same_size() {
|
|||||||
(( $(wc -c < "$script") == $(printf '%s\n' "$content" | wc -c) ))
|
(( $(wc -c < "$script") == $(printf '%s\n' "$content" | wc -c) ))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Where a stub keeps Steam's own script, and the line that runs it from there.
|
||||||
|
MCA_STEAM_ORIG=.orig
|
||||||
|
MCA_STEAM_STUB="exec \"\$0$MCA_STEAM_ORIG\" \"\$@\""
|
||||||
|
|
||||||
|
# _mca_steam_stub <script> <flags>
|
||||||
|
# The stub on stdout, for a script with no comments to pay for the flags. It
|
||||||
|
# is exactly as long as the script and runs Steam's own script, kept next to
|
||||||
|
# it, with the flags added. That script hands its arguments on to the helper.
|
||||||
|
# Steam only checks the files in its manifest, and the copy is not one of them.
|
||||||
|
# Fails when the script does not hand its arguments on, has no #! line, or is
|
||||||
|
# too short to hold the stub.
|
||||||
|
_mca_steam_stub() {
|
||||||
|
local script="$1" flags="$2" head body pad
|
||||||
|
|
||||||
|
[[ -n "$(_mca_steam_exec_line "$script")" ]] || return 1
|
||||||
|
head="$(head -n 1 -- "$script")"
|
||||||
|
[[ $head == '#!'* ]] || return 1
|
||||||
|
|
||||||
|
body="$MCA_STEAM_STUB $flags"
|
||||||
|
pad=$(( $(wc -c < "$script") - $(printf '%s\n%s\n' "$head" "$body" | wc -c) ))
|
||||||
|
(( pad >= 0 )) || return 1
|
||||||
|
|
||||||
|
# The bytes left over go into a comment line.
|
||||||
|
printf '%s\n' "$head"
|
||||||
|
if (( pad == 1 )); then
|
||||||
|
printf '\n'
|
||||||
|
elif (( pad > 1 )); then
|
||||||
|
printf '#%*s\n' $(( pad - 2 )) ''
|
||||||
|
fi
|
||||||
|
printf '%s' "$body"
|
||||||
|
}
|
||||||
|
|
||||||
|
# _mca_steam_is_stub <script>
|
||||||
|
_mca_steam_is_stub() {
|
||||||
|
grep -qF -- "$MCA_STEAM_STUB" "$1" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# _mca_steam_text <script> <flags>
|
||||||
|
# The patched script on stdout: from the comments if they can pay for the
|
||||||
|
# flags, as a stub if not. Fails when neither keeps the size.
|
||||||
|
_mca_steam_text() {
|
||||||
|
local script="$1" flags="$2" out
|
||||||
|
|
||||||
|
if ! { out="$(_mca_steam_build "$script" "$flags")" \
|
||||||
|
&& _mca_steam_same_size "$script" "$out"; }
|
||||||
|
then
|
||||||
|
out="$(_mca_steam_stub "$script" "$flags")" \
|
||||||
|
&& _mca_steam_same_size "$script" "$out" || return 1
|
||||||
|
fi
|
||||||
|
printf '%s' "$out"
|
||||||
|
}
|
||||||
|
|
||||||
|
# _mca_steam_write <script> <backup> <content>
|
||||||
|
# Writes the patched script. <backup> is the untouched copy kept for undoing.
|
||||||
|
_mca_steam_write() {
|
||||||
|
local script="$1" backup="$2" content="$3"
|
||||||
|
|
||||||
|
# A stub needs Steam's script next to it before it can start anything.
|
||||||
|
if [[ $content == *"$MCA_STEAM_STUB"* ]]; then
|
||||||
|
cp -p -- "$backup" "$script$MCA_STEAM_ORIG" 2>/dev/null || return 1
|
||||||
|
chmod +x -- "$script$MCA_STEAM_ORIG" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if mca_write_if_changed "$script" "$content"$'\n'; then
|
||||||
|
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
||||||
|
fi
|
||||||
|
chmod +x -- "$script" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Steam looks at when the file was last written as well as at how big
|
||||||
|
# it is, and the copy taken before the edit still carries the original
|
||||||
|
# timestamp. Putting it back costs nothing and removes the other half
|
||||||
|
# of what the client would notice.
|
||||||
|
touch -r "$backup" -- "$script" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
# _mca_steam_refresh_backup <script>
|
# _mca_steam_refresh_backup <script>
|
||||||
# A client update brings a new version of the script, and the copy kept from
|
# A client update brings a new version of the script, and the copy kept from
|
||||||
# before it is no longer what putting it back means. Only ever done while the
|
# before it is no longer what putting it back means. Only ever done while the
|
||||||
@@ -195,15 +286,18 @@ _mca_steam_settle() {
|
|||||||
# Nothing to compare against, so nothing can be said about the length.
|
# Nothing to compare against, so nothing can be said about the length.
|
||||||
[[ -f $copy ]] || return 0
|
[[ -f $copy ]] || return 0
|
||||||
|
|
||||||
# Already the length Steam expects: the patch is a good one.
|
# Already the length Steam expects: the patch is a good one. Unless it is
|
||||||
(( $(wc -c < "$script") == $(wc -c < "$copy") )) && return 0
|
# a stub that lost Steam's script next to it, and would start nothing.
|
||||||
|
if (( $(wc -c < "$script") == $(wc -c < "$copy") )); then
|
||||||
if out="$(_mca_steam_build "$copy" "$flags")" && _mca_steam_same_size "$copy" "$out"; then
|
if _mca_steam_is_stub "$script" && [[ ! -f $script$MCA_STEAM_ORIG ]]; then
|
||||||
if mca_write_if_changed "$script" "$out"$'\n'; then
|
cp -p -- "$copy" "$script$MCA_STEAM_ORIG" 2>/dev/null || true
|
||||||
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
|
||||||
fi
|
fi
|
||||||
chmod +x -- "$script" 2>/dev/null || true
|
return 0
|
||||||
touch -r "$copy" -- "$script" 2>/dev/null || true
|
fi
|
||||||
|
|
||||||
|
if out="$(_mca_steam_text "$copy" "$flags")" \
|
||||||
|
&& _mca_steam_write "$script" "$copy" "$out"
|
||||||
|
then
|
||||||
mca_ledger_add steam "$script" "$name"
|
mca_ledger_add steam "$script" "$name"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@@ -224,41 +318,31 @@ mca_steam_apply() {
|
|||||||
flags="$(mca_flags)"
|
flags="$(mca_flags)"
|
||||||
|
|
||||||
while IFS= read -r root; do
|
while IFS= read -r root; do
|
||||||
script="$(mca_steam_script "$root")" || continue
|
while IFS= read -r script; do
|
||||||
found=1
|
found=1
|
||||||
|
|
||||||
if mca_steam_script_patched "$script"; then
|
if mca_steam_script_patched "$script"; then
|
||||||
_mca_steam_settle "$script" "$flags"
|
_mca_steam_settle "$script" "$flags"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_mca_steam_refresh_backup "$script"
|
_mca_steam_refresh_backup "$script"
|
||||||
|
|
||||||
# Either the comments can pay for the flag or nothing is written.
|
# Either the file keeps its length or nothing is written. A
|
||||||
# A longer file is one Steam reinstalls itself over; a client update
|
# longer file is one Steam reinstalls itself over; a client
|
||||||
# that changed how the helper is started leaves no line to patch at
|
# update that changed how the helper is started leaves no line
|
||||||
# all. Both end here, and this script is what starts Steam's entire
|
# to patch at all. Both end here, and this script is what starts
|
||||||
# interface, so leaving it alone is the only safe answer to either.
|
# Steam's entire interface, so leaving it alone is the only safe
|
||||||
if ! { out="$(_mca_steam_build "$script" "$flags")" \
|
# answer to either.
|
||||||
&& _mca_steam_same_size "$script" "$out"; }
|
if ! out="$(_mca_steam_text "$script" "$flags")"; then
|
||||||
then
|
mca_note "$(mca_msg "Steam starts its interface in a way this version cannot change without Steam noticing; leaving it alone.")"
|
||||||
mca_note "$(mca_msg "Steam starts its interface in a way this version cannot change without Steam noticing; leaving it alone.")"
|
continue
|
||||||
continue
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
backup="$(mca_backup "$script")" || continue
|
backup="$(mca_backup "$script")" || continue
|
||||||
if mca_write_if_changed "$script" "$out"$'\n'; then
|
_mca_steam_write "$script" "$MCA_BACKUPDIR/$backup" "$out" || continue
|
||||||
MCA_CHANGES=$(( MCA_CHANGES + 1 ))
|
mca_ledger_add steam "$script" "$backup"
|
||||||
fi
|
done < <(mca_steam_scripts "$root")
|
||||||
chmod +x -- "$script" 2>/dev/null || true
|
|
||||||
|
|
||||||
# Steam looks at when the file was last written as well as at how big
|
|
||||||
# it is, and the copy taken before the edit still carries the original
|
|
||||||
# timestamp. Putting it back costs nothing and removes the other half
|
|
||||||
# of what the client would notice.
|
|
||||||
touch -r "$MCA_BACKUPDIR/$backup" -- "$script" 2>/dev/null || true
|
|
||||||
|
|
||||||
mca_ledger_add steam "$script" "$backup"
|
|
||||||
done < <(mca_steam_roots)
|
done < <(mca_steam_roots)
|
||||||
|
|
||||||
(( found ))
|
(( found ))
|
||||||
@@ -266,7 +350,9 @@ mca_steam_apply() {
|
|||||||
|
|
||||||
# mca_steam_revert <script> <backup name>
|
# mca_steam_revert <script> <backup name>
|
||||||
mca_steam_revert() {
|
mca_steam_revert() {
|
||||||
local script="$1" backup="$2"
|
local script="$1" backup="$2" orig="$1$MCA_STEAM_ORIG" stub=1 tmp
|
||||||
|
|
||||||
|
_mca_steam_is_stub "$script" || stub=0
|
||||||
|
|
||||||
if [[ -n $backup && -f "$MCA_BACKUPDIR/$backup" ]]; then
|
if [[ -n $backup && -f "$MCA_BACKUPDIR/$backup" ]]; then
|
||||||
if [[ -e $script ]]; then
|
if [[ -e $script ]]; then
|
||||||
@@ -274,14 +360,21 @@ mca_steam_revert() {
|
|||||||
chmod +x -- "$script" 2>/dev/null || true
|
chmod +x -- "$script" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
rm -f -- "$MCA_BACKUPDIR/$backup"
|
rm -f -- "$MCA_BACKUPDIR/$backup"
|
||||||
|
elif (( stub )) && [[ -f $orig ]]; then
|
||||||
|
# No backup, but a stub keeps Steam's own script right next to it.
|
||||||
|
cp -p -- "$orig" "$script" 2>/dev/null || return 1
|
||||||
|
else
|
||||||
|
# No backup to fall back on, so take the flags back out of the exec line.
|
||||||
|
[[ -f $script ]] || return 1
|
||||||
|
tmp="$(mktemp "${script}.XXXXXX")" || return 1
|
||||||
|
sed "s| $MCA_FLAG||g" "$script" > "$tmp" && mv -f "$tmp" "$script" || { rm -f "$tmp"; return 1; }
|
||||||
|
chmod +x -- "$script" 2>/dev/null || true
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# No backup to fall back on, so take the flags back out of the exec line.
|
# The copy goes once the stub that ran it is gone.
|
||||||
[[ -f $script ]] || return 1
|
if (( stub )) && ! _mca_steam_is_stub "$script"; then
|
||||||
local tmp
|
rm -f -- "$orig"
|
||||||
tmp="$(mktemp "${script}.XXXXXX")" || return 1
|
fi
|
||||||
sed "s| $MCA_FLAG||g" "$script" > "$tmp" && mv -f "$tmp" "$script" || { rm -f "$tmp"; return 1; }
|
|
||||||
chmod +x -- "$script" 2>/dev/null || true
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user