PDA

Просмотр полной версии : [Помогите!] Узнать ХП у таргет-моба


trixicus
30.10.2011, 22:56
Добрый вечер. Помогите пожалуйста реализовать получение ХП у таргет-моба. Пока написал только это:

function GetMobInfo: TMobInfo;
var
BytesCount: DWORD;
Mobs,id: DWORD;
i,j : integer;
begin
ReadProcessMemory(hProcess, ptr(GA), @Mobs, sizeof(Mobs), BytesCount);
ReadProcessMemory(hProcess, ptr(Mobs+$8), @Mobs sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$24), @Mobs, sizeof(Mobs), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$18), @Mobs, sizeof(Mobs), BytesCount);
//----------------- Именно здесь и должно быть получение
end;

Так же отдельно получаю TargetID для персонажа:
ReadProcessMemory(hProcess, ptr(GA+$B68), @ID, sizeof(ID), BytesCount);

HellD
30.10.2011, 23:37
ReadProcessMemory(hProcess, ptr(GA), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$1c), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$24), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$18), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+I*4), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$4), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$11c), @MobId, sizeof(MobId), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$12c), @MobHp, sizeof(MobHp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$16c), @MobMHp, sizeof(MobMHp), BytesCount);


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



и, кстати, поправь таргет GA+34+B68

trixicus
31.10.2011, 00:06
for j := 0 to 5 do
for i := 0 to 768 do begin
ReadProcessMemory(hProcess, ptr(GA), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$1c), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$24), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$18), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+I*4), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$4), @MobsTemp, sizeof(MobsTemp), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$11c), @MobId, sizeof(MobId), BytesCount);
ShowMessage(IntToStr(MobId));
ReadProcessMemory(hProcess, ptr(MobsTemp+$12c), @Result.HP, sizeof(Result.HP), BytesCount);
ReadProcessMemory(hProcess, ptr(MobsTemp+$16c), @Result.MaxHP, sizeof(Result.MaxHP), BytesCount);
end;

MobID всегда равен 4949149, вне зависимости от того какие мобы (и сколько) находятся рядом.

Вопрос 1:
ReadProcessMemory(hProcess, ptr(MobsTemp+$1c), @MobsTemp, sizeof(MobsTemp), BytesCount);
Зачем эта строчка, если и так уже используется Game Adress

Вопрос 2:
GA +8 +24 +18 +[I*4] + (+0)^J +4: (I in [0..300])
Надо ли MobsTemp+$8

и, кстати, поправь таргет GA+34+B68
Сие досадное недоразумение допущено при отправке на форум, в коде все в порядке:)

Прикрепил файл проекта

HellD
31.10.2011, 00:38
по первому и второму вопросу... ответ один )) +1С теперь вместо +8... как итог, +1С надо(и никакого отношение к BA+1C это не имеет), а +8, наоборот, не надо)
то есть другими словами:

GA +1с +24 +18 +[I*4] + (+0)^J +4: (I in [0..300])


MobID всегда равен 4949149

тут сложно помочь... либо прикрепи обновленный архив.. потому что код в нем и код тут различны... либо сам проверь, что все оффсеты правильно прописал... проектик, честно, не запускал, тока в блокноте пролистал... но WIDы всех вокруг, по твоему коду (от сюда, а не из архива) у меня получил на ура...

trixicus
31.10.2011, 11:11
Все, эту проблему решил. Теперь осталось узнать только ХП пета для полного счастья. Точнее максимальное ХП.
Пробовал получить по GA+34+1068+i*4+10+1C (%ХП), но возвращается совсем не то; оффсеты случаем не менялись?

Получение текущего ХП:

ReadProcessMemory(hProcess, ptr(gamer_addr + $1068), @addr, sizeof(addr), BytesCountOfRead);
ReadProcessMemory(hProcess, ptr(addr + 8), @i, sizeof(i), BytesCountOfRead);
if i <> (-1) then begin
ReadProcessMemory(hProcess, ptr(addr+i*4+$10), @addr, sizeof(addr), BytesCountOfRead);
ReadProcessMemory(hProcess, ptr(addr+$38), @addr, sizeof(addr), BytesCountOfRead);
ShowMessage(IntToStr(addr)) ;
end;

krysun
31.10.2011, 12:08
Вот мой пример с перебором. Правда я просто получал список мобов, но добавил сравнение с вашим таргетом.

