Author Topic: Реалистичное передвижение курсора по траектории кривых Безье.  (Read 5573 times)

0 Members and 1 Guest are viewing this topic.

Kashey

  • Зашел в гости
  • *
  • Posts: 10
    • View Profile
Здравствуйте.

К сожалению, авторы игр борются с автоматизацией рутинных действий. Одним из способов для того, чтобы узнать, использовались ли инструменты автоматизации во время игры является оценка движений мышки пользователя по их внутренним критериям. Возможно предположить, что по этим критериям быстрые и прямолинейные движения могут оцениваться как автоматические, ненатуральные. В этом есть своя правда, рукой сделать прямые быстрые точные до пикселя движения мышкой практически невозможно. Хоть подобного рода перемещения и являют собой наиболее простые и лаконичные движения, из - за того, что они могут послужить поводом до вероятных санкций со стороны администраторов игры, при создании скрипта автоматизации их следует избегать. Для этого придумано много вариантов движений, некоторые из них читатель может найти по этой ссылке: http://crapware.aidf.org/forum/index.php?topic=2112.0

Ниже я предлагаю свой вариант движения.

Кривые Безье, как говорит Википедия, являются частным случаем многочленов Бернштейна. С теорией и практикой реализации алгоритмов можно ознакомиться по следующим ссылкам:
https://habr.com/ru/post/344814/
https://habr.com/ru/post/249103/
https://www.cat-in-web.ru/bezier-curves/

Для построения кривых Безье обычно используется рекурсивный алгоритм де Кастельжо. К сожалению из - за ограничений скриптового языка Кликермэнна, непосредственное применение этого алгоритма в нём невозможно. В настоящей реализации я изменил алгоритм де Кастельжо убрав из него рекурсию и адаптировав его к потребностям автоматизации рутинных действий.

К сожалению, алгоритм кривых Безье требует некоторых вычислительных мощностей, что может привести Кликермэнн, не страдающий быстродействием, в некоторое замешательство. Для увеличения быстродействия может быть полезно написать код в другом, более быстром, языке программирования и подключать его внешней скомпилированной библиотекой.

Также замечу, что алгоритм всегда передвигает мышку точно в назначенное ему место, и, если это требуется, необходимо решить проблему размытия координат внешне.


Code: (clickermann) [Select]
// Алгоритм передвижения мышки по траекториям Безье.
// На вход подаются координаты конца пути,
// алгоритм осуществляет движение.

// Алгоритм полностью настраиваемый.

// При большом сглаживании может работать медленно.

// Характер кривых подобран так, чтобы
// основные изменения кривизны происходили
// в самом начале пути. Это отображает
// неосознанные движения пользователя мышкой
// в тот момент, когда он ещё только ищет глазами
// элемент, на который надо нажать.

// Автор реализации алгоритма Kashey.
 
#name "Bezier_move"
// ================ Глобальные переменные
// Количество отрезков, на которое делится путь передвижения. От этого параметра зависит порядок функции Безье и количество петель передвижения. Сильно влияет на производительность.
$steps = 5
// Фактор отклонения отрезков от прямой линии пути. Этот параметр влияет на то, насколько сильно полученный путь будет не похож на прямой отрезок.
$noise = 1
// шаг в расчёте кривых Безье. От этого параметра зависит то, насколько сглаженная будет конечная кривая.
$bezierStep = 2
// Служебные
$tempX = 0
$tempY = 0

// ================ Подпрограммы  

// Расчёт точки на отрезке со смещением ptime.
SUB(pointsCalc, $x1, $y1, $x2, $y2, $rx, $ry, $ptime)
setvar($rx, ($x2-$x1)*($ptime/100)+$x1)             
setvar($ry, ($y2-$y1)*($ptime/100)+$y1)
END_SUB

