Rus. server

12/23/2009 14:22 origmas#1096
- Для НАЧАЛА .. на VC++ это уже работает ..


#include "stdafx.h"
//#include "Bot.h"
//#include "BotDlg.h"
//#include "OptionDlg.h"
//#include "MonitorDlg.h"
//****************************************
#include <windows.h>
#include <iostream>

CString Client = "Element Client";
char BUF[64];

HWND Hwnd = NULL; //
DWORD Pid = NULL; //
HANDLE Proc = NULL; //
DWORD Buf = NULL; // Буфер (перед чт.зн.памяти Нужно обяз.приравнивать к 0 или к значению)
DWORD Base = 0x0098B47C; // 0098b47c 10007676 (старый 0x009771bc 9925052) Базовый Адрес Данных Клиента


// ПЕРСОНАЖ -----------------------------------------------------------------
DWORD Pers = NULL; // Адр. Начала данных Перса (BASE + 32)

CString ChName = ""; // Имя Перса
DWORD _ChName = 0x5F4; // 1524 Смещение к адр. по кот.лежит Имя Перса от начала данных Перса (PERS)

DWORD CharID = NULL; // ID Перса
DWORD _CharID = 0x450; // 1104 Смещение к адр.ID Перса

BYTE CharLEV = 0; // Значение Уровня Перса в Игре
DWORD _CharLEV = 0x45C; // 1116 Смещение к адр.Уровня Перса

DWORD CharTID = NULL; // ID цели Перса (Прицел)
DWORD _CharTID = 0xADC; // 0x0ADC 2780 (старое 0x0A68 2664) Смещение к адр.Прицела Перса

float CharHP = 0.0; // Значение Жизненной Силы Перса (можно и DWORD - float это для согласования с показанием % прогресс-бара)
DWORD _CharHP = 0x464; // 1124 Смещение к адр.HP Перса
float CharMxHP = 0.0; // Значение Макс.Жизненной Силы Перса
DWORD _CharMxHP = 0x494; // 1172 Смещение к адр.Макс.HP Перса
float CharPrHP = 0.0; // Значение Жизненной Силы Перса в процентах

float CharMP = 0.0; // Значение Магической Энергии Перса
DWORD _CharMP = 0x468; // 1128 Смещение к адр.MP Перса
float CharMxMP = 0.0; // Значение Макс.Магической Энергии Перса
DWORD _CharMxMP = 0x498; // 1176 Смещение к адр.Макс.MP Перса
float CharPrMP = 0.0; // Значение Магической Энергии Перса в процентах
float CharDamage = 0.0; // Значение нанесенного Ущерба Персу в процентах

WORD CharX = 0; // Значение Координаты X Перса в Игре - это координата в Игре - она целое число
float CharXX = 0.0; // Значение Координаты X Перса в Памяти Клиента - Для координат в памяти точно нужен float
DWORD _CharXX = 0x3C; // 60 Смещение к адр.Координаты X Перса
WORD CharY = 0; // Значение Координаты Y Перса в Игре
float CharYY = 0.0; // Значение Координаты Y Перса в Памяти
DWORD _CharYY = 0x44; // 68 Смещение к адр.Координаты Y Перса
WORD CharZ = 0; // Значение Координаты Z Перса в Игре
float CharZZ = 0.0; // Значение Координаты Z Перса в Памяти
DWORD _CharZZ = 0x40; // 64 Смещение к адр.Координаты Z Перса

//---------------------------------------------------------------------------

// МОНСТР -------------------------------------------------------------------
// Base + 8 + 36 + 24 + .. Начало данных Моба из записи => [BA] + 8 + 36 + 24 + (i * 4) + 4 + .. (где i от 0 до 768)
DWORD Mobs = NULL; // Адр. Начала данных Моба

CString MobName = ""; // Имя Моба
DWORD _MobName = 0x23c; // 572 + 0 Смещение к адр. по кот.лежит Имя Моба от начала данных Моба (Mobs)