//************************************************** ***************************
// Читаем WideString по адресу (имена мобов, ресов etc.)
function getWideString(hProc, data: dword): string;
var
i,rw: dword;
ch: widechar;
wch: array [0..255] of widechar;
str: string;
begin
i:=0;
repeat
ReadProcessMemory(hProc,ptr(data),@ch,2,rw);
data:=data+2;
wch[i]:=ch;
inc(i);
until (ord(ch)=0) or (i>=255);
//Перегоняем имя с массива в строку
i:=0;
str:='';
repeat
str:=str+wch[i];
inc(i);
until wch[i]='';
//возвращаем строку
Result:= str;
end;
//************************************************** ***************************
procedure GetMobList;
var
d1,d2,rw,mobFlag:dword;
N,Key,List:dword;
i: integer;
mobnameptr:dword;
mobNameStr:string;
CurHP, HP, wID, targetWID: dword;
begin
//Получаем хэш ключ и начало списков
form1.CheckListBox1.Clear; //кинем на форму CheckListBox (или Memo, на ваше усмотрение)
ReadProcessMemory(hProcess, ptr(base_add), @Key, sizeof(Key), rw);
ReadProcessMemory(hProcess, ptr(Key+$1C), @Key, sizeof(Key), rw);
//Читаем свой таргет
ReadProcessMemory(hProcess, ptr(Key+$34), @targetWID, sizeof(targetWID), rw);
ReadProcessMemory(hProcess, ptr(targetWID+$B68), @targetWID, sizeof(targetWID), rw);
//Продолжаем работу с хэш
ReadProcessMemory(hProcess, ptr(Key+$1c), @Key, sizeof(Key), rw);
ReadProcessMemory(hProcess, ptr(Key+$24), @Key, sizeof(Key), rw);
ReadProcessMemory(hProcess, ptr(Key+$18), @List, sizeof(List), rw);
ReadProcessMemory(hProcess, ptr(Key+$24), @Key, sizeof(Key), rw);
// i:=0;
for n:=0 to Key-1 do
begin
ReadProcessMemory(hProcess, ptr(List+$4*N), @d1, sizeof(d1), rw);
while d1<>0 do
begin
ReadProcessMemory(hProcess, ptr(d1+$4), @d2, sizeof(d2), rw);
ReadProcessMemory(hProcess, ptr(d2+$B4), @mobFlag, sizeof(mobFlag), rw);
ReadProcessMemory(hProcess, ptr(d2+$254), @mobnameptr, sizeof(mobnameptr), rw);
mobNameStr:=GetWideString(hProcess,mobnameptr); //Имя моба/нпс/пета
{Вывод в CheckListBox}
{ if (mobFlag=7) then //Если NPC
begin
form1.MobList.Items.Add('[npc] : '+mobNameStr);
end; }
if (mobFlag=6) then //Если моб
begin
ReadProcessMemory(hProcess, ptr(d2+$11C), @wID, sizeof(wID), rw);
if (wID=TargetWID) then
begin
ReadProcessMemory(hProcess, ptr(d2+$12C), @CurHP, sizeof(CurHP), rw);
ReadProcessMemory(hProcess, ptr(d2+$16C), @HP, sizeof(HP), rw);
form1.CheckListBox1.Items.Add(mobNameStr+' [HP:'+inttostr(hp)+']');
end;

end;
{ if (mobFlag=9) then //Если пет
begin
ReadProcessMemory(hProcess, ptr(d2+$12C), @CurHP, sizeof(CurHP), rw);
ReadProcessMemory(hProcess, ptr(d2+$16C), @HP, sizeof(HP), rw);
form1.MobList.Items.Add('[pet] : '+mobNameStr+' [HP:'+inttostr(hp));
end; }
ReadProcessMemory(hProcess, ptr(d1), @d1, sizeof(d1), rw);
end;
end;
end;

Исходник с получением списка мобов, нпс, петов, ресурсов, лута и игроков прикрепляю. Борода, но может пригодится.

По ссылке ниже описан "Доступ к элементам списка БЕЗ Циклов".

[Ссылки могут видеть только зарегистрированные и активированные пользователи] 0%BC-%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0-%D0%B1%D0%B5%D0%B7-%D1%86%D0%B8%D0%BA%D0%BB%D0%BE%D0%B2.193/

HellD
31.10.2011, 14:23
Пробовал получить по GA+34+1068+i*4+10+1C (%ХП), но возвращается совсем не то

Оффсеты верные, просто там тип данных single )) скорей всего именно это ты и не учел )) обозначь переменную так же, и получишь то что надо )) 1-пет здоров, 0.99999..9 пета ранили )) ну а как имея текущее и процент получить макс хп, думаю догадаешься )) простая математика ))

trixicus
01.11.2011, 01:57
Все написал, спасибо огромное. Кстати, не поможешь исходником инжекта по сбору лута.
А то я ни подбежать ни просто взять не могу. Игра с клиент с критом валится.

HellD
01.11.2011, 16:59
Все написал, спасибо огромное. Кстати, не поможешь исходником инжекта по сбору лута.
А то я ни подбежать ни просто взять не могу. Игра с клиент с критом валится.

[Ссылки могут видеть только зарегистрированные и активированные пользователи]

в чем проблема? ))

trixicus
01.11.2011, 17:39
хех, совершенно не заметил ее. А проблема в том, что у меня не так работает определение типа лута:
+14C ItemType (1 - Money; 2 - Mine; Other - Item)

1 - все кроме монет
2 - растения и пр.
3 - только монеты