// Алгоритм передвижения по кривым Безье
SUB(bezier_move,$_X,$_Y)
// Расчёт длины одного отрезка.   
$snipX = ($_X - $_xmouse)/$steps 
$snipY = ($_Y - $_ymouse)/$steps
// Расчёт отклонения отрезка.
$divX = INT(ABS($_xmouse - $_X) * $noise)
$divY = INT(ABS($_ymouse - $_Y) * $noise)
// Копирование координат мышки.
$tempX = $_xmouse
$tempY = $_ymouse
// Инициализация массивов с концами отрезков.
$pointsX[0] = $_xmouse
$pointsY[0] = $_ymouse
// Расчёт и запись координат концов отрезков.   
FOR($a=0, $a < $steps)
$pointsX[$a+1] = $tempX + $snipX + RND(-$divX, $divX)
$pointsY[$a+1] = $tempY + $snipY + RND(-$divY, $divY)
// Здесь можно подключить свой алгоритм движения. Но тогда алгоритм Безье надо выключить.
// MOVE($tempX + RND(-$divX, $divX), $tempY + RND(-$divY, $divY))
END_CYC
$pointsX[$steps+1] = $_X
$pointsY[$steps+1] = $_Y
// Инициализация вспомогательного массива для временного содержания найденных отрезков Безье.
$arrX[0] = 0
$arrY[0] = 0 
// Начало алгоритма кривых Безье.                   
for($time = $bezierStep, $time < 101, $bezierStep)
// Иницилизируем основной массив концов отрезков, с которым будем работать. $tempPointsX - основной массив, $pointsX - образец.
for($i = 0, $i < arrsize($pointsX))
$tempPointsX[$i] = $pointsX[$i]
$tempPointsY[$i] = $pointsY[$i]
END_CYC
// повторяем до тех пор, пока не останется только Один отрезок.
WHILE(arrsize($tempPointsX) > 2)   
For ($i = 0, $i < (arrsize($tempPointsX) - 1))
// Выбираем по два конца отрезков и считаем среднюю точку.           
pointsCalc($tempPointsX[$i], $tempPointsY[$i], $tempPointsX[$i + 1], $tempPointsY[$i + 1], "$tempX", "$tempY", $time)
// Складываем во вспомогательный массив.
$arrX[$i] = $tempX
$arrY[$i] = $tempY 
END_CYC
// Переписываем точки из вспомогательного массива в основной. 
For ($i = 0, $i < (arrsize($tempPointsX) - 1))
$tempPointsX[$i] = $arrX[$i]
$tempPointsY[$i] = $arrY[$i]
END_CYC
// Значений в мвссиве стало на один меньше, удаляем ненужный элемент.         
$i = arrpop($tempPointsX)
$i = arrpop($tempPointsY)
END_CYC
// Остался только один отрезок, считаем на нём точку.
pointsCalc($tempPointsX[0], $tempPointsY[0], $tempPointsX[1], $tempPointsY[1], "$tempX", "$tempY", $time)
// Мы получили точку кривой Безье.
$arrX[0] = $tempX
$arrY[0] = $tempY
// Передвигаем в неё мышку.   
move(ROUND($arrX[0], 0),ROUND($arrY[0], 0))
// Если вдруг понадобится дополнительно замедлить алгоритм, то в этом месте можно добавить соответствующую команду ожидания.
END_CYC
END_SUB

// Эта часть не является частью алгоритма, написана только с целью демонстрации его работы.

LDOWN($_xmouse,$_ymouse)
$x = $_xmouse
$y = $_ymouse
Bezier_move($x + 500, $y + 500)     

LUP($_xmouse,$_ymouse)


« Last Edit: November 07, 2020, 01:37:27 AM by Kashey »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Красивые закарючки получаются  :D.