DWORD MobID = NULL; // ID Моба
DWORD _MobID = 0x11C; // 284 Смещение к адр.ID Моба

BYTE MobTP = 0; // Значение Типа Моба (6-монстр 7-NPS 9-питомец)
DWORD _MobTP = 0xB4; // 180 Смещение к адр.Типа Моба

BYTE MobLEV = 0; // Значение Уровня Моба
DWORD _MobLEV = 0x124; // 292 Смещение к адр.Уровня Моба

DWORD MobTID = 0x0; // ID цели Моба - Занят Монстр - TRUE
DWORD _MobTID = 0x2C4; // 708 Смещение к адр.Прицела Моба

float MobHP = 0.0; // Значение Жизненной Силы Моба
DWORD _MobHP = 0x464; // 1124 ? Смещение к адр.HP Моба
float MobMxHP = 0.0; // Значение Макс.Жизненной Силы Моба
DWORD _MobMxHP = 0x498; // 1176 ? Смещение к адр.Макс.HP Моба
float MobPrHP = 0.0; // Значение Жизненной Силы Моба в процентах

WORD MobX = 0; // Значение Координаты X Моба в Игре
float MobXX = 0.0; // Значение Координаты X Моба в Памяти Клиента
DWORD _MobXX = 0x3C; // 60 Смещение к адр.Координаты X Моба
WORD MobY = 0; // Значение Координаты Y Моба в Игре
float MobYY = 0.0; // Значение Координаты Y Моба в Памяти
DWORD _MobYY = 0x44; // 68 Смещение к адр.Координаты Y Моба
WORD MobZ = 0; // Значение Координаты Z Моба в Игре
float MobZZ = 0.0; // Значение Координаты Z Моба в Памяти
DWORD _MobZZ = 0x40; // 64 Смещение к адр.Координаты Z Моба

WORD MobDIS = 0; // Значение Дистанции до Моба в единицах координат игры
float MobDDD = 0.0; // Значение Дистанции до Моба в Памяти
DWORD _MobDIS = 0x260; // 608 Смещение к адр.Дистанции до Моба

//---------------------------------------------------------------------------



