Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 17.12.2010, 14:01
Inkvisitor Inkvisitor вне форума
Прохожий
 
Регистрация: 17.12.2010
Сообщения: 7
Репутация: 10
По умолчанию Бот для клиентской MMORPG

Здравствуйте, у меня возникла необходимость написать в сжатые сроки бот для одной MMORPG (1-2 недели, возиться дольше не вижу смысла), чисто из спортивного интереса и для личного пользования.
Однако собственных знаний для этого, мягко говоря, недостаточно. В наличии школьный курс по Pascal и основам ООП на Delphi, имею некоторые представления о синтаксисе языка С (но только, в сравнении с Pascal).
Попробовал пошариться по тематическим форумам, но нарыл лишь самую общую информацию, требующую длительного усвоения, что не укладывается в рассчетные сроки.

MMORPG имеет клиент с 3D-интерфейсом.
Бот должен работать по следующей схеме:
1. Логировать все манипуляции пользователя с клавиатурой и мышью (перемещение игрока, выполнение действий, вращение камеры) в окне клиента в течении длительного времени (10-15 минут)
2. По команде, в точности воспроизводить действия пользователя из ранее записанного лога

Что, собственно, вызывает 2 вопроса:
1. Возможно ли вообще реализовать такую схему?
2. Каким инструментарием лучше воспользоваться?
Ответить с цитированием
  #2  
Старый 17.12.2010, 14:07
Аватар для alikoder
alikoder alikoder вне форума
Начинающий
 
Регистрация: 05.12.2007
Сообщения: 126
Репутация: 10
По умолчанию

Цитата:
Сообщение от Inkvisitor
Здравствуйте, у меня возникла необходимость написать в сжатые сроки бот для одной MMORPG (1-2 недели, возиться дольше не вижу смысла), чисто из спортивного интереса и для личного пользования.
Однако собственных знаний для этого, мягко говоря, недостаточно. В наличии школьный курс по Pascal и основам ООП на Delphi, имею некоторые представления о синтаксисе языка С (но только, в сравнении с Pascal).
Попробовал пошариться по тематическим форумам, но нарыл лишь самую общую информацию, требующую длительного усвоения, что не укладывается в рассчетные сроки.

MMORPG имеет клиент с 3D-интерфейсом.
Бот должен работать по следующей схеме:
1. Логировать все манипуляции пользователя с клавиатурой и мышью (перемещение игрока, выполнение действий, вращение камеры) в окне клиента в течении длительного времени (10-15 минут)
2. По команде, в точности воспроизводить действия пользователя из ранее записанного лога

Что, собственно, вызывает 2 вопроса:
1. Возможно ли вообще реализовать такую схему?
2. Каким инструментарием лучше воспользоваться?


дай угадаю.... линейка да?
много вас таких, сам когда то баловался, только смысл? уже полно ботов + исходники - юзай гугл, у меня лично на винте есть 3-4 бота.
с этим проблем нет ищи лучше!
Ответить с цитированием
  #3  
Старый 17.12.2010, 16:10
Inkvisitor Inkvisitor вне форума
Прохожий
 
Регистрация: 17.12.2010
Сообщения: 7
Репутация: 10
По умолчанию

Во-первых, не угадал... это даже не WoW. Игра новая и малоизвестная, на стади открытого бета-теста, ни о каких готовых ботах к ней никто и в помине не слышал, так что проще написать самому с учетом специфики интерфейса.
Во-вторых, надоело задрить на добыче ресов, она реализована таким образом, что через пару часов сам становишься похожим на бота, хочется нормально поиграть. Но без ресов далеко не уедешь, а свободного времени у меня не так много. Т.е. имеется индивидуально генерируемая локация где кроме персонажа и расставленных на СТРОГО ОТВЕДЕННЫХ местах ресов больше ничего нет - создание бота напрашивается само-собой.

