Я что-то не въезжаю о чём спор... string всегда 4 байта, так как возвращается размер указателя на данные, хранимые этим типом.
________________
Принимаются пожертвования любых размеров в фонд поддержки начинающих программистов
Кошельки: WMZ - Z276844220882; WMR - R231028582939; WMU - U394136909210; ЯД - 410011494605270.
Я что-то не въезжаю о чём спор... string всегда 4 байта, так как возвращается размер указателя на данные, хранимые этим типом.
именно
Добавлено через 19 минут
Цитата:
Сообщение от VeTaL_UA
Ginrey, а нафига в массив заносить? У тебя есть файл, в котором id записаны в виде id:name. Ты просто передаёшь в программу путь к файлу и нужный тебе id. Допустим в папке с твоей программой есть файл id.txt и найти тебе нужно название предмета с id 123456 в переменную s2:string, тогда это будет выглядеть так:
Код:
s2:=GetName('id.txt','123456');
В итоге имя предмета по этим id будет в переменной s2.
P.S. Если тебе нужно находить название нескольких предметов сразу, то могу немножко дописать функцию
так ты допишешь функцию, попробую через нее. кстати путь к файлу куда заносить я не совсем понял
Последний раз редактировалось Ginrey; 22.07.2012 в 13:18.
Причина: Добавлено сообщение
Накопал полезный оффсет, по которому можно брать прямо с клиента названия и описания скиллов, предметов инвентаря, экипировки, вобщем полезная штука. Оффсет +BC+0 - Description (unicode string) в структуре элемента управления, остальное можно посмотреть в теме Оффсеты GUI
ПС: небольшой облом получился с оффсетом.. описание предметов оказывается не обновляется, пока не поводишь по предмету мышкой..
Вот например считывается название предмета
или вот, может помочь при крафте
Так же можно считать и описание скиллов, но в стандартные элементы типа Memo без обработки не получается полностью вывести, так как там разделение какими то символами, которые воспринимаются как конец текста.
Даже информацию из окон для разработчиков глянуть можно оказывается.
Хех, да, ошибся тут, видимо криво прочитал про делфю и подумал что как и в с++ одинаковое действие), но почему в ReadProcessMemory нельзя вместо siseof поставить сразу нужное значение?
________________
╔═╗
║ ˑ ˑ ╬ ╬
╚═╝
Последний раз редактировалось dwa83; 23.07.2012 в 14:43.
Причина: Добавлено сообщение
Хех, да, ошибся тут, видимо криво прочитал про делфю и подумал что как и в с++ одинаковое действие), но почему в ReadProcessMemory нельзя вместо siseof поставить сразу нужное значение?
можно. я обычно 4 ставлю. но я хз зачем так делают, не скорость работа не произвоодительность не меняется. а за поиск оффсета ты заслужил СПАСИБО!!!
Цитата:
Сообщение от dwa83
Оффсет +BC+0
так какой оффсеты выполняет запись имене предмета и что это за значение?
Добавлено через 46 минут
и еще. что у меня с этим сканером? максимум 100 номеров в каждом поле[Ссылки могут видеть только зарегистрированные пользователи. ]
Последний раз редактировалось Ginrey; 22.07.2012 в 18:10.
Причина: Добавлено сообщение
Принимаются пожертвования любых размеров в фонд поддержки начинающих программистов
Кошельки: WMZ - Z276844220882; WMR - R231028582939; WMU - U394136909210; ЯД - 410011494605270.
и еще. что у меня с этим сканером? максимум 100 номеров в каждом поле
Да есть такой косяк, это старая версия, новую залил. Для окно сделал 1000, для элементов управления не стал делать больше ста, так как по моему их не бывает столько в окне.
Цитата:
Сообщение от Ginrey
так какой оффсеты выполняет запись имене предмета и что это за значение?
структуре элемента управления) может не понятно написал) CtrlStruct + BC + 0
+BC - это оффсет, по которому в структуре элемента лежит 4х-байтный указатель, представляющий адрес строки текста описания, тоесть по оффсету ...+BC мы получим число-адрес, а по оффсету ..+BC+0 уже считываем данные этой строки по полученному адресу. Так же если по оффсету +BC записать адрес нашей подготовленной и внедрённой строки, то по сути в игре вместо описания должен появится наш текст. С многими строками это работает, но некоторые ПВ обновляет на изначальное значение(то есть оригинал строки ещё где то лежит), с описанием не проверял ещё. Но самое главное - это считывать этот текст.
________________
╔═╗
║ ˑ ˑ ╬ ╬
╚═╝
Последний раз редактировалось dwa83; 23.07.2012 в 00:13.
Сам код у меня был для вытаскивания названия квестов по их id из базы id-name, немного поменял и под другую задачу получилось
________________
Принимаются пожертвования любых размеров в фонд поддержки начинающих программистов
Кошельки: WMZ - Z276844220882; WMR - R231028582939; WMU - U394136909210; ЯД - 410011494605270.
короче через адресс сколько не мудрил не получилось название вытянуть.
делаю вот так
procedure TForm1.btn8Click(Sender: TObject);
var
BC:size_t;
hProcess,PID,ibuf: DWORD;
name:wchar;
i: dword;
begin
hProcess:=OpenProcess(PROCESS_ALL_ACCESS, False, fid[cb1.ItemIndex]);
ReadProcessMemory(hProcess,ptr($A571E0),@ibuf,size of(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf+$1C),@ibuf,siz eof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf+$34),@ibuf,siz eof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf+$D18),@ibuf,si zeof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf+$C),@ibuf,size of(ibuf),BC);
for I := 0 to 63 do
begin
ReadProcessMemory(hProcess,ptr(ibuf+(i*4)),@ibuf,s izeof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf+$40),@ibuf,siz eof(ibuf),BC);
ReadProcessMemory(hProcess,ptr(ibuf),@name,sizeof( name),BC);
memo1.Lines.add(name);
end;
CloseHandle(hProcess);
end;[/QUOTE]
и в мемо поле получается 犴 на каждую из 63 строчек.
так как описание предмета считать точнее специальные параметры
Добавлено через 6 часов 59 минут
ура получилось))
вот рабочая функция. даже убрал лишние звездочки
[QUOTE]
Код:
var
IdPredmeta, KolPredmeta,MaksYacheekInventar, TypePredmeta:Integer;
WGAME_ADD, PlayerStruct, Inventory, IdPredmetaI, nameI,hprocess,h:DWord;
i:Integer; NoB:SIZE_T;
j:array [0..63] of Integer;
itemNname:array[0..63] of widechar;
wnd: THandle;
begin
wnd:=FindWindow('ElementClient window',nil);
GetWindowThreadProcessId(wnd,@h);
hprocess:=OpenProcess(PROCESS_ALL_ACCESS, False,h);
if hProcess <> 0 then
begin
Lst1.Clear;
ReadProcessMemory (hProcess, Pointer($A57ACC), @WGAME_ADD, sizeof(WGAME_ADD), NoB);
ReadProcessMemory (hProcess, Pointer(WGAME_ADD+$34), @PlayerStruct, sizeof(PlayerStruct), NoB);
ReadProcessMemory (hProcess, Pointer(PlayerStruct+$D18), @Inventory, sizeof(Inventory), NoB); //Читаем значение HP
ReadProcessMemory (hProcess, Pointer(Inventory+$10),@MaksYacheekInventar,sizeof(MaksYacheekInventar),NoB);
for i:=0 to (MaksYacheekInventar-1) do
begin
IdPredmeta := 0;
ReadProcessMemory (hProcess, Pointer(Inventory+$C),@IdPredmetaI,sizeof(IdPredmetaI),NoB);
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$4*i),@IdPredmetaI,sizeof(IdPredmetaI),NoB);
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$8),@IdPredmeta,sizeof(IdPredmeta),NoB);
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$10),@KolPredmeta,sizeof(KolPredmeta),NoB);
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$4),@TypePredmeta,sizeof(TypePredmeta),NoB);
if (TypePredmeta = 0) or (TypePredmeta = 3) then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$e0),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI+$C),@itemNname,64,NoB);
end;
if (TypePredmeta = 17) or (TypePredmeta = 11) then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$4C),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI+$8),@itemNname,64,NoB);
end;
if TypePredmeta = 2 then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$CC),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$8),@itemNname,64,NoB);
end;
if (TypePredmeta = 8) or (TypePredmeta = 9) or (TypePredmeta = 22) or (TypePredmeta = 23) then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$54),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$C),@itemNname,64,NoB);
end;
if TypePredmeta = 15 then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$E8),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$C),@itemNname,64,NoB);
end;
if (TypePredmeta = 5) or (TypePredmeta = 10) or (TypePredmeta = 13) or (TypePredmeta = 16) or (TypePredmeta = 19) or (TypePredmeta = 20) or (TypePredmeta = 27) or (TypePredmeta = 31) or (TypePredmeta = 32) or (TypePredmeta = 38) or (TypePredmeta = 40) or (TypePredmeta = 46) then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$4C),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$4),@itemNname,64,NoB);
end;
if TypePredmeta = 43 then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$54),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$4),@itemNname,64,NoB);
end;
if (TypePredmeta = 36) or (TypePredmeta = 37) then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$B8),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$4),@itemNname,64,NoB);
end;
if TypePredmeta = 41 then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$10C),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$4),@itemNname,64,NoB);
end;
if TypePredmeta = 26 then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$A0),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$4),@itemNname,64,NoB);
end;
if TypePredmeta = 4 then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$B4),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$8 +$8),@itemNname,64,NoB);
end;
if TypePredmeta = 34 then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$B4),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$4),@itemNname,64,NoB);
end;
if TypePredmeta = 6 then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$D0),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$C),@itemNname,64,NoB);
end;
if TypePredmeta = 7 then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$D0),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$4),@itemNname,64,NoB);
end;
if TypePredmeta = 18 then
begin
ReadProcessMemory (hProcess, Pointer(IdPredmetaI+$C4),@nameI,sizeof(nameI),NoB);
ReadProcessMemory (hProcess, Pointer(nameI +$4),@itemNname,64,NoB);
end;
j[i]:=IdPredmeta;
if IdPredmeta >0 then
begin
Lst1.Items.Add(itemNname);
end;
end;
lst1.items.Text := StringReplace(lst1.items.Text,'★','',[rfReplaceAll]);
lst1.items.Text := StringReplace(lst1.items.Text,'☆','',[rfReplaceAll]);
end;
end;
Последний раз редактировалось Ginrey; 24.07.2012 в 07:58.
Причина: Добавлено сообщение
Добавлено через 5 часов 2 минуты
Вот смотрю я на твой код и думаю, почему ты себя так не любишь? Ладно себя, но за что ты ненавидишь тех,кто рискнёт использовать твой код?
Во первых, оформление кода. Я, конечно, понимаю пробелами отделять для большей видимости, но не настолько же Во вторых, зачем использовать, при чём беспорядочно, if..then, когда в твоей ситуации case удобнее в 100500 раз, да и правильнее. В третьих, почему у тебя всё в одной процедуре??? Читаемость кода нулевая, всё вместе и ничего не понятно. Да, названия переменных порадовали
Привёл твой код в нормальный вид и немного оптимизировал его:
function FindClient:DWord;
var
Wnd:THandle;
PID,h:DWord;
begin
Wnd:=FindWindow('ElementClient window',nil);
GetWindowThreadProcessId(wnd,@PID);
h:=OpenProcess(PROCESS_ALL_ACCESS,False,PID);
end;
procedure Inv(hProcess:DWord; var Inv:DWord; CellCount:integer);
var
buf:DWord;
bc:size_t;
begin
ReadProcessMemory(hProcess,Ptr($A57ACC),@buf,sizeof(buf),bc);
ReadProcessMemory(hProcess,Ptr(buf+$34),@buf,sizeof(buf),bc);
ReadProcessMemory(hProcess,Ptr(buf+$D18),@inv,sizeof(inv),bc);
ReadProcessMemory(hProcess,Ptr(inv+$10),@cellcount,sizeof(cellcount),bc);
end;
procedure IdCountType(hProcess,Inv:DWord; i:integer; var buf:DWord; Id,Count,TypeP:Integer; T:Bool);
var
bc:size_t;
begin
T:False;
ReadProcessMemory(hProcess,Ptr(Inv+$C),@buf,sizeof(buf),bc);
ReadProcessMemory(hProcess,Ptr(buf+$4*i),@buf,sizeof(buf),bc);
ReadProcessMemory(hProcess,Ptr(buf+$8),@Id,sizeof(Id),bc);
if Id<>0 then
begin
ReadProcessMemory(hProcess,Ptr(buf+$10),@Count,sizeof(Count),bc);
ReadProcessMemory(hProcess,Ptr(buf+$4),@TypeP,sizeof(TypeP),bc);
T:=True;
end;
end;
procedure GetName(hProcess,Buff,Offset1,Offset2:DWord; var Name:array[0..63] of WideChar);
var
buf:DWord;
bc:size_t;
begin
ReadProcessMemory(hProcess,Ptr(Buff+Offset1),@buf,sizeof(buf),bc);
ReadProcessMemory(hProcess,Ptr(buf+Offset2),@Name,64,bc);
end;
procedure Main;
var
IdPredmeta,KolPredmeta,MaksYacheekInventar,TypePredmeta:Integer;
IdPredmetaI,Inventory,hprocess:DWord;
i:Integer;
j:array[0..63] of Integer;
itemNname:array[0..63] of widechar;
T:Bool;
begin
hprocess:=FindClient;
if hProcess <> 0 then
begin
Lst1.Clear;
Inv(hProcess,Inventory,MaksYacheekInventar);
for i:=0 to MaksYacheekInventar-1 do
begin
IdCountType(hProcess,Inventory,i,IdPredmetaI,IdPredmeta,KolPredmeta,TypePredmeta,T);
if T then
begin
GetNameByType(hProcess,IdPredmetaI,TypePredmeta,itemNname);
j[i]:=IdPredmeta;
itemNname:=StringReplace(itemNname,'★','',[rfReplaceAll];
itemNname:=StringReplace(itemNname,'☆','',[rfReplaceAll];
Lst1.Items.Add(itemNname);
end;
end;
end;
CloseHandle(hProcess);
end;
function FindClient:DWord;
var
Wnd:THandle;
PID,h:DWord;
begin
Wnd:=FindWindow('ElementClient window',nil);
GetWindowThreadProcessId(wnd,@PID);
h:=OpenProcess(PROCESS_ALL_ACCESS,False,PID);
end;
procedure Inv(hProcess:DWord; var Inv:DWord; CellCount:integer);
var
buf:DWord;
bc:size_t;
begin
ReadProcessMemory(hProcess,Ptr($A57ACC),@buf,sizeof(buf),bc);
ReadProcessMemory(hProcess,Ptr(buf+$34),@buf,sizeof(buf),bc);
ReadProcessMemory(hProcess,Ptr(buf+$D18),@inv,sizeof(inv),bc);
ReadProcessMemory(hProcess,Ptr(inv+$10),@cellcount,sizeof(cellcount),bc);
end;
procedure IdCountType(hProcess,Inv:DWord; i:integer; var buf:DWord; Id,Count,TypeP:Integer; T:Bool);
var
bc:size_t;
begin
T:False;
ReadProcessMemory(hProcess,Ptr(Inv+$C),@buf,sizeof(buf),bc);
ReadProcessMemory(hProcess,Ptr(buf+$4*i),@buf,sizeof(buf),bc);
ReadProcessMemory(hProcess,Ptr(buf+$8),@Id,sizeof(Id),bc);
if Id<>0 then
begin
ReadProcessMemory(hProcess,Ptr(buf+$10),@Count,sizeof(Count),bc);
ReadProcessMemory(hProcess,Ptr(buf+$4),@TypeP,sizeof(TypeP),bc);
T:=True;
end;
end;
procedure GetName(hProcess,Buff,Offset1,Offset2:DWord; var Name:array[0..63] of WideChar);
var
buf:DWord;
bc:size_t;
begin
ReadProcessMemory(hProcess,Ptr(Buff+Offset1),@buf,sizeof(buf),bc);
ReadProcessMemory(hProcess,Ptr(buf+Offset2),@Name,64,bc);
end;
procedure GetNameByType(hProcess,Buff:DWord; TypeP:integer; var Name:array[0..63] of WideChar);
begin
case TypeP of
0,3:GetName(hProcess,Buff,$e0,$C,Name);
17,11:GetName(hProcess,Buff,$4C,$8,Name);
2:GetName(hProcess,Buff,$CC,$8,Name);
8,9,22,23:GetName(hProcess,Buff,$54,$C,Name);
15:GetName(hProcess,Buff,$E8,$C,Name);
5,10,13,16,19,20,27,31,32,38,40,46:GetName(hProcess,Buff,$4c,$4,Name);
43:GetName(hProcess,Buff,$54,$4,Name);
36,37:GetName(hProcess,Buff,$B8,$4,Name);
41:GetName(hProcess,Buff,$10C,$4,Name);
26:GetName(hProcess,Buff,$A0,$4,Name);
4:GetName(hProcess,Buff,$B4,$10,Name);
34:GetName(hProcess,Buff,$B4,$4,Name);
6:GetName(hProcess,Buff,$D0,$C,Name);
7:GetName(hProcess,Buff,$D0,$4,Name);
18:GetName(hProcess,Buff,$C4,$4,Name);
end;
end;
procedure Main;
var
IdPredmeta,KolPredmeta,MaksYacheekInventar,TypePredmeta:Integer;
IdPredmetaI,Inventory,hprocess:DWord;
i:Integer;
j:array[0..63] of Integer;
itemNname:array[0..63] of widechar;
T:Bool;
begin
hprocess:=FindClient;
if hProcess <> 0 then
begin
Lst1.Clear;
Inv(hProcess,Inventory,MaksYacheekInventar);
for i:=0 to MaksYacheekInventar-1 do
begin
IdCountType(hProcess,Inventory,i,IdPredmetaI,IdPredmeta,KolPredmeta,TypePredmeta,T);
if T then
begin
GetNameByType(hProcess,IdPredmetaI,TypePredmeta,itemNname);
j[i]:=IdPredmeta;
itemNname:=StringReplace(itemNname,'★','',[rfReplaceAll];
itemNname:=StringReplace(itemNname,'☆','',[rfReplaceAll];
Lst1.Items.Add(itemNname);
end;
end;
end;
CloseHandle(hProcess);
end;
Возможны ошибки, так как правил без компилятора, но я думаю, что ты сможешь их исправить, если они возникнут...
P.S. А читается ведь лучше, да?
________________
Принимаются пожертвования любых размеров в фонд поддержки начинающих программистов
Кошельки: WMZ - Z276844220882; WMR - R231028582939; WMU - U394136909210; ЯД - 410011494605270.