В алгоритм вникнуть даже и не пытался, образование не позволяет  :-[, слишком сложно там все. В принципе, если шаг сдвига курсора увеличить, сделать его рандомным, тем самым увеличится скорость передвижения, то выглядело бы вполне раелистично. Я так понимаю, что это скорее всего тестовый образец.

Но ближе к делу, я тебе и в той теме писал, что сетвар не нужен. Убрал его не вникая в работу скрипта за минуту. Результат работы алгоритма не изменился.
Ну и еще две минуты потратил на то, чтобы узнать, зачем вообще нужны эти переменные $tempX и $tempY. Убрал их. Результат остался прежним.

Code: (clickermann) [Select]
// Алгоритм передвижения мышки по траекториям Безье.
// На вход подаются координаты конца пути,
// алгоритм осуществляет движение.

// Алгоритм полностью настраиваемый.

// При большом сглаживании может работать медленно.

// Характер кривых подобран так, чтобы
// основные изменения кривизны происходили
// в самом начале пути. Это отображает
// неосознанные движения пользователя мышкой
// в тот момент, когда он ещё только ищет глазами
// элемент, на который надо нажать.

// Автор реализации алгоритма Kashey.

#name "Bezier_move"
// ================ Глобальные переменные
// Количество отрезков, на которое делится путь передвижения. От этого параметра зависит порядок функции Безье и количество петель передвижения. Сильно влияет на производительность.
$steps = 5
// Фактор отклонения отрезков от прямой линии пути. Этот параметр влияет на то, насколько сильно полученный путь будет не похож на прямой отрезок.
$noise = 1
// шаг в расчёте кривых Безье. От этого параметра зависит то, насколько сглаженная будет конечная кривая.
$bezierStep = 2


// ================ Подпрограммы

// Расчёт точки на отрезке со смещением ptime.
SUB(pointsCalc, $x1, $y1, $x2, $y2, $ptime)
   $arrX[$i] = ($x2-$x1)*($ptime/100)+$x1
   $arrY[$i] = ($y2-$y1)*($ptime/100)+$y1
END_SUB

// Алгоритм передвижения по кривым Безье
SUB(bezier_move,$_X,$_Y)
   // Расчёт длины одного отрезка.
   $snipX = ($_X - $_xmouse)/$steps
   $snipY = ($_Y - $_ymouse)/$steps
   // Расчёт отклонения отрезка.
   $divX = INT(ABS($_xmouse - $_X) * $noise)
   $divY = INT(ABS($_ymouse - $_Y) * $noise)
   // Инициализация массивов с концами отрезков.
   $pointsX[0] = $_xmouse
   $pointsY[0] = $_ymouse
   // Расчёт и запись координат концов отрезков.
   FOR($a=0, $a < $steps)
      $pointsX[$a+1] = $_xmouse + $snipX + RND(-$divX, $divX)
      $pointsY[$a+1] = $_ymouse + $snipY + RND(-$divY, $divY)
      // Здесь можно подключить свой алгоритм движения. Но тогда алгоритм Безье надо выключить.
      // MOVE($tempX + RND(-$divX, $divX), $tempY + RND(-$divY, $divY))
   END_CYC
   $pointsX[$steps+1] = $_X
   $pointsY[$steps+1] = $_Y
   // Инициализация вспомогательного массива для временного содержания найденных отрезков Безье.
   $arrX[0] = 0
   $arrY[0] = 0
   // Начало алгоритма кривых Безье.
   for($time = $bezierStep, $time < 101, $bezierStep)
      // Иницилизируем основной массив концов отрезков, с которым будем работать. $tempPointsX - основной массив, $pointsX - образец.
      for($i = 0, $i < arrsize($pointsX))
         $tempPointsX[$i] = $pointsX[$i]
         $tempPointsY[$i] = $pointsY[$i]
      END_CYC
      // повторяем до тех пор, пока не останется только Один отрезок.
      WHILE(arrsize($tempPointsX) > 2)
         For ($i = 0, $i < (arrsize($tempPointsX) - 1))
            // Выбираем по два конца отрезков и считаем среднюю точку.
            pointsCalc($tempPointsX[$i], $tempPointsY[$i], $tempPointsX[$i + 1], $tempPointsY[$i + 1], $time)
         END_CYC
         // Переписываем точки из вспомогательного массива в основной.
         For ($i = 0, $i < (arrsize($tempPointsX) - 1))
            $tempPointsX[$i] = $arrX[$i]
            $tempPointsY[$i] = $arrY[$i]
         END_CYC
         // Значений в мвссиве стало на один меньше, удаляем ненужный элемент.
         $i = arrpop($tempPointsX)
         $i = arrpop($tempPointsY)
      END_CYC
      // Остался только один отрезок, считаем на нём точку.
      pointsCalc($tempPointsX[0], $tempPointsY[0], $tempPointsX[1], $tempPointsY[1], $time)
      // Мы получили точку кривой Безье.
      $arrX[0] = $arrX[$i]
      $arrY[0] = $arrY[$i]
      // Передвигаем в неё мышку.
      move(ROUND($arrX[0], 0),ROUND($arrY[0], 0))
      // Если вдруг понадобится дополнительно замедлить алгоритм, то в этом месте можно добавить соответствующую команду ожидания.
   END_CYC
END_SUB

// Эта часть не является частью алгоритма, написана только с целью демонстрации его работы.
wait(2)
LDOWN($_xmouse,$_ymouse)
$x = $_xmouse
$y = $_ymouse
Bezier_move($x + 500, $y + 500)

LUP($_xmouse,$_ymouse)
halt

Иллюстрация движения мыши, для наглядности, каждый старт скрипта новым цветом, красиво:



« Last Edit: November 07, 2020, 08:17:38 PM by dramster »

Kashey

  • Зашел в гости
  • *
  • Posts: 10
    • View Profile
Алгоритм не очень сложный, я вроде комментарии везде написал. Посмотрите ссылки в начале поста, по ним много полезной инфы. Если будет желание, надеюсь, разберётесь.

Алгоритмом управляют 3 переменных, все они вынесены в шапку кода и каждую можно сделать случайной. Если надо, пользуйтесь.

Про сетвар, это особенности языка. Без него код лаконичнее, но, чтобы понять как это работает надо хорошо знать эти особенности.

У меня просьба, я там ошибку нашёл, не могли бы вы её исправить в своём посте тоже. В предложении:

Code: (clickermann) [Select]
// шаг в расчёте кривых Безье. От этого параметра зависит то, насколько сглаженная будет конечная прямая.
$bezierStep = 2
заменить "прямая" на "кривая".

Я надеюсь, что это хорошая заявка на полное решение проблемы реалистичного передвижения мышки. Если у кого есть свои мысли на этот счёт, пишите.

А кривые, да, красивые. Выкладывайте их больше!

« Last Edit: November 08, 2020, 03:59:32 AM by Kashey »

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Максимально оптимизировал код. Удалось сократить время выполнения примерно в 2 раза. Тестировал на отрезке ~707 пикс (х+500, у+500), параметры по умолчанию.
Code: (clickermann) [Select]
// Алгоритм передвижения мышки по траекториям Безье.
// На вход подаются координаты конца пути,
// алгоритм осуществляет движение.

// Алгоритм полностью настраиваемый.

// При большом сглаживании может работать медленно.

// Характер кривых подобран так, чтобы
// основные изменения кривизны происходили
// в самом начале пути. Это отображает
// неосознанные движения пользователя мышкой
// в тот момент, когда он ещё только ищет глазами
// элемент, на который надо нажать.

// Автор реализации алгоритма Kashey.

#name "Bezier_move"
// ================ Глобальные переменные
// Количество отрезков, на которое делится путь передвижения. От этого параметра зависит порядок функции Безье и количество петель передвижения. Сильно влияет на производительность.
$steps = 5
// Фактор отклонения отрезков от прямой линии пути. Этот параметр влияет на то, насколько сильно полученный путь будет не похож на прямой отрезок.
$noise = 1
// шаг в расчёте кривых Безье. От этого параметра зависит то, насколько сглаженная будет конечная кривая.
$bezierStep = 2




// Алгоритм передвижения по кривым Безье
SUB(bezier_move,$_X,$_Y)
   
   // Расчёт отклонения отрезка.
   $divX = INT(ABS($_xmouse - $_X) * $noise)
   $divY = INT(ABS($_ymouse - $_Y) * $noise)
   // Инициализация массива с концами отрезков.
   $pointsX[0] = $_xmouse
   $pointsY[0] = $_ymouse
   FOR($a=0, $a < $steps)
      $pointsX[$a+1] = $_xmouse + ($_X - $_xmouse)/$steps + RND(-$divX, $divX)
      $pointsY[$a+1] = $_ymouse + ($_Y - $_ymouse)/$steps + RND(-$divY, $divY)
   END_CYC
   $pointsX[$steps+1] = $_X
   $pointsY[$steps+1] = $_Y
   
   // Начало алгоритма кривых Безье.
   for($time = $bezierStep, $time < 101, $bezierStep)
     
      for($i = 0, $i < $steps+2)
         $tempPointsX[$i] = $pointsX[$i]
         $tempPointsY[$i] = $pointsY[$i]
      END_CYC
     
      For ($a = $steps+2, $a > 1, -1)
         For ($i = 0, $i < ($a-1))
            $tempPointsX[$i] = ($tempPointsX[$i+1]-$tempPointsX[$i])*($time/100)+$tempPointsX[$i]
            $tempPointsY[$i] = ($tempPointsY[$i+1]-$tempPointsY[$i])*($time/100)+$tempPointsY[$i]
         END_CYC
      END_CYC
     
      move(int($tempPointsX[0]),int($tempPointsY[0]))
     
   END_CYC
   
END_SUB

// Эта часть не является частью алгоритма, написана только с целью демонстрации его работы.
wait(2)

$x = 500
$y = 350

LDOWN($x,$y)

$t = $_ms
Bezier_move($x + 500, $y + 500)
print($_ms-$t," ms.")  //проверка на скорость выполнения.

LUP($_xmouse,$_ymouse)
halt

 Кстати если поиграть с начальными параметрами, то и действительно, выглядит примерно как ребенок мышкой играет  :D , очень реалистично.
 Я вчера нарисовал данным алгоритмом с помощью кликера картину и показал брату - он не поверил что это комп нарисовал, сказал, что примерно так его сын в паинте рисует, не отличить  ;D





Kashey

  • Зашел в гости
  • *
  • Posts: 10
    • View Profile
Ну после такой высокой оценки алгоритм можно назвать симулятором ребёнка :)

