Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - ya12

Pages: 1 ... 9 10 [11]
151
На просторах интернета нашел более изящную идею.

Определяется так. Предположим, у нас есть 3 точки: А(х1,у1), Б(х2,у2), С(х3,у3). Через точки А и Б проведена прямая. И нам надо определить, как расположена точка С относительно прямой АБ. Для этого вычисляем значение:
D = (х3 - х1) * (у2 - у1) - (у3 - у1) * (х2 - х1)
- Если D = 0 - значит, точка С лежит на прямой АБ.
- Если D < 0 - значит, точка С лежит слева от прямой.
- Если D > 0 - значит, точка С лежит справа от прямой.

Взято здесь:
Готовая формула - http://www.cyberforum.ru/delphi-beginners/thread652199.html
Теоретическое обоснование - https://habrahabr.ru/post/148325/

152
Что не удачный не спорю. Но пока все баги выловишь...
Если ушел в бесконечный цикл да еще и с нажатиями клавиш приходится жеско останавливать и может вылететь клава.

153
В при включенном режиме PS/2 иногда зависает клава. Т.е. жму клавиши, а реакции нет. Это происходит если принудительно остановить скрипт, где используются продолжительные нажатия клавиш. Простые клики не желательно использовать из-за защиты.

1 Можно ли восстановить работу клавиатуры без перезагрузки компьютера.
2 Можно ли внести изменения в Кликерман, что бы при остановке скрипта отпускал все нажатые клавиши на клавиатуре и мышке.

154
CASE больше нет, переменные используется только в этом потоке, дочерние потоки запускаются только здесь. По логам значение переменной $_gnom_b изменяется в CASE("gnom_b-1"), при том что каталог называется gnom_b-0.

Переписал на IF и глюк пропал.

155
Пока скрипт был маленький работал так: раз в 5 сек искал в каталоге ini каталог с маской gnom_b* (возможные значения * 0 и 1), а с увеличением объема скрипта CASE сломался и в не зависимости от SWITCH($arr2[$ia2]), выбирается последний CASE в списке.  Т.е. CASE("gnom_b-1"). Если его закоментировать выберется $_gnom_b = 0

Code: (clickermann) [Select]
THREAD(gnom_b, 0) //вкл-выкл гнома
UNDEFINE($arr2)
getdirlist($arr2, "ini\gnom_b*")
for($ia2=0, $ia2< arrsize($arr2))
   print($_gnom_b," ",$ia2," ",$arr2[$ia2])
   
   SWITCH($arr2[$ia2])       
   CASE("gnom_b-0")    //база
      $_gnom_b = 0
   CASE("gnom_b-1")    //в бой
      $_gnom_b = 1
   END_SWITCH
end_cyc

print($_gnom_b," ",$_gnom_b2)

if(($_gnom_b=1)&($_gnom_b2=0))  //вперед по точкам
   $_gnom_b2 = 1
   halt
   SETTHREAD(boy, 1) // 0 - Пауза, 1 - Старт, 2 - Стоп
   SETTHREAD(vpered, 1)
END_IF

wait(5)
END_THREAD

156
Большое спасибо.

PS Игра 3D, вид от 3-го лица. Есть текущие координаты геодаты перса, камеры в игре и контрольной точки. Есть расчет угла поворота и дальность до контрольной точки в координатах геодаты. По экспериментальным данным на сайте planetcalc.ru/5992/ построена логарифмическая функция зависимости дистанции в геодате от координат по оси Y куда кликнул мышкой на экране.

PS2   FOR($i_ln=2,$i_ln<3000,2)   ->  при  ln 1000 дает точность до 3 знака после запятой - то что надо.


 

157
Если идей как взять логарифм нет, придется считать через кубическую регрессию. У нее до 1000 условных единиц геодаты погрешность меньше.

158
Переписываю бота на мышиное управление. Для пересчета геодаты игры в экранные координаты мыши требуется взять натуральный логарифм. Как посчитать средствами кликера?

159
MOVER (rx, ry) не подходит. У меня только 1 PS/2 порт на нем висит клава. Если не использовать PS/2 режим, через некоторое время защита с сервера выкинет.

PID по HWND прикручу, когда все части скрипта соберу вместе.