bool CBotDlg::OpenProc() // Открытие процесса Клиента
{ Hwnd = ::FindWindow(NULL, Client); // Находим окно Клиента
if(Hwnd) // Если окно Клиента найдено
{ ::ShowWindow(Hwnd,TRUE); // Показать окно
::SetForegroundWindow(Hwnd); // Окно на передний план
::SetWindowPos(Hwnd,0,256,0,1024,768,0); // Установить окно Игры 1024x768 в прав-верхн угол экрана
GetWindowThreadProcessId(Hwnd,&Pid); // Получаем Process ID
if(Pid) // Если получен ID Процесса
{ Proc = OpenProcess(PROCESS_ALL_ACCESS,0,Pid); // Получаем доступ к процессу
return true;
}
} // !!! Функцию можно запускать 1 раз при открытии Бота
MessageBox("Не найдено окно Клиента","!!!");
return false;
}
//---------------------------------------------------------------------------
bool CBotDlg::GetInfo() // Чтение основнных Данных
{ // читается при запуске Бота и/или если напр. изменился Уровень, макс.HP/MP Перса
BUF[0]=0;
ChName="";
if(Proc) // Если Процесс открыт
{ // Находим адр.начала данных о Мобах - Mobs
ReadProcessMemory(Proc,(LPCVOID) Base, &Buf, 4,0);// Buf - буфер куда копируются данные DWORD
ReadProcessMemory(Proc,(LPCVOID) (Buf+ 0x08), &Mobs, 4,0);// + 8 DWORD
ReadProcessMemory(Proc,(LPCVOID) (Mobs+ 0x24), &Buf, 4,0);// + 36
ReadProcessMemory(Proc,(LPCVOID) (Buf+ 0x18), &Mobs, 4,0);// + 24 - начало данных о Мобах
// Находим адр.начала данных о Персе - Pers
ReadProcessMemory(Proc,(LPCVOID) Base, &Buf, 4,0);// Buf - буфер куда копируются данные
ReadProcessMemory(Proc,(LPCVOID)(Buf+ 0x20), &Pers, 4,0);// Pers - начало данных Персонажа DWORD
// Читаем инфу о Персе
for (i=0;i<64;i++) BUF[i]=0; // очищаем буфер для чтения имени
ReadProcessMemory(Proc,(LPCVOID)(Pers+_ChName), &BUF, 32,0);// Имя
CharID=0;
ReadProcessMemory(Proc,(LPCVOID)(Pers+_CharID), &CharID, 4,0);// ID DWORD
CharLEV=0;
ReadProcessMemory(Proc,(LPCVOID)(Pers+_CharLEV), &CharLEV, 1,0);// Уровень BYTE
CharMxHP=0;
ReadProcessMemory(Proc,(LPCVOID)(Pers+_CharMxHP),& CharMxHP, 4,0);// макс.Жизни float (DWORD)
CharMxMP=0;
ReadProcessMemory(Proc,(LPCVOID)(Pers+_CharMxMP),& CharMxMP, 4,0);// макс.Энергии float (DWORD)
// Скорректируем данные
//for (i=0;i<16;i++) ChName += BUF[i];
//CloseHandle(Proc); // Закрываем процесс (если надо)
// КОНТРОЛЬ ________________________________
inf=ChName;
tmp.Format(": ID = %x LEV = %d",CharID,CharLEV); inf+=tmp; // Работает ...
SetDlgItemText(IDC_INF_REGION,inf);
// _________________________________________
return true;
}
MessageBox("Не определен ID Процесса","!!!");
return false;
}
//---------------------------------------------------------------------------
bool CBotDlg::GetCharInfo() // Чтение текущих данных Персонажа
{ if(Proc)
{ // Читаем данные Персонажа
CharTID=0;
ReadProcessMemory(Proc,(LPCVOID)(Pers+_CharTID),&C harTID, 4,0); // ID цели
CharHP=0;
ReadProcessMemory(Proc,(LPCVOID)(Pers+_CharHP), &CharHP, 4,0); // Жизнь (float) можно и DWORD - float это для согласования с показанием % прогресс-бара
CharMP=0;
ReadProcessMemory(Proc,(LPCVOID)(Pers+_CharMP), &CharMP, 4,0); // Знергия (float)
CharXX=0;
ReadProcessMemory(Proc,(LPCVOID)(Pers+_CharXX), &CharXX, 4,0); // X float
CharYY=0;
ReadProcessMemory(Proc,(LPCVOID)(Pers+_CharYY), &CharYY, 4,0); // Y float
CharZZ=0;
ReadProcessMemory(Proc,(LPCVOID)(Pers+_CharZZ), &CharZZ, 4,0); // Z float
// Скорректируем данные
CharPrHP = CharHP / CharMxHP * 100; // % Жизни float
CharPrMP = CharMP / CharMxMP * 100; // % Энергии float
//CharDamage = Int(Int($LAST_HP_READ) - Int($HP)) // Урон float
CharX = 400 + CharXX / 10; // X в Игре WORD
CharY = 550 + CharYY / 10; // Y в Игре WORD
CharZ = CharZZ / 10; // Z в Игре WORD
// КОНТРОЛЬ ________________________________
inf=""; inf+="Перс: ";
tmp.Format(" TID = %x ",CharTID); inf+=tmp;
tmp.Format(" X = %d ",CharX); inf+=tmp;
//SetDlgItemText(IDC_INF_REGION,inf);
// _________________________________________
//CloseHandle(Proc); // Закрываем процесс (для случая если функ-ия будет использоваться однлкратно)
return true;
}
MessageBox("Не открыт Процесс Клиента","!!!");
return false;
}
//---------------------------------------------------------------------------
void CBotDlg::OnTimer(UINT nIDEvent) // Каждую секунду ..
{ if(Proc)
{ if(GetCharInfo())
{ // Вывод HP% и MP% Перса
m_cPrHp.SetPos(static_cast<int>(CharPrHP));
m_cPrMp.SetPos(static_cast<int>(CharPrMP));
prog.Format("%d %%", static_cast<int>(CharPrHP));
m_cLabPrHp.SetWindowText(prog);
prog.Format("%d %%", static_cast<int>(CharPrMP));
m_cLabPrMp.SetWindowText(prog); // SetDlgItemInt(IDC_LAB_HP,CharMxHP);
// ..
}
Invalidate(); // Обновление Таймера только при открытом Процессе
}
// ...
}


