diff --git a/.gitattributes b/.gitattributes index bb39dce..3c0abf0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,3 @@ * text=auto *.ps1 text eol=crlf *.md text eol=crlf -*.py text eol=lf diff --git a/.gitignore b/.gitignore index 6be1f5f..db4195b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ -__pycache__/ -*.pyc *.lnk diff --git a/AGENTS.md b/AGENTS.md index baf4c5c..1bfded0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,14 +7,13 @@ Guía para agentes de IA y colaboradores que trabajen en este repositorio. Utilidad para Windows que mueve el puntero del ratón solo tras un periodo de inactividad del usuario y se detiene al detectar uso real. Ver `README.md`. -- `Mover.ps1`: implementación principal (PowerShell + C# embebido con `Add-Type`). -- `main.py`: implementación original en Python (`pyautogui`), mantenida como referencia. +- `Mover.ps1`: implementación (PowerShell + C# embebido con `Add-Type`). ## Normas - Idioma: comentarios, documentación y mensajes en **castellano**. - Toda función nueva debe llevar documentación (`<# .SYNOPSIS #>` en PowerShell, - `/// ` en C#, docstrings en Python). Actualizar la documentación al modificarlas. + `/// ` en C#). Actualizar la documentación al modificarlas. - No modificar ficheros sin autorización previa del usuario. - Registrar los cambios en `CHANGELOG.md` y las tareas pendientes en `TODO.md`. @@ -39,6 +38,4 @@ usuario y se detiene al detectar uso real. Ver `README.md`. $err=$null; [System.Management.Automation.Language.Parser]::ParseFile('Mover.ps1',[ref]$null,[ref]$err) | Out-Null; $err.Count # Prueba funcional rápida powershell -ExecutionPolicy Bypass -File .\Mover.ps1 -TiempoInactividad 10 -# Python -python -m py_compile main.py ``` diff --git a/CHANGELOG.md b/CHANGELOG.md index f5298ff..7d6b28f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,13 +15,3 @@ El formato se basa en [Keep a Changelog](https://keepachangelog.com/es-ES/1.1.0/ - Mensajes con hora al iniciar y detener el movimiento. - Cierre automático de instancias anteriores al arrancar. - Documentación: `README.md`, `AGENTS.md`, `CHANGELOG.md` y `TODO.md`. - -### Cambiado -- `main.py`: el movimiento solo se activa tras 3 minutos de inactividad y se detiene al - detectar uso del usuario. Se sustituye `except:` por `except Exception` para permitir - detenerlo con `Ctrl+C`. - -## [0.1.0] - -### Añadido -- `main.py`: versión inicial que movía el ratón aleatoriamente de forma continua. diff --git a/README.md b/README.md index 17dd632..95371dc 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,12 @@ En cuanto se detecta uso real, el movimiento se detiene y se vuelve a esperar. | Fichero | Descripción | |--------------|-------------| -| `Mover.ps1` | Implementación principal en PowerShell. Sin dependencias externas. | -| `main.py` | Implementación original en Python (requiere `pyautogui`). Funcionalidad básica, sin animación. | +| `Mover.ps1` | Implementación en PowerShell. Sin dependencias externas. | ## Requisitos - Windows (usa las APIs `user32`/`kernel32`). -- `Mover.ps1`: Windows PowerShell 5.1 o PowerShell 7. -- `main.py`: Python 3 y `pip install pyautogui`. +- Windows PowerShell 5.1 o PowerShell 7. ## Uso de `Mover.ps1` diff --git a/TODO.md b/TODO.md index 284568f..9e32642 100644 --- a/TODO.md +++ b/TODO.md @@ -2,8 +2,6 @@ ## Pendiente -- [ ] Igualar `main.py` con `Mover.ps1` (deslizamiento animado, cierre de instancias previas, - mensajes) o retirarlo si deja de usarse. - [ ] Añadir un icono en la bandeja del sistema para pausar/salir sin abrir la consola. - [ ] Opción para impedir la suspensión con `SetThreadExecutionState` sin mover el puntero. - [ ] Registro opcional en fichero de los periodos de actividad/inactividad. diff --git a/main.py b/main.py deleted file mode 100644 index bacacd6..0000000 --- a/main.py +++ /dev/null @@ -1,82 +0,0 @@ -"""Mueve el ratón aleatoriamente solo tras un periodo de inactividad del usuario (solo Windows).""" -import ctypes -import ctypes.wintypes -import random -import time - -import pyautogui - -# Segundos sin uso de teclado/ratón antes de empezar a mover el cursor -TIEMPO_INACTIVIDAD = 180 -# Desplazamiento máximo (píxeles) en cada eje -DESPLAZAMIENTO_MAX = 50 -# Intervalo de comprobación de actividad (segundos) -INTERVALO_COMPROBACION = 0.2 - - -class LASTINPUTINFO(ctypes.Structure): - """Estructura de Win32 que recibe el instante de la última entrada del usuario.""" - - _fields_ = [("cbSize", ctypes.wintypes.UINT), ("dwTime", ctypes.wintypes.DWORD)] - - -def obtener_ultima_entrada(): - """ - Obtiene el instante (en ticks del sistema, ms) de la última entrada de teclado o ratón. - - :return: valor dwTime devuelto por GetLastInputInfo. - """ - info = LASTINPUTINFO() - info.cbSize = ctypes.sizeof(LASTINPUTINFO) - if not ctypes.windll.user32.GetLastInputInfo(ctypes.byref(info)): - raise ctypes.WinError() - return info.dwTime - - -def segundos_inactivo(): - """ - Calcula los segundos transcurridos desde la última entrada de teclado o ratón. - - :return: segundos de inactividad. - """ - ahora = ctypes.windll.kernel32.GetTickCount() & 0xFFFFFFFF - # Máscara para tolerar el desbordamiento de GetTickCount (~49,7 días) - return ((ahora - obtener_ultima_entrada()) & 0xFFFFFFFF) / 1000.0 - - -def esperar_inactividad(): - """Bloquea hasta que el usuario lleve TIEMPO_INACTIVIDAD segundos sin usar teclado ni ratón.""" - while segundos_inactivo() < TIEMPO_INACTIVIDAD: - time.sleep(1) - - -def mover_mientras_inactivo(): - """ - Mueve el ratón aleatoriamente hasta detectar actividad real del usuario. - - Los movimientos propios también actualizan GetLastInputInfo, por lo que tras cada - movimiento se guarda el dwTime resultante; cualquier cambio posterior indica uso real. - """ - while True: - pyautogui.moveRel(random.randrange(-DESPLAZAMIENTO_MAX, DESPLAZAMIENTO_MAX), - random.randrange(-DESPLAZAMIENTO_MAX, DESPLAZAMIENTO_MAX)) - ultima_propia = obtener_ultima_entrada() - fin_pausa = time.monotonic() + random.randrange(2, 5) - while time.monotonic() < fin_pausa: - time.sleep(INTERVALO_COMPROBACION) - if obtener_ultima_entrada() != ultima_propia: - return - - -def main(): - """Bucle principal: espera la inactividad, mueve el ratón y se detiene al detectar uso.""" - while True: - try: - esperar_inactividad() - mover_mientras_inactivo() - except Exception: - time.sleep(1) - - -if __name__ == "__main__": - main()