БА зависит от адреса загруженной DLL. Средствами кликера адрес загруженной DLL не получить. К тому же между БА и адресом структуры хранящей координаты находятся 2 смещения представляющие индексные массивы. У каждого персонажа свои смещения. Цифры не большие поэтому поиск выдает тысячи адресов. Ну и защита не спит. Бряки поставленные на адреса начинающиеся с 00 зачастую приводят к отключению от сервера.
До телепортации по адресу 102D19F0 лежит адрес начала структуры. После загрузки персонажа один раз получить содержимое адреса, а потом уже не важно.

160
Code: (clickermann) [Select]
//Скрипт осуществляет перемещение персонажа (стрелки вперед и поворот вправо-влево) по контрольным точкам в 3Д игре с видом от 3го лица
//координатная сетка: слева -X, cправа +X, сверху -Y, снизу +Y
//адреса в памяти программы тип hex; X,Y - координаты тип float
//$_Sx,$_Sy - координаты камеры от 3го лица
//$_Ax,$_Ay - текущие координаты персонажа
//$_Bx,$_By - координаты текущей контрольной точки

#ps2_keyboard
// отключить NumLock (Кликер с включенным глючит)
#include "float.cms"     //подключение процедуры переводящей hex 4 байта во float 4 байта
#include "azimut.cms"    //вызятие азимута
wait(1)
$_ms1g =  1.02 * 6684 / 360   //поворот  (1.02 - поправочный коэф; 6684 - время в мс за которое персонаж повернется на 360 градусов)

EXECUTE("pid.exe") //получение PID игры и запись в Find_PID.ini(привязка по названию окна)
WAIT(2)
$_pid = INT(INIREAD("Find_PID.ini", "pid"))
$_addr = readmem($_pid, 0x102D19F0, 4) //не базовый адрес, но некоторое время начальный адрес здесь храниться
$_addrX = $_addr + 0x000003E0          //Х координаты перса в HEX
$_addrY = $_addr + 0x000003E4          //y
$_addrXs = $_addr + 0x00000950         //х координаты камеры от 3-го лица
$_addrYs = $_addr + 0x00000954         //у

$_a025 = RND(200,220)   //время минимально возможной задержки
$_a1 = RND(1000,1100)

