人物包裹里的第1格子上的药品数量开始查找,
CE
注意在未找到数组之前 如果把第1格子上的物品全部移走,得重新再找。
第1格子上的红数量=[[[[[[924E0C]+1C]+20]+0B4C]+0C]0*4]+14
大瓶活血散=[[[[[[[00924E0C]+1C]+20]+B4C]+C]+0]+54]+C
其他偏移用 MemView(结构化内存监视器)遍历
包裹数组=[[[[00924E0C]+1c]+20]+B4C]
+10 包裹格子数量
+14 包裹格子数量上限
+C ???
包裹数组=[[[[[[0924E0C]+1C]+20]+B4C]+C]
包裹数组列表=[[[[[[0924E0C]+1C]+20]+B4C]+C]+EBX*4]
包裹对象=包裹数组列表
包裹属性=[包裹对象]+偏移
[+54]+C 名称
+4 类型
+8 ID号
+14 物品数量
+18 物品数量上限
+1C 价格(单价)
{冷却时间}
//
{此段代码需要hook的支持}
/// <summary>
/// {人物是在游戏当中还是小退}
/// </summary>
function InGame():Boolean;
var gameretn:DWORD;
begin
asm
mov eax,[$00924D48]
mov gameretn,eax
end;
if gameretn=0 then Result:=true{在游戏当中}
else if gameretn>=1 then Result:=False; {人物在角色选择界面}
end;
procedure TForm1.Button1Click(Sender: TObject);
/// <summary>
/// 包裹信息
/// </summary>
var
I :Integer;
packsack :PDWORD;
pckTmp :DWORD;
pckpck_id :PDWORD;
gdsAmount :PDWORD;
pck_amount:DWORD;
pck_kind :PDWORD;
pck_price :PDWORD;
pck_id :PDWORD;
pck_name :PDWORD;
pck_name1 :PWideChar;
pck_name2 :string;
begin
{
包裹数组=[[[[00924E0C]+1c]+20]+B4C]
+10 包裹格子数量
+14 包裹格子数量上限
+C ???
包裹数组=[[[[[[0924E0C]+1C]+20]+B4C]+C]
包裹数组列表=[[[[[[0924E0C]+1C]+20]+B4C]+C]+EBX*4]
包裹对象=包裹数组列表
包裹属性=[包裹对象]+偏移
[+54]+C 名称
+4 类型
+8 ID号
+14 物品数量
+18 物品数量上限
+1C 价格(单价)
} {冷却时间}
if InGame=False then Exit;
asm
mov eax,[$924E0C]
mov eax,[eax+$1c]
mov eax,[eax+$20]
mov eax,[eax+$b4c]
mov ecx,[eax+$10]
mov pck_amount,ecx//
mov ecx,[eax+$c]
mov pckTmp,ecx //
end;
self.Memo1.Clear;
for I:=0 to pck_amount-1 do
begin
packsack :=pointer(pckTmp+I*4);
pck_kind :=Pointer(packsack^+$4);
pck_id :=Pointer(packsack^+$8);
pck_price:=Pointer(packsack^+$1C);
gdsAmount:=Pointer(packsack^+$14);
if packsack^>0 then //当对象数组列表不为0的时候才添加
begin
if pck_kind^ in[0,3] then {裁缝物品 ,巧匠物品 }
begin
pck_name:=Pointer(packsack^+$DC);
pck_name1:=Pointer(pck_name^+$C);
pck_name2:=WideCharTostring(pck_name1);
end
else if pck_kind^ =15 then {武器类}
begin
pck_name:=Pointer(packsack^+$E4);
pck_name1:=Pointer(pck_name^+$C);
pck_name2:=WideCharTostring(pck_name1);
end
else if pck_kind^ in[8,9,22,23] then {9=药水类}
begin
pck_name:=Pointer(packsack^+$54);
pck_name1:=Pointer(pck_name^+$C);
pck_name2:=WideCharTostring(pck_name1);
end
else if pck_kind^ in[5,10,13,16,19,20,27,31,39] then {矿铲类,27传送石 宠物食物}
begin
pck_name:=Pointer(packsack^+$4C);
pck_name1:=Pointer(pck_name^+$4);
pck_name2:=WideCharTostring(pck_name1);
end
else if not pck_kind^ in[8,9,22,23,0,3,15,5,10,13,16,19,20,27,31,39] then Continue;
//当包裹里错误读不出来的名称 时间就会包错 //包里的物品被读取了2遍 只让它读一次
Self.memo1.lines.add(Format('ID %4X (%4d) 价格%8d %s',[pck_id^,gdsAmount^,(pck_price^)*(gdsAmount^),pck_name2]));
end;
end;
Self.Memo1.Hint:=Self.Memo1.Text;
end;
/// <summary>
/// {人物是在游戏当中还是小退}
/// </summary>
function InGame():Boolean;
var gameretn:DWORD;
begin
asm
mov eax,[$00924D48]
mov gameretn,eax
end;
if gameretn=0 then Result:=true{在游戏当中}
else if gameretn>=1 then Result:=False; {人物在角色选择界面}
end;
procedure TForm1.Button1Click(Sender: TObject);
/// <summary>
/// 包裹信息
/// </summary>
var
I :Integer;
packsack :PDWORD;
pckTmp :DWORD;
pckpck_id :PDWORD;
gdsAmount :PDWORD;
pck_amount:DWORD;
pck_kind :PDWORD;
pck_price :PDWORD;
pck_id :PDWORD;
pck_name :PDWORD;
pck_name1 :PWideChar;
pck_name2 :string;
begin
{
包裹数组=[[[[00924E0C]+1c]+20]+B4C]
+10 包裹格子数量
+14 包裹格子数量上限
+C ???
包裹数组=[[[[[[0924E0C]+1C]+20]+B4C]+C]
包裹数组列表=[[[[[[0924E0C]+1C]+20]+B4C]+C]+EBX*4]
包裹对象=包裹数组列表
包裹属性=[包裹对象]+偏移
[+54]+C 名称
+4 类型
+8 ID号
+14 物品数量
+18 物品数量上限
+1C 价格(单价)
} {冷却时间}
if InGame=False then Exit;
asm
mov eax,[$924E0C]
mov eax,[eax+$1c]
mov eax,[eax+$20]
mov eax,[eax+$b4c]
mov ecx,[eax+$10]
mov pck_amount,ecx//
mov ecx,[eax+$c]
mov pckTmp,ecx //
end;
self.Memo1.Clear;
for I:=0 to pck_amount-1 do
begin
packsack :=pointer(pckTmp+I*4);
pck_kind :=Pointer(packsack^+$4);
pck_id :=Pointer(packsack^+$8);
pck_price:=Pointer(packsack^+$1C);
gdsAmount:=Pointer(packsack^+$14);
if packsack^>0 then //当对象数组列表不为0的时候才添加
begin
if pck_kind^ in[0,3] then {裁缝物品 ,巧匠物品 }
begin
pck_name:=Pointer(packsack^+$DC);
pck_name1:=Pointer(pck_name^+$C);
pck_name2:=WideCharTostring(pck_name1);
end
else if pck_kind^ =15 then {武器类}
begin
pck_name:=Pointer(packsack^+$E4);
pck_name1:=Pointer(pck_name^+$C);
pck_name2:=WideCharTostring(pck_name1);
end
else if pck_kind^ in[8,9,22,23] then {9=药水类}
begin
pck_name:=Pointer(packsack^+$54);
pck_name1:=Pointer(pck_name^+$C);
pck_name2:=WideCharTostring(pck_name1);
end
else if pck_kind^ in[5,10,13,16,19,20,27,31,39] then {矿铲类,27传送石 宠物食物}
begin
pck_name:=Pointer(packsack^+$4C);
pck_name1:=Pointer(pck_name^+$4);
pck_name2:=WideCharTostring(pck_name1);
end
else if not pck_kind^ in[8,9,22,23,0,3,15,5,10,13,16,19,20,27,31,39] then Continue;
//当包裹里错误读不出来的名称 时间就会包错 //包里的物品被读取了2遍 只让它读一次
Self.memo1.lines.add(Format('ID %4X (%4d) 价格%8d %s',[pck_id^,gdsAmount^,(pck_price^)*(gdsAmount^),pck_name2]));
end;
end;
Self.Memo1.Hint:=Self.Memo1.Text;
end;