#!/usr/bin/env bash set -euo pipefail # enable-game-mode.sh # Añade LSApplicationCategoryType=public.app-category.games y LSSupportsGameMode=true # al Info.plist de una app .app y re-firma el bundle ad-hoc para uso local. # # Uso: # ./enable-game-mode.sh "/ruta/a/Application.app" [--category public.app-category.games] [--no-quarantine] [--no-deep] # # Ejemplo: # ./enable-game-mode.sh "/Applications/Application.app" CATEGORY="public.app-category.games" REMOVE_QUARANTINE=1 USE_DEEP=1 APP="" die() { echo "Error: $*" >&2 exit 1 } usage() { cat < Cambia la categoría (por defecto: public.app-category.games) --no-quarantine No elimina atributos de cuarentena --no-deep Firma sin --deep (no recomendado) Ejemplo: $(basename "$0") "/Applications/Application.app" EOF } # Parseo simple de argumentos while [[ $# -gt 0 ]]; do case "$1" in --category) [[ $# -ge 2 ]] || die "--category requiere un valor" CATEGORY="$2" shift 2 ;; --no-quarantine) REMOVE_QUARANTINE=0 shift ;; --no-deep) USE_DEEP=0 shift ;; -h|--help) usage exit 0 ;; -*) die "Opción desconocida: $1" ;; *) if [[ -z "${APP}" ]]; then APP="$1" shift else die "Argumento inesperado: $1" fi ;; esac done [[ -n "${APP}" ]] || { usage; exit 1; } # Resolver ruta absoluta sin realpath APP_DIR="$(cd "$(dirname "$APP")" && pwd)" APP_NAME="$(basename "$APP")" APP_PATH="${APP_DIR}/${APP_NAME}" [[ -d "${APP_PATH}" && "${APP_PATH}" == *.app ]] || die "No parece un bundle .app válido: ${APP_PATH}" INFO_PLIST="${APP_PATH}/Contents/Info.plist" [[ -f "${INFO_PLIST}" ]] || die "No se encontró Info.plist en: ${INFO_PLIST}" # Comprobaciones de herramientas command -v plutil >/dev/null 2>&1 || die "plutil no encontrado" command -v codesign >/dev/null 2>&1 || die "codesign no encontrado" command -v xattr >/dev/null 2>&1 || echo "Aviso: xattr no encontrado; omitiendo cuarentena" >&2 command -v spctl >/dev/null 2>&1 || true # Copia de seguridad TS="$(date +%Y%m%d-%H%M%S)" BACKUP_PATH="${APP_PATH%.app}.backup-${TS}.app" echo "→ Creando copia de seguridad en: ${BACKUP_PATH}" cp -R "${APP_PATH}" "${BACKUP_PATH}" # (Opcional) Eliminar cuarentena if [[ "${REMOVE_QUARANTINE}" -eq 1 ]] && command -v xattr >/dev/null 2>&1; then echo "→ Eliminando cuarentena (si existe)" xattr -dr com.apple.quarantine "${APP_PATH}" || true fi # Editar Info.plist echo "→ Estableciendo LSApplicationCategoryType='${CATEGORY}'" plutil -replace LSApplicationCategoryType -string "${CATEGORY}" "${INFO_PLIST}" echo "→ Estableciendo LSSupportsGameMode=true" plutil -replace LSSupportsGameMode -bool true "${INFO_PLIST}" # Mostrar valores para confirmar echo "→ Claves establecidas:" plutil -p "${INFO_PLIST}" | grep -E "LSApplicationCategoryType|LSSupportsGameMode" || true # Re-firmar (ad-hoc) echo "→ Re-firmando bundle (ad-hoc)" if [[ "${USE_DEEP}" -eq 1 ]]; then codesign -f -s - --deep --preserve-metadata=entitlements,requirements,flags "${APP_PATH}" else codesign -f -s - --preserve-metadata=entitlements,requirements,flags "${APP_PATH}" fi # Verificaciones (best-effort) echo "→ Verificando firma y política de ejecución" codesign -dv --verbose=4 "${APP_PATH}" >/dev/null 2>&1 || true spctl -a -vv "${APP_PATH}" || true cat <<'DONE' Listo ✅ - Abre la app y ponla a pantalla completa para activar Game Mode durante la sesión. - Si algo falla, restaura la copia de seguridad creada junto al original. DONE