KEYDOWN(#TAB)    //что бы можно было стрелками управлять персонажем
waitms($_a025)
KEYUP(#TAB)
waitms($_a025)

KEYDOWN(#TAB)
waitms($_a025)
KEYUP(#TAB)
waitms($_a025)

KEYDOWN(#UP)        //сразу после загрузки (по адресу в памяти) координаты персонажа 0, после короткой пробежки сервер пересылает текущие координаты
waitms($_a025)
KEYUP(#UP)
waitms($_a01)

$_ks = TFCOUNT("loc.txt") + 1   
FOR($_loc = 1, $_loc < $_ks, 2) 
   $kl = 1
   $_Bx =  INT(TFREAD("loc.txt", $_loc))            //чтение координат текущей контрольной точки
   $_By =  INT(TFREAD("loc.txt", ($_loc + 1)))
   WHILE($kl = 1)
      $_Ax = readmem($_pid, $_addrX, 4)           //чтение координат текущей координаты перса
      int_to_Float($_Ax)
      $_Ax = int($float)
     
      $_Ay = readmem($_pid, $_addrY, 4)
      int_to_Float($_Ay)
      $_Ay = int($float)
     
      $_Sx = readmem($_pid, $_addrXs, 4)                  ////чтение координат камеры от 3го лица
      int_to_Float($_Sx)
      $_Sx = int($float)
     
      $_Sy = readmem($_pid, $_addrYs, 4)
      int_to_Float($_Sy)
      $_Sy = int($float)
     
      azimut($_Ax,$_Ay,$_Bx,$_By)  //взятие азимута с текущей координаты перса на текущую контрольную точку
      $_AzAB = $angle               
      $_Dab = $_Dt1t2              //дистанция до контрольной точки
     
      azimut($_Sx,$_Sy,$_Ax,$_Ay)  //взятие азимута с координаты камеры от 3го лица на текущуие координаты перса
      $_AzSA = $angle
     
      $_deltaAz = abs($_AzSA - $_AzAB)  //дельта между азимутами
     
      if (($_AzSA < $_AzAB) and ($_deltaAz < 180)  //какой поворот ближе туда и повернет навычесленный угол
         KEYDOWN(#RIGHT)
         waitms(int(($_deltaAz) * $_ms1g))
         KEYUP(#RIGHT)
      END_IF
      if (($_AzSA > $_AzAB) and ($_deltaAz < 180)
         KEYDOWN(#LEFT)
         waitms(int(($_deltaAz * $_ms1g))
         KEYUP(#LEFT)
      END_IF
      if (($_AzSA > $_AzAB) and ($_deltaAz >= 180)
         KEYDOWN(#RIGHT)
         waitms(int((360 - $_deltaAz) * $_ms1g))
         KEYUP(#RIGHT)
      END_IF
      if (($_AzSA < $_AzAB) and ($_deltaAz >= 180)
         KEYDOWN(#LEFT)
         waitms(int((360 - $_deltaAz) * $_ms1g))
         KEYUP(#LEFT)
      END_IF
     
      IF ($_Dab > 50)        //50 - минимальная дистанция до контрольной точки, после достижения которой можно получить новую
         KEYDOWN(#UP)
         waitms(int($_Dab / 0.14))  //(бег) 0.14 - скорость(точки в мс), при паспортной скорости перса в 129 (0.185-170?)
         KEYUP(#UP)
         $kl = 1
      else
         $kl = 0
      end_if
     
      waitms($_a1)
   END_CYC
END_CYC

halt

Vint - автор идеи с расчетом азимута (с геометрией у меня не очень процедуру переписал чтоб понятней было)

Code: (clickermann) [Select]
SUB(azimut,$t1x,$t1y,$t2x,$t2y) //=============================================

      $_Dt1t2 = DIST($t1x,$t1y,$t2x,$t2y)
      $_Dt1az = DIST($t1x,$t1y,$t1x,$t2y)
      $_Dt2az = DIST($t2x,$t2y,$t1x,$t2y)

      if ($_Dt1t2 = 0)   //на 0 делить нельзя, может кто предложит более изящную идею
$_Dt1t2 = 0,1
      end_if
      if ($_Dt1az = 0)
$_Dt1az = 0,1
      end_if

      $_DV = POW($_Dt1az, 2) + POW($_Dt1t2, 2) - POW($_Dt2az, 2)
      $_DN = 2 * $_Dt1t2 * $_Dt1az

      $beta = arccos($_DV / $_DN)

      if (($t1x > $t2x) and ($t1y > $t2y))
         $angle = 360 - $beta
       end_if
      if (($t1x <= $t2x) and ($t1y >= $t2y))
         $angle = $beta
       end_if
       if (($t1x < $t2x) and ($t1y < $t2y))
         $angle = 180 - $beta
       end_if
       if (($t1x > $t2x) and ($t1y < $t2y))
         $angle = 180 + $beta
       end_if
END_SUB


dramster - автор процедуры перевода HEX 4 байта во FLOAT 4 байта

Code: (clickermann) [Select]
    //перевод числа в двоичную строку $BIN  (строка выйдет длиной в 32бит)
    SUB(dec_to_BIN, $DEC)
       $BIN = ""
     
       IF($DEC > 0)   //если положительное
          WHILE($DEC > 0)
             $DEC = $DEC/2
             IF($DEC > int($DEC))
                $BIN = STRCONCAT("1", $BIN)
             else
                $BIN = STRCONCAT("0", $BIN)
             END_IF
             $DEC = int($DEC)
          END_CYC
          WHILE(STRLEN ($BIN) < 32)       //4 байта
             $BIN = STRCONCAT("0", $BIN)
          END_CYC
       ELSE               //если отрицательное
          $DEC = abs($DEC+1)
          WHILE($DEC > 0)
             $DEC = $DEC/2
             IF($DEC > int($DEC))
                $BIN = STRCONCAT("0", $BIN)
             else
                $BIN = STRCONCAT("1", $BIN)
             END_IF
             $DEC = int($DEC)
          END_CYC
          WHILE(STRLEN ($BIN) < 32)       //4 байта
             $BIN = STRCONCAT("1", $BIN)
          END_CYC
       END_IF
     
    END_SUB
     
     
    //перевод из двоичной строки в десятичное число $DEC
    SUB(bin_to_DEC, $BIN_str)
       $DEC = 0
       IF(ARRSIZE ($arr) = 0)
          $num_arr = 1
          FOR($i=0,$i<32)
             arrpush($arr, $num_arr)
             $num_arr = $num_arr*2
          END_CYC
       END_IF
     
       FOR($i=0,$i < STRLEN($BIN_str))
          $DEC = $DEC + ($arr[$i]*int(STRCUT($BIN_str, STRLEN($BIN_str)-$i, 1)))
       END_CYC
    END_SUB
     
    //перевод из целочисленного в дробное $float. целочисленное 4 байт -  long (Signed int) от -2147483648 до 2147483647
    SUB(int_to_Float, $int_in)
     
       dec_to_BIN($int_in)
     
       bin_to_DEC(STRCUT ($BIN,2, 8))
       $exp = $DEC   //экспонента в десятичном
     
       bin_to_DEC(STRCUT ($BIN,10, 32))
       $mant = $DEC   //мантиса в десятичном
     
       $float =  POW(-1,int(STRCUT ($BIN,1,1))) * pow(2,$exp-127) * (1+($mant/POW(2,23)))
     
    END_SUB
     
    ///////////////////////////////////////////////////////////////////////////////
    //основной код
     
   // int_to_Float(-979615744)
   // print($float)  //  -5000


Скрипт записывающий в файл loc.txt координаты контрольных точек

Code: (clickermann) [Select]
//ALT - запись X,Y координат контрольной точки
//ESC - выход
#name "loc"
#ps2_keyboard

$_sp = 0
$_pid = 0

THREAD(T1, 0)  //поток считывающий координаты из памяти процесса и записывающий их в файл loc.txt
   #include "float.cms"
   
   $_Ax = readmem($_pid, $_addrX, 4)
   $_Ay = readmem($_pid, $_addrY, 4)
   IF($_sp = 1)   
      int_to_Float($_Ax)
      TFWRITE("loc.txt", int($float))
     
      int_to_Float($_Ay)
      TFWRITE("loc.txt", int($float))
      $_sp = 0
   END_IF
   
   WAIT(1)
END_THREAD

THREAD(T2, 0)  //поток обрабатывающий нажатие клавиш
   IF(iskeydown(#ALT)=1)
      $_sp = 1
   END_IF
   IF(iskeydown(#esc)=1)
      halt
   END_IF
   
   waitms(200)
END_THREAD

EXECUTE("pid.exe") //получение PID и запись его в файл Find_PID.ini
WAIT(2)
$_pid = INT(INIREAD("Find_PID.ini", "pid"))
$_addr = readmem($_pid, 0x102D19F0, 4)
$_addrX = $_addr + 0x000003E0
$_addrY = $_addr + 0x000003E4

SETTHREAD (T1, 1)
SETTHREAD (T2, 1)
wait(600000)


Поиск Базового Адреса осуществлен в Cheat Engine. Средствами Кликера до БА добраться не смог, нашел адрес в памяти где указатель на начало структуры некоторое время храниться.
PID.exe сделан в AutoIT

161
Спасибо. Я наконец выспался и прозрел, что ищу не тот угол и для чего нужен азимут.

162
Координатная сетка слева на право от -х до +х. С верху вниз от -y до +y.
Формула вычисляющая угол между векторами не позволяет получить угол больше 180 градусов.
Потому что cos(270)=x существует, а arccos(х)=270 не существует.

Code: (clickermann) [Select]
     
//Axy - координаты начальной точки перса
//Bxy - координаты конечной точки куда надо прийти
//Cxу - координаты случайной точки куда прибежит перс за 1 сек
//Формула вычисляющая угол между векторами
$_ABx = $_Bx - $_Ax
$_ABy = $_By - $_Ay
$_ACx = $_Cx - $_Ax
$_ACy = $_Cy - $_Ay
$_ABAC =  $_ABx*$_ACx+$_ABy*$_ACy
$_ABAC2=(SQRT(($_ABx*$_ABx)+($_ABy*$_ABy)))*(SQRT(($_ACx*$_ACx)+($_ACy*$_ACy)))
$_ugol = ARCCOS($_ABAC/$_ABAC2)  //всегда от 0 до 180 градусов

163
Управление стрелками(#LEFT, #UP, #RIGHT, #DOWN) не работает пока включен NumLock(так же как на цифровой клавиатуре).

164
Огромное спасибо.
Пойду допилю автопилот.

165
Считываю координаты из процесса игрушки. READMEM возвращает целые числа. Как пересчитать в 4 байта с точкой.

Для примера:
в игре y=-5000.00   получаю -979615744, бегу на север(т.е. x не изменяется)
в игре y=-6000.00   получаю -977567744.

Pages: 1 ... 9 10 [11]