summaryrefslogtreecommitdiff
path: root/betterdiscordctl
diff options
context:
space:
mode:
Diffstat (limited to 'betterdiscordctl')
-rwxr-xr-xbetterdiscordctl661
1 files changed, 0 insertions, 661 deletions
diff --git a/betterdiscordctl b/betterdiscordctl
deleted file mode 100755
index 00d9a19..0000000
--- a/betterdiscordctl
+++ /dev/null
@@ -1,661 +0,0 @@
-#!/usr/bin/env bash
-
-set -ueo pipefail
-shopt -s dotglob extglob nullglob
-
-# Constants
-VERSION=1.7.0
-SOURCE=$(readlink -f "${BASH_SOURCE[0]}")
-DISABLE_UPGRADE=
-
-# Options
-cmd=status
-verbosity=0
-scan=(/opt /usr/share /usr/lib64)
-flavors=('' canary ptb)
-discord=
-modules=
-bd_repo='https://github.com/rauenzi/BetterDiscordApp'
-bd_repo_branch=injector
-bd=
-copy_bd=
-snap=
-flatpak=
-upgrade_url='https://github.com/bb010g/betterdiscordctl/raw/master/betterdiscordctl'
-
-# Variables
-flavor=
-core=
-xdg_config=${XDG_CONFIG_HOME:-$HOME/.config}
-data=${XDG_DATA_HOME:-$HOME/.local/share}/betterdiscordctl
-snap_bin=snap
-flatpak_bin=flatpak
-
-show_help() {
- cat << EOF
-Usage: ${0##*/} [COMMAND] [OPTION...]
-
-Options:
- -V, --version Display version info and exit
- -h, --help Display this help message and exit
- -v, --verbose Increase verbosity
- -s, --scan=DIRECTORIES Colon-separated list of directories to scan for
- a Discord installation
- (default '/opt:/usr/share')
- -f, --flavors=FLAVORS Colon-separated list of Discord flavors
- (default ':canary:ptb')
- -d, --discord=DIRECTORY Use the specified Discord directory
- (requires --modules)
- -m, --modules=DIRECTORY Use the specified Discord modules directory
- -r, --bd-repo=REPOSITORY Use the specified Git repo for BetterDiscord
- --bd-repo-branch=BRANCH Use the specified Git branch for BetterDiscord
- (default 'stable16')
- -b, --betterdiscord=DIRECTORY Use the specified BetterDiscord directory
- -c, --copy-bd Copy BD directory instead of symlinking
- --snap[=COMMAND] Use the Snap version of Discord (optionally
- using the specified snap command)
- --flatpak[=COMMAND] Use the Flatpak version of Discord (optionally
- using the specified flatpak command)
- --upgrade-url=URL Custom URL to upgrade betterdiscordctl with
-
-Commands:
- status (default) Show the current Discord patch state.
- install Install BetterDiscord.
- reinstall Reinstall BetterDiscord.
- update Update BetterDiscord.
- uninstall Uninstall BetterDiscord.
- upgrade Update betterdiscordctl.
-EOF
-}
-
-verbose() {
- if (( verbosity >= $1 )); then
- shift
- printf '%s\n' "$1" >&2
- fi
-}
-
-die() {
- while [ $# -gt 0 ]; do
- printf '%s\n' "$1" >&2
- shift
- done
- exit 1
-}
-
-die_with_help() {
- die "$@" 'Use "--help" for more information.'
-}
-
-die_non_empty() {
- die_with_help "ERROR: \"$1\" requires a non-empty option argument."
-}
-
-while :; do
- if [[ -z ${1+x} ]]; then break; fi
- case $1 in
- status|install|reinstall|update|uninstall|upgrade)
- cmd=$1
- ;;
- -V|--version)
- printf 'betterdiscordctl %s\n' "$VERSION" >&2
- exit
- ;;
- -h|-\?|--help)
- show_help; exit
- ;;
- -v|--verbose)
- ((++verbosity))
- ;;
- -s|--scan)
- if [[ ${2+x} ]]; then IFS=':' read -ra scan <<< "$2"; shift
- else die_non_empty '--scan'; fi
- ;;
- --scan=?*)
- IFS=':' read -ra scan <<< "${1#*=}"
- ;;
- --scan=)
- die_non_empty '--scan'
- ;;
- -f|--flavors)
- if [[ ${2+x} ]]; then IFS=':' read -ra flavors <<< "$2"; shift
- else die_non_empty '--flavors'; fi
- ;;
- --flavors=?*)
- IFS=':' read -ra flavors <<< "${1#*=}"
- ;;
- --flavors=)
- die_non_empty '--flavors'
- ;;
- -d|--discord)
- if [[ ${2+x} ]]; then discord=$2; shift
- else die_non_empty '--discord'; fi
- ;;
- --discord=?*)
- discord=${1#*=}
- ;;
- --discord=)
- die_non_empty '--discord'
- ;;
- -m|--modules)
- if [[ ${2+x} ]]; then modules=$2; shift
- else die_non_empty '--modules'; fi
- ;;
- --modules=?*)
- modules=${1#*=}
- ;;
- --modules=)
- die_non_empty '--modules'
- ;;
- --bd-repo-branch)
- if [[ ${2+x} ]]; then bd_repo_branch=$2; shift
- else die_non_empty '--bd-repo-branch'; fi
- ;;
- --bd-repo-branch=?*)
- bd_repo_branch=${1#*=}
- ;;
- --bd-repo-branch=)
- die_non_empty '--bd-repo-branch'
- ;;
- -r|--bd-repo)
- if [[ ${2+x} ]]; then bd_repo=$2; shift
- else die_non_empty '--bd-repo'; fi
- ;;
- --bd-repo=?*)
- bd_repo=${1#*=}
- ;;
- --bd-repo=)
- die_non_empty '--bd-repo'
- ;;
- -b|--betterdiscord)
- if [[ ${2+x} ]]; then bd=$2; shift
- else die_non_empty '--betterdiscord'; fi
- ;;
- --betterdiscord=?*)
- bd=${1#*=}
- ;;
- --betterdiscord=)
- die_non_empty '--betterdiscord'
- ;;
- -c|--copy-bd)
- copy_bd=yes
- ;;
- --snap)
- snap=yes
- copy_bd=yes
- ;;
- --snap=?*)
- snap=yes
- copy_bd=yes
- snap_bin=${1#*=}
- ;;
- --snap=)
- die_non_empty '--snap'
- ;;
- --flatpak)
- flatpak=yes
- copy_bd=yes
- ;;
- --flatpak=?*)
- flatpak=yes
- copy_bd=yes
- flatpak_bin=${1#*=}
- ;;
- --flatpak=)
- die_non_empty '--flatpak'
- ;;
- --upgrade-url)
- if [[ ${2+x} ]]; then upgrade_url=$2; shift
- else die_non_empty '--upgrade-url'; fi
- ;;
- --upgrade-url=?*)
- upgrade_url=${1#*=}
- ;;
- --upgrade-url=)
- die_non_empty '--upgrade-url'
- ;;
- --)
- shift
- break
- ;;
- -?*)
- printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
- ;;
- *)
- break
- esac
- shift
-done
-
-mkdir -p "$data"
-[[ -f $data/bd_map ]] || touch "$data/bd_map"
-
-# Commands
-
-bdc_status() {
- index_mod=no
- linked_dir=no
- linked_repo=no
- if [[ -d $core/injector ]]; then
- if [[ -h $core/injector ]]; then
- linked_dir=$(readlink "$core/injector")
- if pushd "$core/injector" >/dev/null; then
- linked_repo=$(git remote get-url origin 2>/dev/null || printf 'no\n')
- popd >/dev/null
- else
- linked_dir="(broken link) $linked_dir"
- fi
- fi
- fi
- if [[ ! -f $core/index.js ]]; then
- index_mod='(missing) no'
- else
- grep -q 'injector' "$core/index.js" && index_mod=yes
- fi
-
- printf 'Discord: %s
-Modules: %s
-Index modified: %s
-Linked injector directory: %s
-Linked injector repository: %s\n' \
- "$discord" "$modules" "$index_mod" "$linked_dir" "$linked_repo"
-}
-
-bdc_install() {
- [[ -d $core/injector ]] && die 'ERROR: Already installed.'
-
- # Clean up legacy cruft
- if [[ -d $core/core ]]; then
- printf 'Removing legacy core directory...\n' >&2
- rm -rf "$core/core"
- fi
-
- bd_patch
- bd_injector
-
- printf 'Installed. (Restart Discord if necessary.)\n' >&2
-}
-
-bdc_reinstall() {
- [[ -d $core/injector ]] || die 'Not installed.'
-
- bdc_kill
-
- verbose 1 'V: Removing old injector folder.'
- rm -rf "$core/injector"
-
- bd_patch
- bd_injector
-
- printf 'Reinstalled.\n' >&2
-}
-
-bdc_update() {
- [[ -d $core/injector ]] || die 'Not installed.'
-
- if ! pushd "$core/injector" >/dev/null; then
- if [[ -h $core/injector ]]; then
- die 'ERROR: BetterDiscord injector symbolic link is broken.'
- else
- die 'ERROR: BetterDiscord injector location is not a directory.'
- fi
- fi
- if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
- printf 'Updating Git repository...\n' >&2
- git fetch origin "$bd_repo_branch"
- git reset --hard FETCH_HEAD
- else
- printf 'WARN: No Git repository found.\n' >&2
- fi
- popd >/dev/null
-}
-
-bdc_uninstall() {
- [[ -d $core/injector ]] || die 'Not installed.'
-
- bdc_kill
- bd_unpatch
-
- # Remove managed BD repo if applicable
- bd_n=$(bd_map_get_dir "$discord" | bd_map_entry_n)
- bd_map_remove "$discord"
- if [[ -z $(bd_map_get_n "$bd_n") ]]; then
- verbose 2 "VV: Removing $data/bd/$bd_n"
- rm -rf "$data/bd/$bd_n"
- fi
-
- printf 'Uninstalled.\n' >&2
-}
-
-bdc_upgrade() {
- if [[ $DISABLE_UPGRADE ]]; then
- die 'ERROR: Upgrading has been disabled.' \
- 'If you installed this from a package, its maintainer should keep it up to date.'
- fi
-
- github_version=$(curl -NLSs "$upgrade_url" | sed -n 's/^VERSION=//p')
- if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
- die "ERROR: GitHub couldn't be reached to check the version."
- fi
- verbose 2 "VV: Script location: $SOURCE"
- verbose 2 "VV: Upgrade URL: $upgrade_url"
- verbose 1 "V: Local version: $VERSION"
- verbose 1 "V: GitHub version: $github_version"
- semver_diff=$(Semver::compare "$github_version" "$VERSION")
- if [[ $semver_diff -eq 1 ]]; then
- printf 'Downloading betterdiscordctl...\n' >&2
- if curl -LSso "$SOURCE" "$upgrade_url"; then
- printf 'Successfully updated betterdiscordctl.\n' >&2
- else
- die 'ERROR: Failed to update betterdiscordctl.' \
- 'You may want to rerun this command with sudo.'
- fi
- else
- if [[ $semver_diff -eq 0 ]]; then
- printf 'betterdiscordctl is already the latest version (%s).\n' "$VERSION" >&2
- else
- printf 'Local version (%s) is higher than GitHub version (%s).\n' "$VERSION" "$github_version" >&2
- fi
- fi
-}
-
-# Implementation functions
-
-bdc_main() {
- if [[ -z $discord ]]; then
- if [[ $snap ]]; then bdc_snap
- elif [[ $flatpak ]]; then bdc_flatpak
- else bdc_scan; fi
- else
- flavor=$flavors
- # --discord and --modules
- [[ -z $modules ]] && die_with_help 'ERROR: "--discord" requires "--modules" to also be set.'
- [[ -d $discord ]] || die 'ERROR: Discord installation not found.'
- [[ -d $modules ]] || die 'ERROR: Discord modules directory not found.'
- fi
- [[ -d $discord ]] || die 'ERROR: Discord installation not found. Try specifying it with "--discord".'
- core=$modules/discord_desktop_core
- [[ -d $core ]] || die "ERROR: Directory 'discord_desktop_core' not found in $(readlink -f "$modules")"
-}
-
-bdc_scan() {
- for scandir in "${scan[@]}"; do
- verbose 2 "VV: Scanning $scandir"
- for flavor in "${flavors[@]}"; do
- verbose 2 "VV: Trying flavor '$flavor'"
- shopt -s nocaseglob
- for discord in "$scandir"/discord?(-)"$flavor"; do
- shopt -u nocaseglob
- if [[ -d $discord ]]; then
- verbose 1 "V: Using Discord at $discord"
- discord_config=$xdg_config/discord${flavor,,}
- if [[ ! -d $discord_config ]]; then
- printf 'WARN: Config directory not found for Discord %s (%s, %s).\n' \
- "$flavor" "$discord" "$discord_config" >&2
- continue 2
- fi
- if [[ -z $modules ]]; then
- bdc_find_modules
- else
- # --modules
- [[ -d $modules ]] || die 'ERROR: Discord modules directory not found.'
- fi
- break 3
- fi
- done
- done
- done
-}
-
-bdc_find_modules() {
- declare -a all_modules
- all_modules=("$discord_config/"+([0-9]).+([0-9]).+([0-9])/modules)
- ((${#all_modules[@]})) || die 'ERROR: Discord modules directory not found.'
- modules=${all_modules[-1]}
- verbose 1 "V: Found modules in $modules"
-}
-
-bdc_snap() {
- # shellcheck disable=SC2016
- # Expansion should happen inside snap's shell.
- snap_location=$("$snap_bin" run --shell discord <<< $'printf -- \'%s\n\' "$SNAP" 1>&3' 3>&1)
- discord=${snap_location:?}/usr/share/discord
- verbose 2 "VV: Checking $discord"
- if [[ -d $discord ]]; then
- verbose 1 "V: Using Discord at $discord"
- # shellcheck disable=SC2016
- # Expansion should happen inside snap's shell.
- xdg_config=$("$snap_bin" run --shell discord <<< $'printf -- \'%s/.config\n\' "$SNAP_USER_DATA" 1>&3' 3>&1)
- discord_config=$xdg_config/discord
- bdc_find_modules
- else
- die 'ERROR: Discord installation not found.'
- fi
-}
-
-bdc_flatpak() {
- flatpak_version=$("$flatpak_bin" --version | sed -n 's/Flatpak //p')
- if [[ $(Semver::compare "$flatpak_version" '1.0.0') -eq -1 ]]; then
- die 'ERROR: You are using an unsupported version of Flatpak.' \
- 'See https://github.com/bb010g/betterdiscordctl/issues/45'
- fi
- # flatpak sucks and doesn't use stderr for warnings.
- # https://github.com/flatpak/flatpak/blob/13e449b/app/flatpak-main.c#L259-L286
- # This really should be better for directories with newlines, but...
- # We're just going to grab the last line and hope for the best.
- flatpak_location=$("$flatpak_bin" info --show-location com.discordapp.Discord)
- flatpak_location=${flatpak_location##*$'\n'}
- if [[ -d ${flatpak_location:?}/files/discord ]]; then
- discord=$flatpak_location/files/discord
- else
- discord=$flatpak_location/files/extra
- fi
- verbose 2 "VV: Checking $discord"
- if [[ -d $discord ]]; then
- verbose 1 "V: Using Discord at $discord"
- # shellcheck disable=SC2016
- # Expansion should happen inside flatpak's shell.
- flatpak_config=$("$flatpak_bin" run --command=sh com.discordapp.Discord -c $'printf -- \'%s\n\' "$XDG_CONFIG_HOME"')
- discord_config=${flatpak_config:-$HOME/.var/app/com.discordapp.Discord/config}/discord
- if [[ ! -d $discord_config ]]; then
- printf 'WARN: Config directory not found for Discord (%s, %s).\n' "$discord" "$discord_config" >&2
- fi
- bdc_find_modules
- else
- die 'ERROR: Discord installation not found.'
- fi
-}
-
-bdc_kill() {
- declare process_name=Discord
- [[ $flavor ]] && process_name+=" $flavor"
- printf 'Killing %s processes...\n' "$process_name" >&2
- pkill -exi -KILL "discord-?$flavor" || printf 'No active processes found.\n' >&2
-}
-
-bd_injector() {
- if [[ -z $bd ]]; then
- bd=$data/bd/$(bd_map_add "$discord" "$bd_repo")
- if [[ ! -d $bd ]]; then
- printf 'Cloning %s...\n' "$bd_repo" >&2
- git clone "$bd_repo" -b "$bd_repo_branch" --depth=1 --single-branch "$bd"
- fi
- fi
-
- if [[ $copy_bd ]]; then
- verbose 1 'V: Copying BetterDiscord injector...'
- cp -r "$bd" "$core/injector"
- else
- verbose 1 'V: Linking BetterDiscord injector...'
- ln -s "$bd" "$core/injector"
- fi
-}
-
-bd_patch() {
- if ! grep -q 'injector' "$core/index.js"; then
- verbose 1 'V: Injecting into index.js...'
- sed -i "$core/index.js" \
- -e "1i require('./injector');" \
- -e "s/core'/core.asar'/"
- fi
-}
-
-bd_unpatch() {
- verbose 1 'V: Removing BetterDiscord injection...'
- sed -i "$core/index.js" \
- -e '/injector/d' \
- -e "s/core'/core.asar'/"
- rm -rf "$core/injector"
-}
-
-bd_map_entry_n() {
- sed 's/^.*\t\t.*\t\(.*\)$/\1/' "$@"
-}
-
-bd_map_fresh() {
- verbose 2 'VV: Generating fresh bd_map number...'
- bd_map_entry_n "$data/bd_map" | sort | awk \
- 'BEGIN {max=-1} NF != 0 {if ($1>max+1) {exit}; max=$1} END {print max+1}'
-}
-
-bd_map_add() {
- entry=$(bd_map_get_repo "$2")
- if [[ $entry ]]; then
- num=$(head -n1 <<< "$entry" | bd_map_entry_n)
- else
- num=$(bd_map_fresh)
- fi
- printf '%s\t\t%s\t%s\n' "$1" "$2" "$num" >> "$data/bd_map"
- printf '%s\n' "$num"
-}
-
-bd_map_get_dir() {
- grep -F "$1"$'\t\t' "$data/bd_map"
-}
-
-bd_map_get_repo() {
- grep -F $'\t\t'"$1"$'\t' "$data/bd_map"
-}
-
-bd_map_get_n() {
- grep $'\t'"$1\$" "$data/bd_map"
-}
-
-bd_map_remove() {
- sed -i "$data/bd_map" -e "\\%$1\\t\\t%d"
-}
-
-# Included from https://github.com/bb010g/Semver.sh , under the MIT License.
-
-Semver::validate() {
- # shellcheck disable=SC2064
- trap "$(shopt -p extglob)" RETURN
- shopt -s extglob
-
- declare normal=${1%%[+-]*}
- declare extra=${1:${#normal}}
-
- declare major=${normal%%.*}
- if [[ $major != +([0-9]) ]]; then echo "Semver::validate: invalid major: $major" >&2; return 1; fi
- normal=${normal:${#major}+1}
- declare minor=${normal%%.*}
- if [[ $minor != +([0-9]) ]]; then echo "Semver::validate: invalid minor: $minor" >&2; return 1; fi
- declare patch=${normal:${#minor}+1}
- if [[ $patch != +([0-9]) ]]; then echo "Semver::validate: invalid patch: $patch" >&2; return 1; fi
-
- declare -r ident="+([0-9A-Za-z-])"
- declare pre=${extra%%+*}
- declare pre_len=${#pre}
- if [[ $pre_len -gt 0 ]]; then
- pre=${pre#-}
- if [[ $pre != $ident*(.$ident) ]]; then echo "Semver::validate: invalid pre-release: $pre" >&2; return 1; fi
- fi
- declare build=${extra:pre_len}
- if [[ ${#build} -gt 0 ]]; then
- build=${build#+}
- if [[ $build != $ident*(.$ident) ]]; then echo "Semver::validate: invalid build metadata: $build" >&2; return 1; fi
- fi
-
- if [[ $2 ]]; then
- echo "$2=(${major@Q} ${minor@Q} ${patch@Q} ${pre@Q} ${build@Q})"
- else
- echo "$1"
- fi
-}
-
-Semver::compare() {
- declare -a x y
- eval "$(Semver::validate "$1" x)"
- eval "$(Semver::validate "$2" y)"
-
- declare x_i y_i i
- for i in 0 1 2; do
- x_i=${x[i]}; y_i=${y[i]}
- if [[ $x_i -eq $y_i ]]; then continue; fi
- if [[ $x_i -gt $y_i ]]; then echo 1; return; fi
- if [[ $x_i -lt $y_i ]]; then echo -1; return; fi
- done
-
- x_i=${x[3]}; y_i=${y[3]}
- if [[ -z $x_i && $y_i ]]; then echo 1; return; fi
- if [[ $x_i && -z $y_i ]]; then echo -1; return; fi
-
- declare -a x_pre; declare x_len
- declare -a y_pre; declare y_len
- IFS=. read -ra x_pre <<< "$x_i"; x_len=${#x_pre[@]}
- IFS=. read -ra y_pre <<< "$y_i"; y_len=${#y_pre[@]}
-
- if (( x_len > y_len )); then echo 1; return; fi
- if (( x_len < y_len )); then echo -1; return; fi
-
- for (( i=0; i < x_len; i++ )); do
- x_i=${x_pre[i]}; y_i=${y_pre[i]}
- if [[ $x_i = "$y_i" ]]; then continue; fi
-
- declare num_x num_y
- num_x=$([[ $x_i = +([0-9]) ]] && echo "$x_i")
- num_y=$([[ $y_i = +([0-9]) ]] && echo "$y_i")
- if [[ $num_x && $num_y ]]; then
- if [[ $x_i -gt $y_i ]]; then echo 1; return; fi
- if [[ $x_i -lt $y_i ]]; then echo -1; return; fi
- else
- if [[ $num_y ]]; then echo 1; return; fi
- if [[ $num_x ]]; then echo -1; return; fi
- if [[ $x_i > $y_i ]]; then echo 1; return; fi
- if [[ $x_i < $y_i ]]; then echo -1; return; fi
- fi
- done
-
- echo 0
-}
-
-# Run command
-
-case "$cmd" in
- status)
- bdc_main
- bdc_status
- ;;
- install)
- bdc_main
- bdc_install
- ;;
- reinstall)
- bdc_main
- bdc_reinstall
- ;;
- update)
- bdc_main
- bdc_update
- ;;
- uninstall)
- bdc_main
- bdc_uninstall
- ;;
- upgrade)
- bdc_upgrade
- ;;
- *)
- die "ERROR: Unknown command: $cmd"
- ;;
-esac