Правки мне очень понравились, особенно хитро получилось с этими с этим циклом, сам что - то я до такого не додумался:

Code: (clickermann) [Select]
      For ($a = $steps+2, $a > 1, -1)
         For ($i = 0, $i < ($a-1))
            $tempPointsX[$i] = ($tempPointsX[$i+1]-$tempPointsX[$i])*($time/100)+$tempPointsX[$i]
            $tempPointsY[$i] = ($tempPointsY[$i+1]-$tempPointsY[$i])*($time/100)+$tempPointsY[$i]
         END_CYC
      END_CYC

Немного опишу работу алгоритма. Он состоит из двух частей, первая рисует ломаную кривую, вторая сглаживает её алгоритмом Безье.
Ломанная кривая рисуется так: сначала весь путь делится на количество шагов steps и потом к каждому шагу добавляется случайное отклонение, которое, в свою очередь, вычисляется в соответствии с длинной пути перемещения. То есть на небольшие пути будет малое отклонение, на большие - большое. За влияние этого отклонение отвечает переменная noise.

 




Kashey

  • Зашел в гости
  • *
  • Posts: 10
    • View Profile
Ну чем не современное искусство?


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Сам когда-то думал о Безье. Глянул, там формулы трёхэтажные, думаю куда там кликером их считать. И не думал что можно так упростить.