---- реализация:

OpenProc()
GetInfo()
GetCharInfo()
потом кажд сек по таймеру выводится в прогресс-бар как в игре полосками - показатели HP/MP Перса

при выхлоде из Бота - //CloseHandle(Proc); // Закрываем процесс
12/23/2009 17:03 zachelovek#1097
Quote:
Originally Posted by origmas View Post
- Для НАЧАЛА .. на VC++ это уже работает ..


[/COLOR] // Закрываем процесс
это готовый код бота? если да, то можно скомпилированый exe?
12/23/2009 17:26 origmas#1098
Стартовый Проект на VC++ 6.0 - это не VC++ 2005-2008 - в 6-ом свое правило составления проектов, поэтому если будете пробывать то нужен именно 6-ой Визуал - он небольшой 170 мегов - всюду можно скачать с Инета, к нему еще надо будет библу красивых элементов управления ActivX Control скачать тоже есть в Инете. Тем кто осваивают 8-9 Визуал - нужно будет переводить проект на них
Конечно это не то, что у меня есть в полном объеме, потому-что не все там налажено на 100%, а выложил то что работает и с простыми элементами управления, конечно недоделки - каждый доделает сам, лучше ведь можно сделать и нужно делать лучше - я не специалист какой-нить, но многие не знают с чего начать строить проект - пусть эта моя работа будет им отправной точкой .. надеюсь меня не будут обсуждать, потому-что обсуждать можно любой код, даже если его написал-бы - Профи ..))

..PS.. в папке Release есть EXE-шка проекта - это не готовый Бот - это начальный этап разработки..
12/24/2009 05:58 sumikot#1099
Качаю... Может, кому тоже пригодится VC 6.0 - [Only registered and activated users can see links. Click Here To Register...]
Не я ложил, поэтому проверяйте.
Origmas, если не трудно, обьясни отличия 6-го от 2008. У меня было мнение, что существует совместимость сверху вниз, но ты ее только что опроверг... Стоит 2008, через минут 40 докачаю 6.0, попробую открыть и там и там.
Попробовал открыть в 2008 как проект - пишет файл повлежден, значит, совместимости нет...
12/24/2009 08:45 origmas#1100
Quote:
Originally Posted by sumikot View Post
... было мнение, что существует совместимость сверху вниз
Язык программирования везде один С++ но существуют разные среды разработки Borland, VC++ 6, VC++ 8 ....
Всюду свое устройство проекта, свои заголовочные файлы - своя компановка рессурсов (панелей, элементов, изображений).
Очень трудно перевести проект из одной среды в другую - нет никакой совместимости ... Только руками ...
12/24/2009 08:52 AlexGD#1101
Ориг... Просто интересно - что тебя побудило писать именно на VC++ 6? ЕМНИП там жуткий мозготрах с юникодом...
12/24/2009 09:06 origmas#1102
Quote:
Originally Posted by AlexGD View Post
что тебя побудило писать именно на VC++ 6?
Ни Русские, ни Китайцы, ни Англичане - никогда не страдали от того что они разговаривают на своем языке - это никак не портит их жизнь и развитие ... Не унижает, не ограничивает и не мозготрахает ..
12/24/2009 09:12 AlexGD#1103
Да нп ;) Просто мне для работы над этой задачей пришлось слезть со своего любимого Delphi7. Я-то победил и в нем все проблемы - но это оказалось гораздо неудобнее, чем пользоваться D2010.
12/24/2009 09:17 origmas#1104
Quote:
Originally Posted by AlexGD View Post
Да нп ;) Просто мне для работы .....
а нам всегда или Х... длиннен или рубашка коротка ..))
именно надо работать а не приспосабливаться .. Дельфи рулил и будет рулить - Отличная среда разработки, гибкий Язык, много запчастей нв любой СТО ..
12/24/2009 09:36 AlexGD#1105
Хочу сказать огромное спасибо всем в этой ветке, а также многим другим людям, которые, выложив свой код в свободный доступ, помогли разобраться с тонкостями взаимодействия с чужими процессами. Эти задачки доставили мне уйму занимательного времени изучения чего-то нового.

