blackd
11-16-2012, 17:25
Many people is asking me about the new char list of Tibia 9.71, so I have decide to share here the code of a simple function to read the new charlist in Tibia.
Code is Delphi 7, and it should be easy to port to any other language.
7598
The important parts:
// This Delphi 7 procedure can read the new charlist in Tibia 9.71
// -Made by Blackd-
procedure TForm3.charlist();
var
i,address,address_end ,lastchar:Cardinal;
Nick, World : string;
Base_Address, remoteadr: Cardinal;
nametype: Cardinal;
begin
// in this simplified function we will think that there is
// a single Tibia client running.
// (Other way every function should have a ProcessId paramater to
// handle multiclient correctly)
ProcessID := func.ProcessIDFromAppname32('Tibia.exe');
// get base address. One time is enough.
Base_Address := Integer(func.GetModuleBaseAddress(ProcessID, 'Tibia.exe'));
// get index of selected char
ClientSelectedCharId := MemReadInteger(charlist_selected - $400000 + Base_Address);
StringList.Clear;
// we must do some maths to know how many chars are loaded
address := func.ReadMemInteger(charlist_start - $400000 + Base_Address);
address_end := func.ReadMemInteger(charlist_end - $400000 + Base_Address);
lastchar := ((address_end - address) div charlist_dist) - 1 ;
for i:=0 to lastchar do
begin
// union type: string can be stored here or in other place.
// depends on the value of nametype
nametype := func.ReadMemInteger(address + dist_name_type);
if nametype = 15 then
// nametype = hex 0F => Read name here directly
Nick := func.MemReadString(address+dist_name )
else
begin
// nametype = other value => Read address here
remoteadr := func.ReadMemInteger(address+dist_name );
// then read name in that address
Nick := func.MemReadString(remoteadr);
end;
// world is always there directly
World := func.MemReadString(address+dist_world );
// check if this char was the current char:
if (i=ClientSelectedCharId) then
begin
ClientSelectedCharName:=Nick;
ClientSelectedCharServer:=World;
end;
// add item to our list
StringList.Add(Nick+'|'+World);
address := address + charlist_dist;
end;
end;
StringList := TStringList.Create;
charlist_start:=$946CB0;
charlist_selected:=$946CFC;
charlist_end:=$946CB4;
charlist_dist:=72;
dist_name:=4;
dist_world:=32;
dist_name_size:=20;
dist_name_type:=24;
ClientSelectedCharId:=0;
ClientSelectedCharName:='';
ClientSelectedCharServer:='';
7598
Code is Delphi 7, and it should be easy to port to any other language.
7598
The important parts:
// This Delphi 7 procedure can read the new charlist in Tibia 9.71
// -Made by Blackd-
procedure TForm3.charlist();
var
i,address,address_end ,lastchar:Cardinal;
Nick, World : string;
Base_Address, remoteadr: Cardinal;
nametype: Cardinal;
begin
// in this simplified function we will think that there is
// a single Tibia client running.
// (Other way every function should have a ProcessId paramater to
// handle multiclient correctly)
ProcessID := func.ProcessIDFromAppname32('Tibia.exe');
// get base address. One time is enough.
Base_Address := Integer(func.GetModuleBaseAddress(ProcessID, 'Tibia.exe'));
// get index of selected char
ClientSelectedCharId := MemReadInteger(charlist_selected - $400000 + Base_Address);
StringList.Clear;
// we must do some maths to know how many chars are loaded
address := func.ReadMemInteger(charlist_start - $400000 + Base_Address);
address_end := func.ReadMemInteger(charlist_end - $400000 + Base_Address);
lastchar := ((address_end - address) div charlist_dist) - 1 ;
for i:=0 to lastchar do
begin
// union type: string can be stored here or in other place.
// depends on the value of nametype
nametype := func.ReadMemInteger(address + dist_name_type);
if nametype = 15 then
// nametype = hex 0F => Read name here directly
Nick := func.MemReadString(address+dist_name )
else
begin
// nametype = other value => Read address here
remoteadr := func.ReadMemInteger(address+dist_name );
// then read name in that address
Nick := func.MemReadString(remoteadr);
end;
// world is always there directly
World := func.MemReadString(address+dist_world );
// check if this char was the current char:
if (i=ClientSelectedCharId) then
begin
ClientSelectedCharName:=Nick;
ClientSelectedCharServer:=World;
end;
// add item to our list
StringList.Add(Nick+'|'+World);
address := address + charlist_dist;
end;
end;
StringList := TStringList.Create;
charlist_start:=$946CB0;
charlist_selected:=$946CFC;
charlist_end:=$946CB4;
charlist_dist:=72;
dist_name:=4;
dist_world:=32;
dist_name_size:=20;
dist_name_type:=24;
ClientSelectedCharId:=0;
ClientSelectedCharName:='';
ClientSelectedCharServer:='';
7598