Красиво конечно выходит, но хочу задать пару вопросов. Если двигать не совсем уж по прямой, как в старых скриптах, какой алгоритм будет это вылавливать? Кто там отличит плавные Безье от случайных отклонений и сколько на это нужно ресурсов. Никто столько не выделит.
Если определять визуально, то перемещения похожи, но похожи на задумавшегося человека, так водят мышкой в размышлениях или от скуки. При жёсткой и быстрой работе с интерфейсом, таких вензелей минимум. Ну, по крайней мере большая часть.
И главное это скорость! Курсор "тяжёлый", человек разгоняет его сначала, потом идёт движение на максимальной скорости и торможение. Торможение медленнее, чем разгон, т.к. идёт прицеливание.

Задание на дальнейшее развитие скрипта, чтоб прям "ну как человек"  ;D  -  Сделать изменение скорости по наклонённой параболе или как там оно должно быть.


Kashey

  • Зашел в гости
  • *
  • Posts: 10
    • View Profile
Сам когда-то думал о Безье. Глянул, там формулы трёхэтажные, думаю куда там кликером их считать. И не думал что можно так упростить.

Красиво конечно выходит, но хочу задать пару вопросов. Если двигать не совсем уж по прямой, как в старых скриптах, какой алгоритм будет это вылавливать? Кто там отличит плавные Безье от случайных отклонений и сколько на это нужно ресурсов. Никто столько не выделит.
Если определять визуально, то перемещения похожи, но похожи на задумавшегося человека, так водят мышкой в размышлениях или от скуки. При жёсткой и быстрой работе с интерфейсом, таких вензелей минимум. Ну, по крайней мере большая часть.
И главное это скорость! Курсор "тяжёлый", человек разгоняет его сначала, потом идёт движение на максимальной скорости и торможение. Торможение медленнее, чем разгон, т.к. идёт прицеливание.

