Maneira não-javascript
Na verdade, eu gosto de soluções, que podem ser baseadas em javascript, pois são mais prováveis relacionadas à Web, e boas chances são independentes de SO. No entanto, eu estava pensando em - como resolver seu problema em todos os navegadores, já que as soluções javascript, neste caso, serão difíceis de ajustar para todos os navegadores possíveis (não tenho certeza se é possível).
Então, como você mencionou, existe outra maneira - ie imitar o comportamento no nível do SO. Isso também tem outra vantagem - você pode ter certeza de que, para o navegador, parece 100% humano (porque, bem, é o driver que está enviando o sinal). Portanto, você pode usar soluções baseadas em driver / dispositivo com qualquer navegador (ou mesmo quando o javascript estiver desativado).
Linux
Infelizmente, envolver driver / dispositivo imediatamente causa dependência do sistema operacional. Portanto, para cada sistema operacional, você precisará de uma solução própria. Neste post, estou focado na solução baseada em Linux (portanto, funcionará com Linux) - e no Mac OS um pouco. Com o Linux, é possível gravar eventos no dispositivo explicitamente; portanto, abaixo está um exemplo de função com o loop principal:
int main()
{
struct input_event event, event_end;
int fd = open("/dev/input/event4", O_RDWR);
long ma = getInteger("Enter max amplitude [points, 0..50]: ", 0, 50);
long ta = getInteger("Enter max wait time [usecs , 0..200000]: ", 0, 200000);
if (fd < 0)
{
printf("Mouse access attempt failed:%s\n", strerror(errno));
return -1;
}
memset(&event, 0, sizeof(event));
memset(&event, 0, sizeof(event_end));
gettimeofday(&event.time, NULL);
event.type = EV_REL;
gettimeofday(&event_end.time, NULL);
event_end.type = EV_SYN;
event_end.code = SYN_REPORT;
event_end.value = 0;
while(1)
{
event.code = rand() % 2 ? REL_X : REL_Y;
event.value = (rand() % 2 ? -1 : 1) * randomTill(ma);
write(fd, &event, sizeof(event));
write(fd, &event_end, sizeof(event_end));
usleep(randomTill(ta));
}
close(fd);
return 0;
}
Meu código completo para o problema pode ser encontrado aqui . O programa pedirá amplitude de "tremor" e sua frequência (assim, quanto tempo em microssegundos há entre "tremores"). Para emular a situação, forçará o mouse a mover-se aleatoriamente para obter 0..X
pontos na direção aleatória (de cima para baixo, à esquerda, em baixo) e espere aleatoriamente 0..Y
microssegundos até o próximo "tremor", há X
amplitude de "tremor" eY
frequência de "tremor "
Outra coisa pode ser adaptar o programa ao seu sistema. O programa é "fictício" e não pode detectar o mouse por si só, por isso "/dev/input/event4"
é codificado. Para perceber o que pode ser um identificador para o seu sistema, você pode tentar:
user@host:/path$ cat /proc/bus/input/devices | grep mouse
H: Handlers=mouse0 event3
H: Handlers=mouse1 event4
E assim são as possibilidades "event3"
e "event4"
- mas para o seu sistema que podem ter outros valores. Portanto, se isso for diferente do atualmente usado no código C, basta alterar a linha correspondente (então, alinhe int fd = open("/dev/input/event4", O_RDWR);
e coloque o dispositivo em vez deevent4
)
Uma demonstração gif para este programa (baixa taxa de quadros, infelizmente, portanto, mantenha a imagem não muito grande) aqui .
Uma pequena nota lateral (se você não sabe o que fazer com o código C) - para compilar o programa acima, basta usar:
user@host:/path$ gcc -std=gnu99 file.c -o m
onde file.c
é o nome do seu arquivo de código-fonte C, você será executável, chamado m
em seu diretório. Provavelmente, você precisará de permissões para gravar diretamente no dispositivo do mouse, portanto, você pode usar sudo
:
user@host:/path$ sudo ./m
Outro SO
A lógica permanecerá a mesma:
- Encontre uma maneira de acessar o dispositivo do mouse
- Escrever evento de movimento do mouse
- Aplique a randomização ao seu evento
É isso aí. Por exemplo, o Mac OS possui uma maneira própria de trabalhar com o mouse (não como o Linux, o Mac também não procfs
), é bem descrito aqui .
Como uma conclusão
O que é melhor - soluções javascript ou orientadas a dispositivos - depende de você, porque determinadas condições (como entre navegadores ou SO) podem decidir tudo nesse caso. Portanto, forneci diretrizes juntamente com um exemplo prático de como implementá-lo no nível do sistema operacional. O benefício aqui é que a solução é entre navegadores, mas como custo, temos um programa vinculado ao sistema operacional.