Entwickler-Ecke

Dateizugriff - INI auslesen in Array


neuronet - Do 13.01.11 01:37
Titel: INI auslesen in Array
Ich glaub ich hab heute irgendwie nen Brett vorm Kopp...

Ich hab 'ne .INI in folgendem Format:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
[Character_Offset]
$CharacterOffset = 0x568

[Life]
$Static    = 0x016BFAD4
$Offset_1  = 0x7B8
$Offset_2  = 0xC
$Offset_3  = 0x30
$Offset_4  = 0x24C8

[Mana]
$Static    = 0x016BFAD4
$Offset_1  = 0x7B8
$Offset_2  = 0xC
$Offset_3  = 0x30
$Offset_4  = 0x24CC

[Exp]
$Static    = 0x016BFAD4
$Offset_1  = 0x7B8
$Offset_2  = 0xC
$Offset_3  = 0x30
$Offset_4  = 0x24B8


Die einzelnen "Sections" sind vom Namen her bekannt und sollen jeweils in ein 1D-Array eingelesen werden, um mit der folgenden Funktion ausgewertet werden:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
function PointerSolve(Process: THandle; p_array: array of integer):integer;
var
  pointercount: integer;
  i: integer;
  base_addr: integer;
  temp: integer;
  Wert:DWORD  ;
begin
  pointercount:=length(p_array);
  base_addr:=p_array[0];
  for I := 1 to pointercount-1 do
  begin
    ReadProcessMemory(Process, ptr(base_addr), @temp, 4, Wert);
    base_addr:= temp + p_array[i];
  end;
  result:=base_addr;
end;


Irgendwie raff ichs grad net die INI auszulesen...

:autsch:


Narses - Do 13.01.11 02:02

Moin!

user profile iconneuronet hat folgendes geschrieben Zum zitierten Posting springen:
Die einzelnen "Sections" sind vom Namen her bekannt und sollen jeweils in ein 1D-Array eingelesen werden, um mit der folgenden Funktion ausgewertet werden:
Was hat denn der Code mit der INI-Datei zu tun? :gruebel:

user profile iconneuronet hat folgendes geschrieben Zum zitierten Posting springen:
Irgendwie raff ichs grad net die INI auszulesen...
Wo ist denn das Problem, notfalls Umgangssprachlich beschrieben? :nixweiss: Ist die INI immer so aufgebaut, bekannter (=konstanter) Section-Name und Keys?

cu
Narses


neuronet - Do 13.01.11 02:15

Der Code soll nur veranschaulichen, wie das array weiterverarbeitet wird, also dass ich die variablennamen in den sections keinesfalls mit drin haben darf.

Die sections sind immer so aufgebaut. mal mit mehr und mal mit weniger variablen.


Narses - Do 13.01.11 02:24

Moin!

user profile iconneuronet hat folgendes geschrieben Zum zitierten Posting springen:
Die sections sind immer so aufgebaut. mal mit mehr und mal mit weniger variablen.
Kriegst du die Dateien geliefert oder ist das deine Kreation? (zielt darauf ab, ob man die auch noch etwas ändern könnte)

cu
Narses


neuronet - Do 13.01.11 02:27

Der INI-Aufbau kann ggf. geändert werden.

Die INI wird eh nur durch ein script aus ner Cheat-Engine XML Tabelle generiert....


Narses - Do 13.01.11 02:32

Moin!

Dann würde ich vorschlagen, das so zu machen:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
[Character_Offset]
$CharacterOffset = 0x568

[Life]
$Static    = 0x016BFAD4
$Offset_count = 4
$Offset_1  = 0x7B8
$Offset_2  = 0xC
$Offset_3  = 0x30
$Offset_4  = 0x24C8
Damit sollte es dann recht einfach sein. :idea: ;)

cu
Narses


neuronet - Do 13.01.11 02:36

Hmmm. Die Anzahl der Offsets kriege ich ja ggf. über length(array) raus..

Das war mir grad partout nich innen kopp geht is, wie ich nun die werte allgemein in ein eindimensionales array reinkriege... also nur die werte der variablen ohne den bezeichner davor.

mit IniFiles.Tinifile.readsection liest er mir ja auch die variablenbezeichner mit ein...


Narses - Do 13.01.11 02:40

Moin!

user profile iconneuronet hat folgendes geschrieben Zum zitierten Posting springen:
Hmmm. Die Anzahl der Offsets kriege ich ja ggf. über length(array) raus..
Ja, aber erst, wenn du die INI-Datei schon gelesen hast. :zwinker:

user profile iconneuronet hat folgendes geschrieben Zum zitierten Posting springen:
Das war mir grad partout nich innen kopp geht is, wie ich nun die werte allgemein in ein eindimensionales array reinkriege... also nur die werte der variablen ohne den bezeichner davor.
Du musst in einer Schleife die Key-Namen erzeugen und einzeln lesen, deshalb ja das Count. :idea:

user profile iconneuronet hat folgendes geschrieben Zum zitierten Posting springen:
mit IniFiles.Tinifile.readsection liest er mir ja auch die variablenbezeichner mit ein...
Damit kommst du hier nicht weiter. Sofern die Section-Namen wirklich bekannt sind... :? (wenn es darum geht, dass auch die Sections als Daten anzusehen sind und unklar ist, welche Sections in einer INI sind, dann solltest du die INI-Datei ganz anders aufbauen - und dich auch gleich fragen, ob das INI-Format dafür überhaupt geeignet ist)

cu
Narses


neuronet - Do 13.01.11 02:43

Für Konstruktive vorschläge bin ich immer zu haben...

Der Dateiaufbau selber ist mir eigentlich wurscht, da ich diese über ein script selber erzeuge.

nur muss ich die werte eben iwie jeweils in ein array reinbekommen um die aktuelle speicheradresse berechnen zu können (und ggf. einzelne offsets zu manipulieren).


Narses - Do 13.01.11 02:47

Moin!

Wat is denn nu mit den Sections, sind das immer nur "Life, Mana, Exp" oder werden die Section-Namen hier (mal wieder) als Datenlager missbraucht? ;)

cu
Narses


neuronet - Do 13.01.11 02:49

Die Section-Namen Bezeichnen eigentlich nur die Pointer Arrays.

Jede Section enthält Static- und Offsets von Speicheradressen, die dynamisch berechnet werden müsssen...


Narses - Do 13.01.11 02:50

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
sind das immer nur "Life, Mana, Exp"


neuronet - Do 13.01.11 02:52

Ach so... :autsch:

Nein.. gibt auch noch andere, aber die sind alle immer gleich, also ändern sich nicht.

Also Life, Mana, Exp, Char_1_Invi_1, Bank_X, Map_X...


Narses - Do 13.01.11 03:01

Moin!

Dann so vielleicht? :nixweiss:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
type
  TIntArray = array of Integer;

function GetIntArrayFromIni(AIniFile: TIniFile; const ASection: String): TIntArray;
  var
    i, len: Integer;
begin
  len := StrToIntDef(AIniFile.ReadString(ASection, '$Offset_count'''), 0);
  SetLength(Result, len);
  for i := 1 to len do
    Result[i-1] := StrToIntDef(AIniFile.ReadString(ASection, Format('$Offset_%d', [i]), ''), 0);
end;
Wobei ich gerade unsicher bin, ob StrToIntX() mit der '0x'-Notation was anfangen kann, ggfs. durch '$' ersetzen. :idea:

cu
Narses


neuronet - Do 13.01.11 03:26

Gute Idee.. aber ich sagte ja.. Brett vor Kopp...

INI Datei so ändern:


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
[Life]
$016BFAD4
$7B8
$C
$30
$24C8

[Mana]
$016BFAD4
$7B8
$C
$30
$24CC


dann mit readsection einlesen und mit der folgenden funktion in ein normales array umpacken...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function CopyListToArray(List: TStringList): TStringArray;
var
  nCount: Integer;
begin
  SetLength(result, List.Count);

  for nCount := Low(result) to High(result) do
    result[nCount] := List.Strings[nCount];
end;


und die berechnungsfunktion um nen strtoint ergänzen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
function PointerSolve(Process: THandle; p_array: array of string):integer;
var
  pointercount: integer;
  i: integer;
  base_addr: integer;
  temp: integer;
  Wert:DWORD  ;
begin
  pointercount:=length(p_array);
  base_addr:=stritoint(p_array[0]);
  for I := 1 to pointercount-1 do
  begin
    ReadProcessMemory(Process, ptr(base_addr), @temp, 4, Wert);
    base_addr:= temp + strtoint(p_array[i]);
  end;
  result:=base_addr;
end;


P.S.: StrToInt kennt auch die 0x Notation...

Trotzdem vielen Dank Narses...