Сейчас прикинул список логируемых действий обычного пользователя:
1. Нажатие клавиши клавиатуры - выполнение действия
2. Удержание клавиши клавиатуры - движение вперед/назад, круговое вращение камеры
3. Нажатие клавиши мыши - движение персонажа в точку позиционирования указателя, взаимодействие с объектом (это ключевое
действие бота)
4. Удержание клавиши мыши + движение указателя - свободное вращение камеры
5. комбо из удержания клава+клава, мышь+клава, мышь+мышь - передвижение персонажа

Задумался над логированием... особенно над п.5 и другими операциями с удержанием клавиш, порылся в интерфейсе клиента, пришел к выводу что все это можно заменить двумя операциями ввода данных:
1. Нажатие клавиши клавиатуры - выполнение действия, выставление вида камеры "по умолчанию" (вид со спины)
2. Нажатие клавиши мыши - перемещение персонажа, взаимодействие с объектом

Сложно для игрока, но зато легко залогировать по простейшему алгоритму:
1. RunTimer
2. нажатие клавиши -> запись времени и параметров клавиши
Ответить с цитированием
  #4  
Старый 17.12.2010, 17:12
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Глобальный хук на нужные сообщения, отсеивать по хендлу процесса. А потом - серии SendMessage. Я бы так делал
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #5  
Старый 26.12.2010, 01:58
Inkvisitor Inkvisitor вне форума
Прохожий
 
Регистрация: 17.12.2010
Сообщения: 7
Репутация: 10
По умолчанию

Все не было времени продолжить, два дня бегал по магазинам, собирал новый системник потом еще столько же возился с вин7, хоть она мне и не нравится (многие привычные программы плохо с ней совместимы), но х64 проц, 4гб оперативы и DX11 вынудили... да и на работе аврал.

За идею с хуками спасибо. Сильно помогло, т.к. не знал с чего вообще подступиться. Столкнулся было с одной проблемой, но пока описывал, дорубился как поискать ответ
Пойду терзать гугл...
Ответить с цитированием
  #6  
Старый 26.12.2010, 09:59
Аватар для EvilRussian
EvilRussian EvilRussian вне форума
Начинающий
 
Регистрация: 21.12.2010
Адрес: Россия, Красноярский край
Сообщения: 177
Репутация: 22
Восклицание

Товарищ! Не колупайте себе мозг!
Есть же волшебная штука AutoIt! Она как будто специально заточена для таких целей. Попробуй - понравится. Там всё легко и удобно.
__________________
Если не ты, то кто?
(с) Терри Пратчетт

Не забывайте ставить плюсы и говорить спасибо!
Ответить с цитированием
  #7  
Старый 26.12.2010, 12:07
Inkvisitor Inkvisitor вне форума
Прохожий
 
Регистрация: 17.12.2010
Сообщения: 7
Репутация: 10
По умолчанию

EvilRussian, а как ты думаешь, что проще: врубиться в совершенно незнакомый синтаксис и написать на нем код, или написать тот же код на известном синтаксисе?

Есть проблема при постановке хука:
Если ставить глобальный затык
Цитата:
BotHook:=SetWindowsHookEx(WH_KEYBOARD_LL or WH_MOUSE_LL,@BotLogger, HInstance, 0);
то лог пишется, но глобальный хук, это не слишком удобно, потому что при его остановке хук перехватывает нажатие кнопки "Стоп" и UnhookWindowsHookEx(BotHook) выдает ошибку

А затык по pID, который ищется таким способом:
Цитата:
HandleMainWindow:=FindWindow(Nil,'&MainWindowName& ');
ThreadId := GetWindowThreadProcessId(HandleMainWindow,@Process Id);
почему то не проходит. Где я туплю?
Ответить с цитированием
  #8  
Старый 26.12.2010, 12:20
Аватар для EvilRussian
EvilRussian EvilRussian вне форума
Начинающий
 