Лут он отображает весь, который найдет. Мне же нужен только свой.
И еще не могу определить, поднял он вещь или нет, и в какой момент уже можно бежать за следующей. Вот:)

aktivizion15
01.11.2011, 18:29
Лут он отображает весь, который найдет. Мне же нужен только свой.
И еще не могу определить, поднял он вещь или нет, и в какой момент уже можно бежать за следующей.

Сделай функцию которая бы возвращала wid лута, конечно отсеивая по координатам смерти моба в определенном радиусе.
И через цикл
while loot <> 0 then
//и тут собираем его же
PickWalk(loot)

trixicus
01.11.2011, 18:37
Это все безусловно хорошо, если бы не парачка "НО":
- в этом месте где мы убили моба, могут оказаться и чужой лут, который попадет в этот радиус.
while loot <> 0 then PickWalk(loot)
- быстренько все переберет и побежит за последним. Поэтому и нужно определить взяли мы вещь или нет

PS: Скорее всего клиент автоматически выгружает из памяти WID того объекта, который мы взяли. Поэтому можно ждать пока WID не пропадет из списка, но какова вероятность, что он не появится снова от фармящих рядом.

А зная я список только своего лута, я мог бы сравнить просто 2 списка, ДО и После убийства моба, и определить WID-ы того, что мне надо поднять

aktivizion15
01.11.2011, 18:44
быстренько все переберет и побежит за последним
Ну у меня возвращает первое найденное соответствие, теотсь пока не возьму его, не пойдет дальше, топорно, но работает, радиус под мобом метров 5-ть, да старается брать и чужой, но это же не сильная проблема, можно решить занося во временный черный список того что неберется в течении некоторого времени, а после удалять

trixicus
01.11.2011, 19:20
Сейчас потестил. Действительно собирает по порядку. Цикл отрабатывает моментально, как я и предполагал, но выражаясь вольным языком, "запросы встают в очередь" и бот бегает собирает лут. Осталось только заставить его собирать лут около места смерти моба, но я, признаюсь, понятия не имею как это сделать

aktivizion15
01.11.2011, 21:13
Осталось только заставить его собирать лут около места смерти моба, но я, признаюсь, понятия не имею как это сделать
Не буду давать готовое)
У меня сделано так:
Дополнительно крутится поточег на получение координат моба, тоетсь пока моб в таргете пишем его координаты, после смерти запись прерывается и я собираю лут в пределах радиуса этих координат

if id = TargetID then
begin
ReadProcessMemory(ProcessID, Pointer(struct_ + $3C), @x, 4, num);
ReadProcessMemory(ProcessID, Pointer(struct_ + $44), @y, 4, num);
ReadProcessMemory(ProcessID, Pointer(struct_ + $40), @z, 4, num);
last_x := x;
last_y := y;
last_z := z;
end;



function getdistanceloot(x2, y2: single): integer;
begin
getcord;
result := round(sqrt(sqr(last_x - x2) + sqr(last_y - y2)));
end;

function getdistanceloot3d(x2, y2, z2: single): integer;
begin
getcord;
result := round(sqrt(sqr(last_x - x2) + sqr(last_y - y2) + sqr(last_z - z2)));
end;



...
if getdistanceloot(Loot_x, Loot_y) < {form1.TrackBar3.Position} 5 then
...

trixicus
02.11.2011, 02:22
Не буду давать готовое)
Странно, а получилось наоборот, ведь тут есть все, что надо)

В итоге я получаю весь лут, что упал с моба(ну или еще каким-то образом попал в радиус), но как остановить поиск следующего моба для битья, пока мы собираем лут. То есть как узнать, что мы собрали все, что нам надо?

aktivizion15
02.11.2011, 08:38
Странно, а получилось наоборот, ведь тут есть все, что надо)


Чорд)

как остановить поиск следующего моба для битья

Смотря как сделан твой бот.
В моем первом боте сделан шаблон:

...
foundtarget; // Поиск Таргета
Killing; // Убийство
lotting; // Лут
...

Тоесть всё выполняется по порядку, нашел, убил, собрал, и тд.
Сейчас же я переделываю эту систему на более продвинутую)

То есть как узнать, что мы собрали все, что нам надо?


Показывал же раньше)


...
while loot <> 0 then
//и тут собираем его же
PickWalk(loot)
...

function loot(): dword;
begin
result:=0;
...

Далее мы ищем всё что надо,возвратит wid, иначе если ненайдем возвратит нуль

trixicus
02.11.2011, 09:44
Проспавшись, я все-таки смог понять, зачем нужен этот цикл). Сделал немного по-другому, со считыванием WID-ов в динамический массив, и уже потом в цикле смотрел сколько осталось собрать. Спасибо за идею, и примеры реализации.

PS: Думаю тему бы неплохо переименовать в "Как написать каркас для бота за 2 дня" :)

aktivizion15
02.11.2011, 11:55
trixicus, ЛС проверь)