В результате выродилось у меня некое чудо.

Что это? Это stand-alone швейцарский ножик для работы с элемент-клиентом. Например:

"Хочу получить окно клиента!"
Code:
var
  aPWWindow: TaPWWindow;
  CurrentHandle, PreviousHandle : HWND;
begin
    aPWT.FindClientWindow(0, '', CurrentHandle, aPWWindow);
    ShowMessage(aPWWindow.Name);
Имею всю информацию об окне.

"Хочу знать кто в локе!"
Code:
var
  aPlayersArray: TaPlayersArray;
begin
    aPlayersArray := aPWT.GetLocationPlayers(aPWWindow.aProcessID);
"Хочу прыгнуть!"
Code:
  aPWT.Jump(aPWWindow.aProcessID);
Ну и т.д. и т.п. Файл постарался детально откомментировать.

Главная задача, которая здесь решена - мультиоконность и осутствие предопределенных внутри констант. Все необходимые адреса - в aPWTools.ini

Ну, в общем, работа начата, но еще далека до завершения. У меня тупо нет времени над этим серьезно работать ((( Если кому пригодится - пользуйтесь на здоровье. Все, что буду добавлять в него - буду обновлять и сообщать об этом. Но надеяться на скорые обновления не стоит...

Еще раз всем спасибо за помощь!
12/24/2009 09:38 AlexGD#1106
Не могу наваять инжект закрытия окна НПС... Адрес есть, что делать вроде как понимаю... А клиент выносиццо... Может кто помочь с асмом? :handsdown:
12/24/2009 13:22 silkytail#1107
Quote:
Originally Posted by origmas View Post
именно надо работать а не приспосабливаться .. Дельфи рулил и будет рулить - Отличная среда разработки, гибкий Язык, много запчастей нв любой СТО ..
Только у него одна проблема - как коммерческая платформа для разработки дельфи давно умер, и будущего у него нет никакого, кроме как для обучения студентов лепить формочки.
12/24/2009 13:35 dj_al#1108
Quote:
Originally Posted by silkytail View Post
Только у него одна проблема - как коммерческая платформа для разработки дельфи давно умер, и будущего у него нет никакого, кроме как для обучения студентов лепить формочки.
Оппа!!! А мужики то и не знают... Пишут себе и пишут на Delphi, себе в удовольствие и на радость клиентов...
Чего в нём такого нет, что таки архи-нужно для современной разработки?
12/24/2009 13:57 origmas#1109
Открывать процессы - умеет - создавать потоки умеет, мозговые извилины моделировать может .. что еще не хватает для Бота ..
А куда денишься если с студенческой скамьи приучают к Паскалю ..
Другое дело если голова не забита еще никакими языками - тут - да лучше с С++ начинать, но опять-же это просто мое мнение и совет тут даст только опытный человек, прошедший через всЁ ..
12/24/2009 14:07 silkytail#1110
Quote:
Originally Posted by dj_al View Post
Оппа!!! А мужики то и не знают... Пишут себе и пишут на Delphi, себе в удовольствие и на радость клиентов...
Ну вот пусть знают. Спрос на рынке дельфи-программистов колеблется на уровне трех процентов и постоянно падает.
Quote:
Чего в нём такого нет, что таки архи-нужно для современной разработки?
Это не ко мне вопрос :)