Задание на дальнейшее развитие скрипта, чтоб прям "ну как человек"  ;D  -  Сделать изменение скорости по наклонённой параболе или как там оно должно быть.
Вопрос, конечно не по адресу. Я не знаю, что они там используют для выявления автомитизации и сколько ресурсов на это надо.

Лично мне не нравилось наличие в других предложенных скриптах большого количества углов. Движения должны быть плавнее.
И третье, забанить человека за то, что он слишком задумчивый - это надо быть очень жёстким админом :)

Скрипт, как я уже писал, - настраиваемый, можно свести количество вензелей к минимуму , оставив только плавное перемещение. Для этого поставьте
Code: (clickermann) [Select]
$steps = 1


Изменять скорость в данном скрипте нецелесообразно, поскольку интерпретатор Кликерманна снижает эту самую скорость до минимума. Глазом заметно как он мышкой водит. Но Вы, если будете писать его в С++ и подключать внешней библиотекой, можете реализовать данную возможность.

Кстати, курсор не такой уж и тяжёлый, если, конечно, тефлоновые подставки на мышке не стёрты и на коврике чисто. Можете, кстати, собрать статистику на эту тему, я с удовольствием посмотрю.
« Last Edit: November 09, 2020, 07:39:05 PM by Kashey »

Axelenz

  • Освоившийся
  • **
  • Posts: 31
  • Парсинг сайтов, наполнение интернет-магазинов
    • View Profile
Добавлю своё понимание "реалистичности"...
Человек не робот и он не может прицельно взять мышку, не сдвинув её на минимальное расстояние и точно так же не может остановиться на заданной точке намертво. Поэтому для "реалистичности" движения (я использовал это правда не в играх, а на сайте, где была нежелательна автоматизированная работа с товаром, а товара было тысячи позиций, поэтому перестраховался...) вставлял "тремор рук"... непроизвольное движение, когда команда с головы уже ушла, а рука по инерции не успела остановиться  :)

Code: (clickermann) [Select]
SUB(mouse_tremor, $_xmouse, $_ymouse)
   //тремор
   //MOVE($_xmouse + RNDFROM(-1, 1, 2, 3), $_ymouse + RNDFROM(-1, 1, 2, 3))
   //WAITMS(RND(100, 150))
   MOVE($_xmouse + RND(-1, 1), $_ymouse + RND(-1, 1))
   WAITMS(RND(50, 100))
   MOVE($_xmouse + RNDFROM(0, -1, 0, 1, 0), $_ymouse + RNDFROM(0, -1, 0, 1, 0))
   WAITMS(RND(500, 1000))
END_SUB

Тремор перед любым началом движения мышки и в конце, при останове, добавлял так же в скрипт с форума:

Code: (clickermann) [Select]
SUB(mouse_move, $MOVE_END_X, $MOVE_END_Y)
   $RND_SPEED_MIN = 3
   $RND_SPEED_MAX = 5
   $MOVE_SPEED = RND($RND_SPEED_MIN, $RND_SPEED_MAX)  //множитель скорости
   //Отвечает за количество точек, по которым движется курсор
   
   $MOVE_Start_X = $_xmouse
   $MOVE_Start_Y = $_ymouse
   $MOVE_X = $MOVE_Start_X
   $MOVE_Y = $MOVE_Start_Y
   
   $dist = DIST($MOVE_END_X, $MOVE_END_Y, $MOVE_Start_X, $MOVE_Start_Y)
   
   $MOVE_SPEEDVAR = INT((SQRT($dist))/$MOVE_SPEED)
   
   IF($MOVE_SPEEDVAR < 1)
      $MOVE_SPEEDVAR = 1
   END_IF
   
   $MOVE_step = ($dist-1)/$MOVE_SPEEDVAR
   $MOVE_X_step = ($MOVE_END_X-$MOVE_Start_X)/$MOVE_step
   $MOVE_Y_step = ($MOVE_END_Y-$MOVE_Start_Y)/$MOVE_step
   
   FOR($MOVE_i = 0, $MOVE_i < INT($MOVE_step))
      $MOVE_X = $MOVE_X + $MOVE_X_step
      $MOVE_Y = $MOVE_Y + $MOVE_Y_step
      MOVE(ROUND($MOVE_X, 0), ROUND($MOVE_Y, 0))
      WAITMS($RND_SPEED_MIN + $RND_SPEED_MAX - $MOVE_SPEED)   //скорость перемещения в мс
      //Можно увеличить задержку между каждым движением к следующей точке.
   END_CYC
   
   MOVE($MOVE_END_X, $MOVE_END_Y)  //передвинуть окончательно в заданную точку
   WAITMS(RND(200, 300))
   
   mouse_tremor($_xmouse, $_ymouse)
END_SUB

Это даже движениями трудно назвать... это скорее микродвижения, связанные с дыханием человека, его сердцебиением, гендерной принадлежности, днём недели (это вечер пятницы или утро понедельника), принятием дозы алкоголя до того, истеричным складом ума и т.п. факторами физиологического и психического характера... Думал даже сделать разные треморы для разных психотипов людей, чтобы при входе с разных аккаунтов подключалась или истеричка или флегмат и т.д.  ;)
« Last Edit: November 10, 2020, 11:37:33 PM by Axelenz »
"Можно бесконечно смотреть на три вещи: как течёт вода, как горит огонь и как Clickermann работает вместо тебя..."

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Это даже движениями трудно назвать... это скорее микродвижения, связанные с дыханием человека, его сердцебиением, гендерной принадлежности, днём недели (это вечер пятницы или утро понедельника), принятием дозы алкоголя до того, истеричным складом ума и т.п. факторами физиологического и психического характера... Думал даже сделать разные треморы для разных психотипов людей, чтобы при входе с разных аккаунтов подключалась или истеричка или флегмат и т.д.  ;)

Да, есть такое. Но опять же, насколько целесообразно такое вводить? Есть ли данные что это отслеживается?

Поясню. Ставите себя на место разработчика, которому нужно отсеять большинство (не всех, всех очень трудно) автоматов. В нашем случае говорим сейчас только про движение курсора.
1. Отслеживаем, что курсор вообще движется, а не шлются тупо запросы, например POST. Часть самых распространённых автоматов отвалилась.
2. Отслеживаем, что курсор не телепортируется. Часть примитивов отвалилась.
3. Отслеживаем, что курсор движется не по прямой.

Большинство ограничивается 1 пунктом.
Максимум 3 пункта используют, думаю оставшихся 99 процентов. Потому как...

4. Отслеживаем, что курсор движется по "человечному" пути. Это то, что решает эта тема.

