Last active 1 month ago

enable-game-mode.sh Raw
1#!/usr/bin/env bash
2set -euo pipefail
3
4# enable-game-mode.sh
5# Añade LSApplicationCategoryType=public.app-category.games y LSSupportsGameMode=true
6# al Info.plist de una app .app y re-firma el bundle ad-hoc para uso local.
7#
8# Uso:
9# ./enable-game-mode.sh "/ruta/a/Application.app" [--category public.app-category.games] [--no-quarantine] [--no-deep]
10#
11# Ejemplo:
12# ./enable-game-mode.sh "/Applications/Application.app"
13
14CATEGORY="public.app-category.games"
15REMOVE_QUARANTINE=1
16USE_DEEP=1
17
18APP=""
19
20die() {
21 echo "Error: $*" >&2
22 exit 1
23}
24
25usage() {
26 cat <<EOF
27Uso: $(basename "$0") "/ruta/a/App.app" [opciones]
28
29Opciones:
30 --category <id> Cambia la categoría (por defecto: public.app-category.games)
31 --no-quarantine No elimina atributos de cuarentena
32 --no-deep Firma sin --deep (no recomendado)
33
34Ejemplo:
35 $(basename "$0") "/Applications/Application.app"
36EOF
37}
38
39# Parseo simple de argumentos
40while [[ $# -gt 0 ]]; do
41 case "$1" in
42 --category)
43 [[ $# -ge 2 ]] || die "--category requiere un valor"
44 CATEGORY="$2"
45 shift 2
46 ;;
47 --no-quarantine)
48 REMOVE_QUARANTINE=0
49 shift
50 ;;
51 --no-deep)
52 USE_DEEP=0
53 shift
54 ;;
55 -h|--help)
56 usage
57 exit 0
58 ;;
59 -*)
60 die "Opción desconocida: $1"
61 ;;
62 *)
63 if [[ -z "${APP}" ]]; then
64 APP="$1"
65 shift
66 else
67 die "Argumento inesperado: $1"
68 fi
69 ;;
70 esac
71done
72
73[[ -n "${APP}" ]] || { usage; exit 1; }
74
75# Resolver ruta absoluta sin realpath
76APP_DIR="$(cd "$(dirname "$APP")" && pwd)"
77APP_NAME="$(basename "$APP")"
78APP_PATH="${APP_DIR}/${APP_NAME}"
79
80[[ -d "${APP_PATH}" && "${APP_PATH}" == *.app ]] || die "No parece un bundle .app válido: ${APP_PATH}"
81
82INFO_PLIST="${APP_PATH}/Contents/Info.plist"
83[[ -f "${INFO_PLIST}" ]] || die "No se encontró Info.plist en: ${INFO_PLIST}"
84
85# Comprobaciones de herramientas
86command -v plutil >/dev/null 2>&1 || die "plutil no encontrado"
87command -v codesign >/dev/null 2>&1 || die "codesign no encontrado"
88command -v xattr >/dev/null 2>&1 || echo "Aviso: xattr no encontrado; omitiendo cuarentena" >&2
89command -v spctl >/dev/null 2>&1 || true
90
91# Copia de seguridad
92TS="$(date +%Y%m%d-%H%M%S)"
93BACKUP_PATH="${APP_PATH%.app}.backup-${TS}.app"
94echo "→ Creando copia de seguridad en: ${BACKUP_PATH}"
95cp -R "${APP_PATH}" "${BACKUP_PATH}"
96
97# (Opcional) Eliminar cuarentena
98if [[ "${REMOVE_QUARANTINE}" -eq 1 ]] && command -v xattr >/dev/null 2>&1; then
99 echo "→ Eliminando cuarentena (si existe)"
100 xattr -dr com.apple.quarantine "${APP_PATH}" || true
101fi
102
103# Editar Info.plist
104echo "→ Estableciendo LSApplicationCategoryType='${CATEGORY}'"
105plutil -replace LSApplicationCategoryType -string "${CATEGORY}" "${INFO_PLIST}"
106
107echo "→ Estableciendo LSSupportsGameMode=true"
108plutil -replace LSSupportsGameMode -bool true "${INFO_PLIST}"
109
110# Mostrar valores para confirmar
111echo "→ Claves establecidas:"
112plutil -p "${INFO_PLIST}" | grep -E "LSApplicationCategoryType|LSSupportsGameMode" || true
113
114# Re-firmar (ad-hoc)
115echo "→ Re-firmando bundle (ad-hoc)"
116if [[ "${USE_DEEP}" -eq 1 ]]; then
117 codesign -f -s - --deep --preserve-metadata=entitlements,requirements,flags "${APP_PATH}"
118else
119 codesign -f -s - --preserve-metadata=entitlements,requirements,flags "${APP_PATH}"
120fi
121
122# Verificaciones (best-effort)
123echo "→ Verificando firma y política de ejecución"
124codesign -dv --verbose=4 "${APP_PATH}" >/dev/null 2>&1 || true
125spctl -a -vv "${APP_PATH}" || true
126
127cat <<'DONE'
128
129Listo ✅
130- Abre la app y ponla a pantalla completa para activar Game Mode durante la sesión.
131- Si algo falla, restaura la copia de seguridad creada junto al original.
132DONE
133
macos-gamemode.md Raw

Activar Game Mode en una app de macOS (edición local)

Resumen: Vas a añadir dos claves al Info.plist para declarar la app como Juegos y marcarla como compatible con Game Mode, y después volver a firmarla ad‑hoc para que se ejecute localmente.

Requisitos

  • macOS Sonoma (14) o posterior.
  • Terminal con permisos de administrador cuando sea necesario.
  • Trabaja sobre una copia si no quieres modificar el original.

Pasos rápidos

  1. (Opcional) Quitar cuarentena y/o hacer copia
cp -R "/Applications/Application.app" ~/Desktop/
xattr -dr com.apple.quarantine ~/Desktop/Application.app  # si la app está bloqueada
cd ~/Desktop
  1. Editar Info.plist
plutil -replace LSApplicationCategoryType -string "public.app-category.games"   "Application.app/Contents/Info.plist"

plutil -replace LSSupportsGameMode -bool true   "Application.app/Contents/Info.plist"
  1. Re-firmar ad‑hoc (uso local)
codesign -f -s - --deep --preserve-metadata=entitlements,requirements,flags   "Application.app"
  1. Abrir a pantalla completa → Game Mode se activa durante la sesión.

Verificaciones útiles

# Comprobar claves
plutil -p "Application.app/Contents/Info.plist" |   grep -E "LSApplicationCategoryType|LSSupportsGameMode"

# Ver firma y política de ejecución
codesign -dv --verbose=4 "Application.app"
spctl -a -vv "Application.app"

Script automático

Si prefieres automatizar todo, usa el script: enable-game-mode.sh.
Uso básico:

chmod +x enable-game-mode.sh
./enable-game-mode.sh "/Applications/Application.app"

Flags opcionales:

  • --category <id> para cambiar la categoría (por defecto: public.app-category.games).
  • --no-quarantine para no tocar atributos de cuarentena.
  • --no-deep para firmar sin --deep (no recomendado salvo bundles simples).

Notas y advertencias

  • Cualquier cambio en el bundle invalida la firma original. Re‑firmar con -s - (ad‑hoc) es suficiente para uso local, no para distribución.
  • Si vas a distribuir la app, firma con Developer ID y notariza para evitar bloqueos de Gatekeeper.
  • Algunas apps pueden dejar de auto‑actualizarse tras modificar el bundle.