1067 lines
31 KiB
Bash
1067 lines
31 KiB
Bash
#!/usr/bin/env bash
|
||
set -u
|
||
|
||
PLUGIN_ID="local.omarchy-citizen"
|
||
PLUGIN_VERSION="0.6.1"
|
||
|
||
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/starcitizen-lug"
|
||
DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||
CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/omarchy-citizen"
|
||
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/omarchy-citizen"
|
||
UPDATE_CACHE="$CACHE_DIR/lug-update-status"
|
||
LOG_FILE="$STATE_DIR/omarchy-citizen.log"
|
||
WINE_CONF="$CONFIG_DIR/winedir.conf"
|
||
GAME_CONF="$CONFIG_DIR/gamedir.conf"
|
||
SELF="$(readlink -f "${BASH_SOURCE[0]}")"
|
||
PLUGIN_DIR="$(cd -- "$(dirname -- "$SELF")" && pwd)"
|
||
SANITIZER="$PLUGIN_DIR/support-sanitize.py"
|
||
BACKEND_EXTERNAL="$HOME/.local/lib/omarchy-citizen/omarchy-citizen-backend"
|
||
BACKEND_BUNDLED="$PLUGIN_DIR/backend/bin/omarchy-citizen-backend"
|
||
|
||
GUI_PACKAGES=(zenity polkit cabextract unzip)
|
||
|
||
mkdir -p "$CACHE_DIR" "$STATE_DIR"
|
||
|
||
rotate_log() {
|
||
local max_bytes=$((4 * 1024 * 1024))
|
||
local keep_bytes=$((2 * 1024 * 1024))
|
||
if [[ -f "$LOG_FILE" ]] && (( $(stat -c '%s' "$LOG_FILE" 2>/dev/null || echo 0) > max_bytes )); then
|
||
tail -c "$keep_bytes" "$LOG_FILE" > "$LOG_FILE.tmp" 2>/dev/null || true
|
||
mv -f "$LOG_FILE.tmp" "$LOG_FILE" 2>/dev/null || true
|
||
fi
|
||
}
|
||
|
||
rotate_log
|
||
|
||
ACTION="${1:-primary}"
|
||
|
||
log_line() {
|
||
local message="$*"
|
||
printf '%s [%s] %s\n' "$(date '+%Y-%m-%dT%H:%M:%S%z')" "$$" "$message" >> "$LOG_FILE" 2>/dev/null || true
|
||
}
|
||
|
||
log_line "action=$ACTION version=$PLUGIN_VERSION"
|
||
|
||
|
||
find_backend() {
|
||
if [[ -x "$BACKEND_EXTERNAL" ]]; then
|
||
printf '%s\n' "$BACKEND_EXTERNAL"
|
||
return 0
|
||
fi
|
||
if [[ -x "$BACKEND_BUNDLED" ]]; then
|
||
printf '%s\n' "$BACKEND_BUNDLED"
|
||
return 0
|
||
fi
|
||
return 1
|
||
}
|
||
|
||
backend_status() {
|
||
local backend
|
||
backend="$(find_backend 2>/dev/null)" || return 1
|
||
"$backend" status
|
||
}
|
||
|
||
plugin_update_check() {
|
||
local backend output state
|
||
backend="$(find_backend 2>/dev/null)" || {
|
||
notify_error "Das Omarchy-Citizen-Update-Backend wurde nicht gefunden. Installiere das Plugin erneut."
|
||
return 1
|
||
}
|
||
output="$($backend check 2>&1)" || true
|
||
printf '%s\n' "$output" >> "$LOG_FILE"
|
||
state="$(printf '%s\n' "$output" | sed -n 's/^update=//p' | head -n1)"
|
||
case "$state" in
|
||
available) notify "Omarchy Citizen" "Ein Plugin-Update ist verfügbar." ;;
|
||
current) notify "Omarchy Citizen" "Omarchy Citizen ist aktuell." ;;
|
||
unavailable) notify "Omarchy Citizen" "Diese Installation ist noch nicht Git-verwaltet. Automatische Plugin-Updates werden nach der Git-Installation verfügbar." ;;
|
||
blocked-dirty) notify_error "Plugin-Update blockiert: Im Plugin-Verzeichnis gibt es lokale Änderungen." ;;
|
||
blocked-remote-changed) notify_error "Plugin-Update aus Sicherheitsgründen blockiert: Das Git-Remote hat sich geändert." ;;
|
||
*) notify_error "Plugin-Update konnte nicht eindeutig geprüft werden. Das Support-Paket enthält Details." ;;
|
||
esac
|
||
}
|
||
|
||
plugin_update_now() {
|
||
local backend
|
||
backend="$(find_backend 2>/dev/null)" || {
|
||
notify_error "Das Update-Backend wurde nicht gefunden."
|
||
return 1
|
||
}
|
||
if "$backend" update >>"$LOG_FILE" 2>&1; then
|
||
notify "Omarchy Citizen" "Plugin-Update abgeschlossen."
|
||
else
|
||
notify_error "Plugin-Update fehlgeschlagen oder nicht verfügbar. Erstelle bei Bedarf ein Support-Paket."
|
||
fi
|
||
}
|
||
|
||
plugin_auto_enable() {
|
||
local backend
|
||
backend="$(find_backend 2>/dev/null)" || { notify_error "Update-Backend fehlt."; return 1; }
|
||
if "$backend" auto enable >>"$LOG_FILE" 2>&1; then
|
||
notify "Omarchy Citizen" "Automatische Plugin-Updates sind aktiviert."
|
||
else
|
||
notify_error "Auto-Updates konnten nicht aktiviert werden. Bei ZIP-Installationen ist zuerst eine Git-verwaltete Plugin-Installation nötig."
|
||
fi
|
||
}
|
||
|
||
plugin_auto_disable() {
|
||
local backend
|
||
backend="$(find_backend 2>/dev/null)" || { notify_error "Update-Backend fehlt."; return 1; }
|
||
"$backend" auto disable >>"$LOG_FILE" 2>&1 || true
|
||
notify "Omarchy Citizen" "Automatische Plugin-Updates sind deaktiviert."
|
||
}
|
||
|
||
open_updater_log() {
|
||
local log="$STATE_DIR/updater.log"
|
||
if [[ ! -f "$log" ]]; then
|
||
notify_error "Noch kein Updater-Log vorhanden."
|
||
return 1
|
||
fi
|
||
xdg-open "$log" >/dev/null 2>&1 &
|
||
}
|
||
|
||
notify() {
|
||
local title="$1"
|
||
local message="$2"
|
||
if command -v omarchy-notification-send >/dev/null 2>&1; then
|
||
omarchy-notification-send "$title" "$message" >/dev/null 2>&1 || true
|
||
elif command -v notify-send >/dev/null 2>&1; then
|
||
notify-send "$title" "$message" >/dev/null 2>&1 || true
|
||
fi
|
||
}
|
||
|
||
notify_error() {
|
||
local message="$1"
|
||
log_line "error=$message"
|
||
if command -v zenity >/dev/null 2>&1; then
|
||
zenity --error --width=500 --title="Omarchy Citizen" --text="$message" >/dev/null 2>&1 &
|
||
else
|
||
notify "Omarchy Citizen" "$message"
|
||
printf 'Omarchy Citizen: %s\n' "$message" >&2
|
||
fi
|
||
}
|
||
|
||
find_helper() {
|
||
local candidate
|
||
|
||
if command -v lug-helper >/dev/null 2>&1; then
|
||
command -v lug-helper
|
||
return 0
|
||
fi
|
||
|
||
if command -v lug-helper.sh >/dev/null 2>&1; then
|
||
command -v lug-helper.sh
|
||
return 0
|
||
fi
|
||
|
||
for candidate in \
|
||
"$HOME/.local/bin/lug-helper" \
|
||
"$HOME/.local/bin/lug-helper.sh" \
|
||
"$DATA_DIR/lug-helper/lug-helper.sh" \
|
||
"$HOME/lug-helper/lug-helper.sh"
|
||
do
|
||
if [[ -f "$candidate" ]]; then
|
||
printf '%s\n' "$candidate"
|
||
return 0
|
||
fi
|
||
done
|
||
|
||
shopt -s nullglob
|
||
for candidate in \
|
||
"$HOME/Applications"/*LUG*Helper*.AppImage \
|
||
"$HOME/Applications"/lug-helper*.AppImage \
|
||
"$HOME/Downloads"/*LUG*Helper*.AppImage \
|
||
"$HOME/Downloads"/lug-helper*.AppImage
|
||
do
|
||
if [[ -x "$candidate" ]]; then
|
||
printf '%s\n' "$candidate"
|
||
shopt -u nullglob
|
||
return 0
|
||
fi
|
||
done
|
||
shopt -u nullglob
|
||
|
||
return 1
|
||
}
|
||
|
||
run_helper_sync() {
|
||
local helper
|
||
helper="$(find_helper)" || {
|
||
notify_error "Der Star Citizen LUG Helper wurde nicht gefunden."
|
||
return 1
|
||
}
|
||
|
||
log_line "lug-helper sync args=$*"
|
||
if [[ "$helper" == *.sh ]]; then
|
||
bash "$helper" "$@" >>"$LOG_FILE" 2>&1
|
||
else
|
||
"$helper" "$@" >>"$LOG_FILE" 2>&1
|
||
fi
|
||
}
|
||
|
||
run_helper_gui() {
|
||
local helper
|
||
helper="$(find_helper)" || {
|
||
notify_error "Der Star Citizen LUG Helper wurde nicht gefunden.
|
||
|
||
Wähle im SC-Panel „Einrichten“ – Omarchy Citizen installiert die benötigten Komponenten."
|
||
return 1
|
||
}
|
||
|
||
log_line "lug-helper gui args=$*"
|
||
if [[ "$helper" == *.sh ]]; then
|
||
nohup bash "$helper" "$@" >>"$LOG_FILE" 2>&1 &
|
||
else
|
||
nohup "$helper" "$@" >>"$LOG_FILE" 2>&1 &
|
||
fi
|
||
}
|
||
|
||
read_prefix() {
|
||
[[ -f "$WINE_CONF" ]] || return 1
|
||
local prefix
|
||
IFS= read -r prefix < "$WINE_CONF"
|
||
[[ -n "$prefix" && -d "$prefix" ]] || return 1
|
||
printf '%s\n' "$prefix"
|
||
}
|
||
|
||
read_game_dir() {
|
||
[[ -f "$GAME_CONF" ]] || return 1
|
||
local game_dir
|
||
IFS= read -r game_dir < "$GAME_CONF"
|
||
[[ -n "$game_dir" ]] || return 1
|
||
printf '%s\n' "$game_dir"
|
||
}
|
||
|
||
package_installed() {
|
||
pacman -Qq "$1" >/dev/null 2>&1
|
||
}
|
||
|
||
installed_lug_version() {
|
||
pacman -Q lug-helper 2>/dev/null | awk '{print $2}'
|
||
}
|
||
|
||
read_update_cache() {
|
||
local key="$1"
|
||
[[ -f "$UPDATE_CACHE" ]] || return 1
|
||
sed -n "s/^${key}=//p" "$UPDATE_CACHE" | head -n 1
|
||
}
|
||
|
||
write_update_cache() {
|
||
local state="$1"
|
||
local version="${2:-}"
|
||
mkdir -p "$CACHE_DIR"
|
||
{
|
||
printf 'state=%s\n' "$state"
|
||
printf 'version=%s\n' "$version"
|
||
printf 'checked_at=%s\n' "$(date +%s)"
|
||
} > "$UPDATE_CACHE"
|
||
}
|
||
|
||
check_update() {
|
||
local installed output rc line target=""
|
||
|
||
if ! package_installed lug-helper; then
|
||
write_update_cache "not-installed" ""
|
||
printf 'not-installed\n'
|
||
return 0
|
||
fi
|
||
|
||
installed="$(installed_lug_version)"
|
||
|
||
if ! command -v yay >/dev/null 2>&1; then
|
||
write_update_cache "unknown" ""
|
||
printf 'unknown\n'
|
||
return 1
|
||
fi
|
||
|
||
set +e
|
||
output="$(timeout 25s yay -Qua 2>/dev/null)"
|
||
rc=$?
|
||
set -e
|
||
|
||
if (( rc != 0 )); then
|
||
write_update_cache "unknown" ""
|
||
printf 'unknown\n'
|
||
return 1
|
||
fi
|
||
|
||
line="$(printf '%s\n' "$output" | awk '$1=="lug-helper"{print; exit}')"
|
||
if [[ -n "$line" ]]; then
|
||
target="$(printf '%s\n' "$line" | awk '{print $NF}')"
|
||
write_update_cache "available" "$target"
|
||
printf 'available=%s\n' "$target"
|
||
else
|
||
write_update_cache "current" "$installed"
|
||
printf 'current=%s\n' "$installed"
|
||
fi
|
||
}
|
||
|
||
status() {
|
||
local helper="" version="" prefix="" game_dir="" dep missing_deps=""
|
||
local helper_state="missing" helper_managed="missing" deps_state="ready"
|
||
local prefix_state="missing" launcher_state="missing" game_state="missing"
|
||
local update_state="unknown" update_version="" health="setup"
|
||
|
||
for dep in "${GUI_PACKAGES[@]}"; do
|
||
if ! package_installed "$dep"; then
|
||
deps_state="missing"
|
||
if [[ -n "$missing_deps" ]]; then missing_deps+=","; fi
|
||
missing_deps+="$dep"
|
||
fi
|
||
done
|
||
|
||
if package_installed lug-helper; then
|
||
helper_state="ready"
|
||
helper_managed="aur"
|
||
version="$(installed_lug_version)"
|
||
elif helper="$(find_helper 2>/dev/null)"; then
|
||
helper_state="ready"
|
||
helper_managed="external"
|
||
if [[ "$helper" == *.sh ]]; then
|
||
version="$(bash "$helper" --version 2>/dev/null | head -n 1 || true)"
|
||
else
|
||
version="$("$helper" --version 2>/dev/null | head -n 1 || true)"
|
||
fi
|
||
version="${version//$'\n'/ }"
|
||
version="${version//$'\r'/ }"
|
||
fi
|
||
|
||
update_state="$(read_update_cache state 2>/dev/null || printf 'unknown')"
|
||
update_version="$(read_update_cache version 2>/dev/null || true)"
|
||
|
||
if prefix="$(read_prefix 2>/dev/null)"; then
|
||
prefix_state="ready"
|
||
if [[ -f "$prefix/sc-launch.sh" ]]; then
|
||
launcher_state="ready"
|
||
fi
|
||
fi
|
||
|
||
if game_dir="$(read_game_dir 2>/dev/null)"; then
|
||
if [[ -f "$game_dir/LIVE/Bin64/StarCitizen.exe" ]]; then
|
||
game_state="ready"
|
||
elif [[ -d "$game_dir" ]]; then
|
||
game_state="partial"
|
||
fi
|
||
fi
|
||
|
||
if [[ "$deps_state" != "ready" || "$helper_state" != "ready" ]]; then
|
||
health="setup"
|
||
elif [[ "$prefix_state" != "ready" ]]; then
|
||
health="install"
|
||
elif [[ "$launcher_state" != "ready" ]]; then
|
||
health="repair"
|
||
elif [[ "$game_state" != "ready" ]]; then
|
||
health="install-game"
|
||
else
|
||
health="ready"
|
||
fi
|
||
|
||
printf 'plugin_version=%s\n' "$PLUGIN_VERSION"
|
||
printf 'health=%s\n' "$health"
|
||
printf 'deps=%s\n' "$deps_state"
|
||
printf 'deps_missing=%s\n' "$missing_deps"
|
||
printf 'helper=%s\n' "$helper_state"
|
||
printf 'helper_managed=%s\n' "$helper_managed"
|
||
printf 'helper_version=%s\n' "$version"
|
||
printf 'update=%s\n' "$update_state"
|
||
printf 'update_version=%s\n' "$update_version"
|
||
printf 'prefix=%s\n' "$prefix_state"
|
||
printf 'launcher=%s\n' "$launcher_state"
|
||
printf 'game=%s\n' "$game_state"
|
||
|
||
local backend_output="" backend_state="missing"
|
||
if backend_output="$(backend_status 2>/dev/null)"; then
|
||
backend_state="ready"
|
||
fi
|
||
printf 'backend=%s\n' "$backend_state"
|
||
printf 'backend_version=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^backend_version=//p' | head -n1)"
|
||
printf 'plugin_managed=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^managed=//p' | head -n1)"
|
||
printf 'plugin_auto=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^auto_apply=//p' | head -n1)"
|
||
printf 'plugin_update=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^update=//p' | head -n1)"
|
||
printf 'plugin_local_commit=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^local_commit=//p' | head -n1)"
|
||
printf 'plugin_remote_commit=%s\n' "$(printf '%s\n' "$backend_output" | sed -n 's/^remote_commit=//p' | head -n1)"
|
||
}
|
||
|
||
probe_detached_start() {
|
||
local label="$1"
|
||
shift
|
||
|
||
"$@" >>"$LOG_FILE" 2>&1 &
|
||
local pid=$!
|
||
|
||
# Give immediate launcher errors a chance to surface. A successful terminal
|
||
# launcher may either stay alive or exit 0 after handing the terminal off.
|
||
sleep 0.35
|
||
|
||
if ! kill -0 "$pid" 2>/dev/null; then
|
||
local rc=0
|
||
wait "$pid" || rc=$?
|
||
if (( rc != 0 )); then
|
||
log_line "$label failed rc=$rc"
|
||
return "$rc"
|
||
fi
|
||
else
|
||
disown "$pid" 2>/dev/null || true
|
||
fi
|
||
|
||
log_line "$label accepted"
|
||
return 0
|
||
}
|
||
|
||
launch_terminal_action() {
|
||
local action="$1"
|
||
local cmd
|
||
|
||
printf -v cmd 'bash %q %q' "$SELF" "$action"
|
||
log_line "launch-terminal action=$action cmd=$cmd"
|
||
|
||
if command -v omarchy-launch-floating-terminal-with-presentation >/dev/null 2>&1; then
|
||
if probe_detached_start "omarchy-floating-terminal" \
|
||
omarchy-launch-floating-terminal-with-presentation bash "$SELF" "$action"; then
|
||
return 0
|
||
fi
|
||
log_line "primary floating terminal launcher failed; trying direct terminal fallback"
|
||
fi
|
||
|
||
if command -v uwsm-app >/dev/null 2>&1 && command -v xdg-terminal-exec >/dev/null 2>&1; then
|
||
if probe_detached_start "direct-omarchy-terminal" \
|
||
setsid uwsm-app -- xdg-terminal-exec \
|
||
--app-id=org.omarchy.terminal \
|
||
--title="Omarchy Citizen" \
|
||
-e bash -c "$cmd"; then
|
||
return 0
|
||
fi
|
||
elif command -v xdg-terminal-exec >/dev/null 2>&1; then
|
||
if probe_detached_start "xdg-terminal" \
|
||
xdg-terminal-exec -e bash "$SELF" "$action"; then
|
||
return 0
|
||
fi
|
||
fi
|
||
|
||
notify_error "Das Setup-Terminal konnte nicht geöffnet werden.
|
||
|
||
Bitte erstelle im SC-Panel ein Support-Paket. Darin ist jetzt auch der fehlgeschlagene Startversuch protokolliert."
|
||
return 1
|
||
}
|
||
|
||
guided_setup_interactive() {
|
||
log_line "guided-setup begin"
|
||
|
||
if ! find_helper >/dev/null 2>&1; then
|
||
launch_terminal_action install-stack-terminal
|
||
return 0
|
||
fi
|
||
|
||
run_helper_sync --preflight-check || true
|
||
|
||
if ! read_prefix >/dev/null 2>&1; then
|
||
run_helper_sync --install || true
|
||
elif ! prefix="$(read_prefix 2>/dev/null)" || [[ ! -f "$prefix/sc-launch.sh" ]]; then
|
||
run_helper_sync --update-launch-script || true
|
||
fi
|
||
|
||
prefix="$(read_prefix 2>/dev/null || true)"
|
||
if [[ -n "$prefix" && -f "$prefix/sc-launch.sh" ]]; then
|
||
game_dir="$(read_game_dir 2>/dev/null || true)"
|
||
if [[ -z "$game_dir" || ! -f "$game_dir/LIVE/Bin64/StarCitizen.exe" ]]; then
|
||
log_line "guided-setup opening RSI Launcher for game installation"
|
||
nohup bash "$prefix/sc-launch.sh" >>"$LOG_FILE" 2>&1 &
|
||
fi
|
||
fi
|
||
|
||
notify "Omarchy Citizen" "Einrichtung abgeschlossen. Falls Star Citizen noch fehlt, ist der RSI Launcher für die Installation geöffnet."
|
||
log_line "guided-setup end"
|
||
}
|
||
|
||
guided_setup() {
|
||
if ! package_installed zenity || ! find_helper >/dev/null 2>&1; then
|
||
launch_terminal_action install-stack-terminal
|
||
return
|
||
fi
|
||
nohup bash "$SELF" guided-setup-interactive >>"$LOG_FILE" 2>&1 &
|
||
}
|
||
|
||
install_stack_terminal() {
|
||
set -e
|
||
exec > >(tee -a "$LOG_FILE") 2>&1
|
||
|
||
echo
|
||
echo "=================================================="
|
||
echo " Omarchy Citizen – Plug & Play Setup"
|
||
echo "=================================================="
|
||
echo
|
||
echo "Omarchy Citizen richtet die Linux-Gaming-Basis ein."
|
||
echo "Du musst keine Paketnamen oder Linux-Befehle kennen."
|
||
echo
|
||
echo "Installiert/überprüft werden:"
|
||
echo " - zenity / polkit"
|
||
echo " - cabextract / unzip"
|
||
echo " - Star Citizen LUG Helper aus dem AUR"
|
||
echo
|
||
|
||
omarchy pkg add zenity polkit cabextract unzip
|
||
|
||
if package_installed lug-helper; then
|
||
echo "LUG Helper ist bereits installiert."
|
||
else
|
||
echo "Installiere LUG Helper..."
|
||
omarchy pkg aur add lug-helper
|
||
fi
|
||
|
||
rm -f "$UPDATE_CACHE"
|
||
|
||
echo
|
||
echo "Systempakete sind bereit."
|
||
echo "Als Nächstes startet der grafische Star-Citizen-Assistent."
|
||
echo
|
||
|
||
run_helper_sync --preflight-check || true
|
||
|
||
if ! read_prefix >/dev/null 2>&1; then
|
||
run_helper_sync --install || true
|
||
fi
|
||
|
||
echo
|
||
echo "Plug-&-Play-Setup beendet."
|
||
echo "Du kannst dieses Fenster schließen und ✦SC öffnen."
|
||
notify "Omarchy Citizen" "Grundsetup abgeschlossen. Öffne ✦SC und starte Star Citizen."
|
||
log_line "install-stack complete"
|
||
}
|
||
|
||
update_helper_terminal() {
|
||
set -e
|
||
exec > >(tee -a "$LOG_FILE") 2>&1
|
||
|
||
if ! package_installed lug-helper; then
|
||
echo "LUG Helper ist noch nicht als AUR-Paket installiert."
|
||
echo "Starte bitte zuerst das normale Omarchy-Citizen-Setup."
|
||
exit 1
|
||
fi
|
||
|
||
echo "Aktualisiere den LUG Helper..."
|
||
omarchy pkg aur add lug-helper
|
||
rm -f "$UPDATE_CACHE"
|
||
echo "LUG Helper ist aktuell."
|
||
installed_lug_version
|
||
log_line "lug-helper update complete"
|
||
}
|
||
|
||
system_update_terminal() {
|
||
set -e
|
||
log_line "omarchy update begin"
|
||
omarchy update
|
||
rm -f "$UPDATE_CACHE"
|
||
log_line "omarchy update end rc=0"
|
||
}
|
||
|
||
launch_game() {
|
||
local prefix script
|
||
prefix="$(read_prefix 2>/dev/null)" || {
|
||
guided_setup
|
||
return
|
||
}
|
||
|
||
script="$prefix/sc-launch.sh"
|
||
if [[ ! -f "$script" ]]; then
|
||
log_line "launch script missing; opening repair"
|
||
run_helper_gui --update-launch-script
|
||
return
|
||
fi
|
||
|
||
log_line "launch game via sc-launch.sh"
|
||
nohup bash "$script" >>"$LOG_FILE" 2>&1 &
|
||
}
|
||
|
||
primary_action() {
|
||
local st health
|
||
st="$("$SELF" status)"
|
||
health="$(printf '%s\n' "$st" | sed -n 's/^health=//p' | head -n1)"
|
||
|
||
case "$health" in
|
||
ready)
|
||
launch_game
|
||
;;
|
||
setup)
|
||
launch_terminal_action install-stack-terminal
|
||
;;
|
||
install)
|
||
guided_setup
|
||
;;
|
||
install-game)
|
||
launch_game
|
||
;;
|
||
repair)
|
||
run_helper_gui --update-launch-script
|
||
;;
|
||
*)
|
||
guided_setup
|
||
;;
|
||
esac
|
||
}
|
||
|
||
repair_assistant_interactive() {
|
||
local st health choice prefix
|
||
|
||
st="$("$SELF" status)"
|
||
health="$(printf '%s\n' "$st" | sed -n 's/^health=//p' | head -n1)"
|
||
log_line "repair health=$health"
|
||
|
||
case "$health" in
|
||
setup)
|
||
launch_terminal_action install-stack-terminal
|
||
return
|
||
;;
|
||
install)
|
||
guided_setup_interactive
|
||
return
|
||
;;
|
||
repair)
|
||
run_helper_sync --update-launch-script || true
|
||
notify "Omarchy Citizen" "Start-Script wurde geprüft/repariert. Versuche den Start erneut."
|
||
return
|
||
;;
|
||
esac
|
||
|
||
if ! command -v zenity >/dev/null 2>&1; then
|
||
run_helper_gui --preflight-check
|
||
return
|
||
fi
|
||
|
||
choice="$(zenity --list \
|
||
--width=610 --height=420 \
|
||
--title="Omarchy Citizen – Problem beheben" \
|
||
--text="Was funktioniert nicht? Du brauchst keine Linux-Diagnose zu kennen." \
|
||
--column="Problem" \
|
||
"Automatisch prüfen (empfohlen)" \
|
||
"RSI Launcher startet nicht / ist kaputt" \
|
||
"Star Citizen startet nicht" \
|
||
"Grafik / Performance / Abstürze" \
|
||
"NGL macht Probleme" \
|
||
"Problem ist unklar – Support-Paket erstellen" \
|
||
2>/dev/null)" || return 0
|
||
|
||
log_line "repair choice=$choice"
|
||
|
||
case "$choice" in
|
||
"Automatisch prüfen (empfohlen)")
|
||
run_helper_sync --preflight-check || true
|
||
run_helper_sync --update-launch-script || true
|
||
notify "Omarchy Citizen" "Automatische Basisreparatur abgeschlossen. Bitte erneut starten."
|
||
;;
|
||
"RSI Launcher startet nicht / ist kaputt")
|
||
run_helper_sync --update-rsi-launcher || true
|
||
run_helper_sync --update-launch-script || true
|
||
notify "Omarchy Citizen" "RSI Launcher und Start-Script wurden repariert."
|
||
;;
|
||
"Star Citizen startet nicht")
|
||
run_helper_sync --preflight-check || true
|
||
run_helper_sync --update-launch-script || true
|
||
notify "Omarchy Citizen" "Startumgebung wurde geprüft. Falls es weiter nicht startet, erstelle bitte das Support-Paket."
|
||
;;
|
||
"Grafik / Performance / Abstürze")
|
||
run_helper_sync --preflight-check || true
|
||
run_helper_gui --manage-runners
|
||
;;
|
||
"NGL macht Probleme")
|
||
if zenity --question --width=540 \
|
||
--title="NGL Problem" \
|
||
--ok-label="Vanilla RSI Launcher reparieren" \
|
||
--cancel-label="Abbrechen" \
|
||
--text="Omarchy Citizen kann den offiziellen RSI Launcher über den LUG Helper neu installieren. NGL kann danach optional erneut installiert werden." \
|
||
2>/dev/null; then
|
||
run_helper_sync --update-rsi-launcher || true
|
||
run_helper_sync --update-launch-script || true
|
||
fi
|
||
;;
|
||
"Problem ist unklar – Support-Paket erstellen")
|
||
"$SELF" support-build
|
||
;;
|
||
esac
|
||
}
|
||
|
||
repair_assistant() {
|
||
nohup bash "$SELF" repair-interactive >>"$LOG_FILE" 2>&1 &
|
||
}
|
||
|
||
sanitize_to() {
|
||
local source="$1"
|
||
local target="$2"
|
||
|
||
if [[ ! -f "$source" ]]; then
|
||
return 0
|
||
fi
|
||
|
||
if command -v python3 >/dev/null 2>&1 && [[ -f "$SANITIZER" ]]; then
|
||
python3 "$SANITIZER" < "$source" > "$target"
|
||
else
|
||
sed \
|
||
-e "s#${HOME//\#/\\#}#~#g" \
|
||
-e 's/[A-Za-z0-9._%+-]\+@[A-Za-z0-9.-]\+\.[A-Za-z]\{2,\}/<email>/g' \
|
||
"$source" > "$target"
|
||
fi
|
||
}
|
||
|
||
capture_sanitized() {
|
||
local target="$1"
|
||
shift
|
||
local tmp="$CACHE_DIR/capture-$$-$RANDOM.txt"
|
||
{
|
||
"$@"
|
||
} >"$tmp" 2>&1 || true
|
||
sanitize_to "$tmp" "$target"
|
||
rm -f "$tmp"
|
||
}
|
||
|
||
support_build() {
|
||
local stamp support_id work downloads archive prefix="" game_dir=""
|
||
stamp="$(date '+%Y%m%d-%H%M%S')"
|
||
support_id="OC-${stamp}-$(printf '%s-%s-%s' "$stamp" "$$" "$RANDOM" | sha256sum | cut -c1-6)"
|
||
work="$CACHE_DIR/support-$support_id"
|
||
|
||
if command -v xdg-user-dir >/dev/null 2>&1; then
|
||
downloads="$(xdg-user-dir DOWNLOAD 2>/dev/null || true)"
|
||
else
|
||
downloads=""
|
||
fi
|
||
[[ -n "$downloads" && -d "$downloads" ]] || downloads="$HOME/Downloads"
|
||
mkdir -p "$downloads" "$work"
|
||
|
||
log_line "support build id=$support_id"
|
||
|
||
cat > "$work/README_SUPPORT.txt" <<EOF
|
||
Omarchy Citizen Support-Paket
|
||
Support-ID: $support_id
|
||
Plugin-Version: $PLUGIN_VERSION
|
||
Erstellt: $(date '+%Y-%m-%d %H:%M:%S %z')
|
||
|
||
Dieses Paket wurde automatisch erstellt, um Support ohne Linux-Kenntnisse zu ermöglichen.
|
||
|
||
Datenschutz:
|
||
- Home-Pfad, Benutzername und Hostname werden beim Export maskiert.
|
||
- E-Mail-Adressen, IP-/MAC-Adressen und typische Token-/Session-Werte werden maskiert.
|
||
- Es werden keine Browserdaten, SSH-Schlüssel oder Passwortdateien gesammelt.
|
||
- Star-Citizen-Game.log/EAC-Vollprotokolle sind im Standardpaket NICHT enthalten.
|
||
- Die Maskierung ist eine Best-Effort-Funktion. Nutzer können das Archiv vor dem Senden prüfen.
|
||
|
||
Bitte bei Support-Anfragen die Support-ID mit angeben.
|
||
EOF
|
||
|
||
{
|
||
echo "support_id=$support_id"
|
||
echo "plugin_id=$PLUGIN_ID"
|
||
echo "plugin_version=$PLUGIN_VERSION"
|
||
echo "created=$(date --iso-8601=seconds)"
|
||
"$SELF" status
|
||
} > "$work/citizen-status.txt"
|
||
|
||
if backend="$(find_backend 2>/dev/null)"; then
|
||
capture_sanitized "$work/updater-status.json" "$backend" status --json
|
||
fi
|
||
if [[ -f "$STATE_DIR/updater.log" ]]; then
|
||
tail -n 1200 "$STATE_DIR/updater.log" > "$CACHE_DIR/updater-log-$$.txt"
|
||
sanitize_to "$CACHE_DIR/updater-log-$$.txt" "$work/updater.log"
|
||
rm -f "$CACHE_DIR/updater-log-$$.txt"
|
||
fi
|
||
|
||
capture_sanitized "$work/omarchy-debug.txt" omarchy debug --no-sudo --print
|
||
|
||
{
|
||
echo "=== Kernel / Desktop ==="
|
||
uname -rmo 2>/dev/null || true
|
||
printf 'XDG_SESSION_TYPE=%s\n' "${XDG_SESSION_TYPE:-unknown}"
|
||
printf 'XDG_CURRENT_DESKTOP=%s\n' "${XDG_CURRENT_DESKTOP:-unknown}"
|
||
printf 'WAYLAND_DISPLAY=%s\n' "${WAYLAND_DISPLAY:-unknown}"
|
||
echo
|
||
echo "=== Memory ==="
|
||
free -h 2>/dev/null || true
|
||
echo
|
||
echo "=== Filesystems ==="
|
||
df -hT / "$HOME" 2>/dev/null || true
|
||
echo
|
||
echo "=== Block devices ==="
|
||
lsblk -o NAME,SIZE,FSTYPE,FSAVAIL,MOUNTPOINTS 2>/dev/null || true
|
||
echo
|
||
echo "=== GPU ==="
|
||
lspci -nnk 2>/dev/null | grep -A4 -Ei 'VGA|3D|Display' || true
|
||
echo
|
||
echo "=== Vulkan ==="
|
||
if command -v vulkaninfo >/dev/null 2>&1; then
|
||
vulkaninfo --summary 2>/dev/null || true
|
||
else
|
||
echo "vulkaninfo not installed"
|
||
fi
|
||
echo
|
||
echo "=== Star Citizen kernel limits ==="
|
||
sysctl vm.max_map_count 2>/dev/null || true
|
||
printf 'hard_open_files=%s\n' "$(ulimit -Hn 2>/dev/null || true)"
|
||
} > "$CACHE_DIR/system-$$.txt"
|
||
sanitize_to "$CACHE_DIR/system-$$.txt" "$work/system.txt"
|
||
rm -f "$CACHE_DIR/system-$$.txt"
|
||
|
||
{
|
||
echo "=== Relevant packages ==="
|
||
pacman -Q omarchy omarchy-dev lug-helper zenity polkit cabextract unzip 2>/dev/null || true
|
||
echo
|
||
echo "=== AUR helper ==="
|
||
yay --version 2>/dev/null | head -n 4 || true
|
||
echo
|
||
echo "=== Commands ==="
|
||
for cmd in omarchy lug-helper yay zenity wine winetricks gamescope gamemoderun; do
|
||
if command -v "$cmd" >/dev/null 2>&1; then
|
||
printf '%s=present\n' "$cmd"
|
||
else
|
||
printf '%s=missing\n' "$cmd"
|
||
fi
|
||
done
|
||
} > "$work/packages.txt"
|
||
|
||
if command -v omarchy >/dev/null 2>&1; then
|
||
capture_sanitized "$work/plugin-validation.txt" omarchy plugin validate "$PLUGIN_DIR"
|
||
fi
|
||
|
||
if [[ -f "$LOG_FILE" ]]; then
|
||
tail -n 1500 "$LOG_FILE" > "$CACHE_DIR/plugin-log-$$.txt"
|
||
sanitize_to "$CACHE_DIR/plugin-log-$$.txt" "$work/omarchy-citizen.log"
|
||
rm -f "$CACHE_DIR/plugin-log-$$.txt"
|
||
fi
|
||
|
||
if [[ -f /tmp/omarchy-update.log ]]; then
|
||
tail -n 500 /tmp/omarchy-update.log > "$CACHE_DIR/update-log-$$.txt"
|
||
sanitize_to "$CACHE_DIR/update-log-$$.txt" "$work/omarchy-update-tail.log"
|
||
rm -f "$CACHE_DIR/update-log-$$.txt"
|
||
fi
|
||
|
||
prefix="$(read_prefix 2>/dev/null || true)"
|
||
game_dir="$(read_game_dir 2>/dev/null || true)"
|
||
|
||
{
|
||
printf 'wine_prefix=%s\n' "${prefix:-not-configured}"
|
||
printf 'game_dir=%s\n' "${game_dir:-not-configured}"
|
||
printf 'launch_script=%s\n' "$([[ -n "$prefix" && -f "$prefix/sc-launch.sh" ]] && echo present || echo missing)"
|
||
printf 'game_binary=%s\n' "$([[ -n "$game_dir" && -f "$game_dir/LIVE/Bin64/StarCitizen.exe" ]] && echo present || echo missing)"
|
||
} > "$CACHE_DIR/paths-$$.txt"
|
||
sanitize_to "$CACHE_DIR/paths-$$.txt" "$work/star-citizen-path-status.txt"
|
||
rm -f "$CACHE_DIR/paths-$$.txt"
|
||
|
||
if [[ -n "$prefix" && -f "$prefix/sc-launch.log" ]]; then
|
||
tail -n 600 "$prefix/sc-launch.log" > "$CACHE_DIR/sc-launch-$$.txt"
|
||
sanitize_to "$CACHE_DIR/sc-launch-$$.txt" "$work/sc-launch-tail.log"
|
||
rm -f "$CACHE_DIR/sc-launch-$$.txt"
|
||
fi
|
||
|
||
if [[ -n "$prefix" && -f "$prefix/sc-launch.sh" ]]; then
|
||
head -n 350 "$prefix/sc-launch.sh" > "$CACHE_DIR/sc-script-$$.txt"
|
||
sanitize_to "$CACHE_DIR/sc-script-$$.txt" "$work/sc-launch-script-sanitized.txt"
|
||
rm -f "$CACHE_DIR/sc-script-$$.txt"
|
||
fi
|
||
|
||
archive="$downloads/Omarchy-Citizen-Support-$support_id.tar.gz"
|
||
tar -C "$work" -czf "$archive" .
|
||
rm -rf "$work"
|
||
|
||
log_line "support archive=$archive"
|
||
|
||
if command -v wl-copy >/dev/null 2>&1; then
|
||
printf '%s' "$archive" | wl-copy
|
||
fi
|
||
|
||
if command -v zenity >/dev/null 2>&1; then
|
||
zenity --info --width=580 \
|
||
--title="Support-Paket erstellt" \
|
||
--text="Support-ID:
|
||
<b>$support_id</b>
|
||
|
||
Das bereinigte Support-Paket wurde in deinem Downloads-Ordner erstellt:
|
||
|
||
$(basename "$archive")
|
||
|
||
Der Dateipfad wurde – falls die Zwischenablage verfügbar ist – kopiert.
|
||
|
||
Schicke dieses Archiv zusammen mit der Support-ID an den Plugin-Support." \
|
||
>/dev/null 2>&1 || true
|
||
else
|
||
notify "Omarchy Citizen" "Support-Paket erstellt: $(basename "$archive")"
|
||
fi
|
||
|
||
if command -v xdg-open >/dev/null 2>&1; then
|
||
xdg-open "$downloads" >/dev/null 2>&1 &
|
||
fi
|
||
|
||
printf '%s\n' "$archive"
|
||
}
|
||
|
||
support_start() {
|
||
nohup bash "$SELF" support-build >>"$LOG_FILE" 2>&1 &
|
||
}
|
||
|
||
open_debug_log() {
|
||
if [[ ! -f "$LOG_FILE" ]]; then
|
||
notify_error "Noch kein Debug-Log vorhanden."
|
||
return 1
|
||
fi
|
||
xdg-open "$LOG_FILE" >/dev/null 2>&1 &
|
||
}
|
||
|
||
open_log() {
|
||
local prefix log
|
||
prefix="$(read_prefix 2>/dev/null)" || {
|
||
notify_error "Noch kein Star-Citizen-Wine-Prefix gefunden."
|
||
return 1
|
||
}
|
||
|
||
log="$prefix/sc-launch.log"
|
||
if [[ ! -f "$log" ]]; then
|
||
notify_error "Noch kein Start-Log gefunden.
|
||
|
||
Starte den RSI Launcher mindestens einmal."
|
||
return 1
|
||
fi
|
||
|
||
xdg-open "$log" >/dev/null 2>&1 &
|
||
}
|
||
|
||
open_wiki() {
|
||
xdg-open "https://wiki.starcitizen-lug.org" >/dev/null 2>&1 &
|
||
}
|
||
|
||
open_ngl_page() {
|
||
xdg-open "https://www.nglproject.com/de#downloads" >/dev/null 2>&1 &
|
||
}
|
||
|
||
ngl_info() {
|
||
local msg
|
||
msg="NGL ist ein optionaler Community-Mod für den Windows-RSI-Launcher.
|
||
|
||
Omarchy Citizen behandelt NGL als EXPERIMENTELL und installiert es nie ohne deine Auswahl und Bestätigung.
|
||
|
||
Der Mod läuft im selben Wine-Prefix wie dein RSI Launcher."
|
||
|
||
if command -v zenity >/dev/null 2>&1; then
|
||
zenity --info --width=520 --title="Omarchy Citizen – NGL" --text="$msg" >/dev/null 2>&1 &
|
||
else
|
||
notify "Omarchy Citizen – NGL" "$msg"
|
||
fi
|
||
}
|
||
|
||
ngl_install_interactive() {
|
||
local prefix script selected workdir exe
|
||
|
||
if ! command -v zenity >/dev/null 2>&1; then
|
||
notify_error "Die NGL-Installation benötigt die grafische Dateiauswahl. Bitte zuerst das normale Setup ausführen."
|
||
return 1
|
||
fi
|
||
|
||
prefix="$(read_prefix 2>/dev/null)" || {
|
||
notify_error "Star Citizen muss zuerst eingerichtet werden."
|
||
return 1
|
||
}
|
||
|
||
script="$prefix/sc-launch.sh"
|
||
[[ -f "$script" ]] || {
|
||
notify_error "Das Star-Citizen-Start-Script fehlt. Nutze zuerst „Problem beheben“."
|
||
return 1
|
||
}
|
||
|
||
selected="$(zenity \
|
||
--file-selection \
|
||
--title="NGL Installer auswählen" \
|
||
--filename="$HOME/Downloads/" \
|
||
--file-filter="NGL Installer | *.zip *.ZIP *.exe *.EXE" \
|
||
--file-filter="Alle Dateien | *" 2>/dev/null)" || return 0
|
||
|
||
[[ -f "$selected" ]] || return 1
|
||
|
||
workdir="$CACHE_DIR/ngl-installer"
|
||
rm -rf -- "$workdir"
|
||
mkdir -p "$workdir"
|
||
|
||
case "${selected,,}" in
|
||
*.zip)
|
||
unzip -q "$selected" -d "$workdir" || {
|
||
notify_error "Der NGL-Installer konnte nicht entpackt werden."
|
||
return 1
|
||
}
|
||
exe="$(find "$workdir" -type f \( -iname '*ngl*.exe' -o -iname '*installer*.exe' -o -iname '*setup*.exe' -o -iname '*.exe' \) \
|
||
-printf '%p\n' | head -n 1)"
|
||
;;
|
||
*.exe)
|
||
exe="$selected"
|
||
;;
|
||
*)
|
||
notify_error "Bitte eine NGL-ZIP- oder EXE-Datei auswählen."
|
||
return 1
|
||
;;
|
||
esac
|
||
|
||
[[ -n "${exe:-}" && -f "$exe" ]] || {
|
||
notify_error "Kein Windows-Installer in der ausgewählten Datei gefunden."
|
||
return 1
|
||
}
|
||
|
||
if ! zenity --question --width=560 \
|
||
--title="NGL experimentell installieren?" \
|
||
--ok-label="Installer starten" \
|
||
--cancel-label="Abbrechen" \
|
||
--text="NGL ist Community-Code und läuft im selben Wine-Prefix wie dein RSI Launcher.
|
||
|
||
Bitte nutze ausschließlich Downloads von nglproject.com.
|
||
|
||
Fortfahren?" 2>/dev/null; then
|
||
return 0
|
||
fi
|
||
|
||
log_line "NGL installer confirmed by user"
|
||
|
||
{
|
||
printf 'wine '
|
||
printf '%q' "$exe"
|
||
printf '\nexit\n'
|
||
} | bash "$script" shell >>"$LOG_FILE" 2>&1
|
||
}
|
||
|
||
ngl_install() {
|
||
nohup bash "$SELF" ngl-install-interactive >>"$LOG_FILE" 2>&1 &
|
||
}
|
||
|
||
case "$ACTION" in
|
||
status) status ;;
|
||
primary) primary_action ;;
|
||
setup) guided_setup ;;
|
||
guided-setup-interactive) guided_setup_interactive ;;
|
||
repair) repair_assistant ;;
|
||
repair-interactive) repair_assistant_interactive ;;
|
||
support) support_start ;;
|
||
support-build) support_build ;;
|
||
debug-log) open_debug_log ;;
|
||
plugin-update-check) plugin_update_check ;;
|
||
plugin-update-now) plugin_update_now ;;
|
||
plugin-auto-enable) plugin_auto_enable ;;
|
||
plugin-auto-disable) plugin_auto_disable ;;
|
||
updater-log) open_updater_log ;;
|
||
check-update) check_update ;;
|
||
install-stack) launch_terminal_action install-stack-terminal ;;
|
||
install-stack-terminal) install_stack_terminal ;;
|
||
update-helper) launch_terminal_action update-helper-terminal ;;
|
||
update-helper-terminal) update_helper_terminal ;;
|
||
system-update) launch_terminal_action system-update-terminal ;;
|
||
system-update-terminal) system_update_terminal ;;
|
||
launch) launch_game ;;
|
||
helper) run_helper_gui ;;
|
||
install) run_helper_gui --install ;;
|
||
preflight) run_helper_gui --preflight-check ;;
|
||
runners) run_helper_gui --manage-runners ;;
|
||
dxvk) run_helper_gui --manage-dxvk ;;
|
||
repair-launch) run_helper_gui --update-launch-script ;;
|
||
repair-rsi) run_helper_gui --update-rsi-launcher ;;
|
||
dirs) run_helper_gui --show-directories ;;
|
||
log) open_log ;;
|
||
wiki) open_wiki ;;
|
||
ngl-page) open_ngl_page ;;
|
||
ngl-info) ngl_info ;;
|
||
ngl-install) ngl_install ;;
|
||
ngl-install-interactive) ngl_install_interactive ;;
|
||
*)
|
||
notify_error "Unbekannte Omarchy-Citizen-Aktion: $ACTION"
|
||
exit 2
|
||
;;
|
||
esac
|