Почему если используем третий, не использовать и четвёртый? Трудность отслеживания и нагрузка. Тяжело отличить "правильный" путь от неправильного простыми способами. Вот курсор движется не по прямой - делаем преобразование Фурье и анализируем результат и исходник по десяткам признаков. В результате решаем процент похожести по нашим меркам.
Делать это нужно на сервере иначе нам подменят результат.
Опять же те, кто дошёл до данного этапа, до этого помимо предыдущих пунктов уже обязательно используют все современные способы по защите от парсеров, грабберов и прочих автоматов. Куки, проверка цифрового отпечатка, проверка цифрового отпечатка canvas (падла ещё та), проверка по спискам сайтов с прокси. Иначе смысла нет городить городульки.

Пункт 4 применяют в Google капча 'Я не робот'. Возможно крупные конторы Яндекс, Гугл. Часть помельче могут применять ограниченно, на этапах регистрации/авторизации/оплат.
Возможно используется сразу и 4.1

4.1 Отслеживаем изменение скорости передвижения курсора.

4.2 Микродвижения

Возможно и отслеживается вкупе со всем 4 пунктом, но отдельно использовать смысла мало. Вот нет микродвижений до/между/после прибытия курсора в заданную точку нам блокировать аккаунт? Собирать статистику и вынести решение позже? Поставить чувака 'на карандаш' включив ему другие способы контроля?
А если я с ноута сижу и мышь меня ломает подключать, управляю с тачпада. Там микродвижений практически и нет. По дыханию/сердцебиению уж точно.
Не можем точно классифицировать, значит не можем применять.

В большинстве случаев достаточно отсеять основную массу самыми простыми способами, на остальных забить, т.к. лучше пусть виновный будет не наказан, чем наказать невиновного.
« Last Edit: November 12, 2020, 10:36:12 AM by Vint »


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Можете, кстати, собрать статистику на эту тему, я с удовольствием посмотрю.

Это конечно не статистика, но прикинуть можно. Только сидеть записывать и анализировать
https://yadi.sk/d/7PqpjahHzRjHJQ

Общая тенденция такая: На старте нарастает скорость, на финише падает. На поворотах тоже всегда падает.
Скорость набирает на более-мение прямых участках. Я думал что не резкие повороты пролетаем на скорости, оказалось нет.

Ссылка на репозиторий с кодом на Python
https://bitbucket.org/Vintets/graphic_mouse/

На форумном сервере место закончилось.

« Last Edit: November 17, 2020, 06:18:45 PM by Vint »


Kashey

  • Зашел в гости
  • *
  • Posts: 10
    • View Profile
Интересные наблюдения. Однако, по скольку нет графика время - перемещение, то визуально по графикам нельзя их сопоставить.

Нагляднее было бы, если сюда добавить ещё и трёхмерный график с временем по оси х, по осям y и z - координаты мышки (x, y). Так можно было бы его наглядно сравнить его с другими графиками и увидеть, где именно скорость падает, а где нарастает.

Или можно раскрасить точки первого графика в градиент синий - красный в зависимости от скорости, ускорения.

Интересно было бы посмотреть график ускорения в зависимости от угла поворота и от начала - конца пути.


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Т.к. отсчёты по времени не регулярные (просто пишу с возможной скоростью, потом выкидываю дубли по координатам) то график ускорения нам ничего не даёт к сожалению. Ещё он не даёт, потому, что значения расстояний очень маленькие. В итоге замер всегда показывает цикличное ускорение-замедление из-за джиттера. Надо его совсем убрать.

Но отсчёты примерно через одинаковое время. Поэтому на первом графике чем плотнее точки, тем меньше скорость. Я сопоставлял так. Хотел тоже сначала ещё сделать время - перемещение но что это даст? Он будет отражением скорости, просто кривая будет всегда расти, но с разным наклоном. Неинформативно.

Трёхмерный - очень интересная мысль.


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Сделал комбинацию, трёхмерный с градиентом синий - красный в зависимости от скорости.

Только 3D (включено в версии на битбакете)



Или 3D + путь + скорость (в гите есть, но выключено)



Лучше скачать скрипт и повертеть графики руками.
https://youtu.be/M2Qgn7V_3RQ