Регистрация: 21.12.2010
Адрес: Россия, Красноярский край
Сообщения: 177
Репутация: 22
Счастье

Inkvisitor, бот дельфяшный очень легко перехватывается, кроме того, его сложно писать.
Поскольку ботоводство в 80% онлайн-игр карается вечным баном, это не вариант.
AutoIt имитирует нафатия клавиш на клавиатуре и передвижения мыши, поэтому перехватить его практически невозможно.
Кроме того, на нём на написание понадобится только 40 минут, ну и часа 2 в крайнем случае на обучению коду (синтаксис несложен).

Ну и какие выводы?..
__________________
Если не ты, то кто?
(с) Терри Пратчетт

Не забывайте ставить плюсы и говорить спасибо!
Ответить с цитированием
  #9  
Старый 26.12.2010, 13:49
Аватар для v1s2222
v1s2222 v1s2222 вне форума
Продвинутый
 
Регистрация: 07.09.2010
Сообщения: 726
Репутация: 26711
По умолчанию

Тебе не надо все сообщения отлавливать. Отлавливай сообщения только нужного тебе процесса (то бишь игры), а все остальные сообщения винды просто игнорируй...
__________________
Помогаю за Спасибо
Ответить с цитированием
  #10  
Старый 26.12.2010, 14:55
Inkvisitor Inkvisitor вне форума
Прохожий
 
Регистрация: 17.12.2010
Сообщения: 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от EvilRussian
AutoIt имитирует нафатия клавиш на клавиатуре и передвижения мыши, поэтому перехватить его практически невозможно.
мой бот должен делать то же самое, но на делфи... логгер уже заработал, осталось накатать реплеер. Смысл переучиваться?

v1s2222
а я это и делаю, логгер уже ловит только то, что нужно, но глобально, без привязки к процессу

приложение имеет надцать скрытых окон (смотрел в WinSight), если ставить хук на хендл видимого окна или самого процесса, то он "слепнет" и выдает пустой лог.
Ответить с цитированием
  #11  
Старый 26.12.2010, 16:51
Аватар для v1s2222
v1s2222 v1s2222 вне форума
Продвинутый
 
Регистрация: 07.09.2010
Сообщения: 726
Репутация: 26711
По умолчанию

Делай хук на ThreadID, соответственно все окна, видимые и не видимые будут отлавливаться... кстати, если читать справку по функции SetWindowsHookEx, то там сказано, что функция должна находиться в библиотеке.
Вот пример задания хука для приложения:
Код:
//библиотека
library Hook;
uses Windows, SysUtils;
const
  crlf = #$0D#$0A;
Var
 logfile    : string = 'D:\log.txt';
 Hook       : dword;
 dwThreadId : dword;
 cFile      : dword;

Function kWriteFile(
    hFile:THANDLE;
    lpBuffer:Pointer;
    nNumberOfBytesToWrite:DWORD ;
    lpNumberOfBytesWritten:LPDWORD;
    lpOverlapped:pointer ):boolean; stdcall; external 'kernel32.dll' name 'WriteFile';
Function kReadFile(
    hFile:THANDLE;
    lpBuffer:Pointer;
    nNumberOfBytesToRead:DWORD ;
    lpNumberOfBytesReaden:LPDWORD;
    lpOverlapped:pointer ):boolean; stdcall; external 'kernel32.dll' name 'ReadFile';

Function FindWnd (pWndCaption: PChar) : boolean;
var
 w : dword;
begin
 result := false;
 w := FindWindow(nil,pWndCaption);
 if w = 0 then exit;
 dwThreadID := GetWindowThreadProcessId(w,nil);
 if dwThreadId <> 0 then result := true;
end;

procedure LibraryProc(Reason: Integer);
begin
 if (Reason = DLL_PROCESS_ATTACH) or (Reason = DLL_THREAD_ATTACH) then
  begin
   cFile := CreateFile(PChar(logfile),GENERIC_WRITE or GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_ALWAYS,FILE_ATTRIBUTE_HIDDEN,0);
  end else CloseHandle(cFile);
end;

function CbtProc(code: integer; wparam: integer; lparam: integer):Integer; stdcall;
var
 written : dword;
 cFileSizeLow,cFileSizeHi : integer;
 sBuf : string;
begin
 if code < 0 then result := CallNextHookEx(Hook,code,wParam,lparam) else
  begin
   cFileSizeLow := GetFileSize(cFile,@cFileSizeHi);
   SetFilePointer(cFile,cFileSizeLow,@cFileSizeHi,FILE_BEGIN );
   sBuf := ParamStr(0)+': code = '+IntToStr(code)+' wparam = '+IntToStr(wParam)+' lparam = '+IntToStr(lParam)+crlf;
   kWriteFile(cFile,PChar(sbuf),length(sBuf),@written,nil);
   Result:=0;
  end; 
end;

Function InstallHook (pWndCaption: PChar): boolean;
begin
 result := false;
 if not(FindWnd(pWndCaption))  then   exit;
 if not(ForceDirectories(ExtractFilePath(logfile))) then exit;
 Hook := SetWindowsHookEx(WH_CBT,@CbtProc,HInstance,dwThreadId);
 result := Hook <> 0;
end;

Function UnInstallHook: boolean;
begin
 result := false;
 CloseHandle(cFile);
 if Hook <> 0 then result := UnhookWindowsHookEx(Hook);
end;

exports
 InstallHook name 'InstallHook',UnInstallHook name 'UnInstallHook';
begin
 DLLProc := LibraryProc;
end.
Код:
// и сама программа
...
Function InstallHook  (pWndCaption: PChar): boolean; external 'Hook.dll';
Function UnInstallHook: boolean; external 'Hook.dll';
...

procedure TForm1.Button1Click(Sender: TObject);
begin
if InstallHook('Блокнот') then ShowMessage('Installed');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if UnInstallHook then ShowMessage('Uninstalled');
end;
__________________
Помогаю за Спасибо
Ответить с цитированием
  #12  
Старый 27.12.2010, 00:16
Inkvisitor Inkvisitor вне форума
Прохожий
 
Регистрация: 17.12.2010
Сообщения: 7
Репутация: 10
По умолчанию

v1s2222, спс за листинг, по сути - то же, что и у меня, но смысла упаковывать все обработчики в отдельную библиотеку я лично не вижу...
попытка поставить хук на ThreadID, ни к чему хорошему не приводит, как и на processID или хендл любого скрытого окна клиента. Работает только глобальный хук: "0";
Из него как-нибудь можно выцепить хендл процесса, которому передавалось ссбытие?
Ответить с цитированием
  #13  
Старый 27.12.2010, 01:08
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
но смысла упаковывать все обработчики в отдельную библиотеку я лично не вижу...
вообще-то обычно винда работает нормально ТОЛЬКО с хуками, которые в DLL
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #14  
Старый 04.01.2011, 00:17
Inkvisitor Inkvisitor вне форума
Прохожий
 
Регистрация: 17.12.2010
Сообщения: 7
Репутация: 10
По умолчанию

Bargest, ну у меня хуки и без дллки ловят необходимый минимум событий.
Проблема сейчас в другом: я не знаю, куда посылать сообщения из лога.
Получается, что по хендлу главного окна обрабатываются только события интерфейса - хоткеи различных окон и хоткеи панели действий. Т.е. я могу залезть в инвентарь или заюзать скил, но не могу перемещать персонажа мышью или выделить цель хоткеем.
Поэтому у меня возникла пара вопросов на которые я икак не найду внятного ответа:
1. Можно ли в обработчике хука получить хендл окна, которому адресовано событие?
2. Как получить хендлы всех дочерних окон главного окна?


P.S. и да... я уже пытался отсылать сообщения по хендлам процесса и потока.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 11:08.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025