Witam. Tworzę aplikację modującą, a dokładniej podmieniającą pliki w gta3.img, w GTA SA. Mam taki kod:
type
//nagłówek pliku archiwum *.img
TNaglIMG = record
iZnacznik: array [0..3] of Char; //znacznik archiwum - zawsze VER2
iLiczbaPl: Integer; //liczba plików w archiwum
end;
//nagłówek dla każdego pliku zawartego w archiwum
TNaglPliku = record
pOffset: Integer; //offset w archiwum do danych pliku (odczytaną wartość mnożymy przez 2048)
pRozmiar: Integer; //rozmiar danych pliku (odczytaną wartość mnożymy przez 2048)
pNazwa: array [0..23] of Char; //nazwa pliku
end;
function ZamienPlikWArchiwum(ScPlikuArchiwum, ScPlikuDoZamiany: String): Boolean; stdcall;
var
i, OffsetNowyPlik: Integer;
NaglIMG: TNaglIMG;
NaglPliku: TNaglPliku;
strIMG, strPlik: TFileStream;
b: Byte;
begin
b := 0;
strIMG := TFileStream.Create(ScPlikuArchiwum, fmOpenReadWrite);
strPlik := TFileStream.Create(ScPlikuDoZamiany, fmOpenRead);
try
strIMG.Position := 0;
strPlik.Position := 0;
//odczyt nagłówka archiwum
strIMG.ReadBuffer(NaglIMG, SizeOf(NaglIMG));
//kontynuuje działanie tylko jeżeli poprawny znacznik
if NaglIMG.iZnacznik = 'VER2' then
begin
//rozmiar pliku musi być podzielny przez 2048 - orginalny będzie, ale modyfikowany
//niekoniecznie. Jeżeli nie jest - dodawane są zera, aż do uzyskania odpowiedniego
//rozmiaru.
if strIMG.Size mod 2048 > 0 then
begin
strIMG.Seek(0, soFromEnd);
while strIMG.Size mod 2048 > 0 do
strIMG.Write(b, 1);
end;
strIMG.Seek(0, soFromEnd);
//aktualny rozmiar strumienia będzie offsetem do zamienionego pliku
OffsetNowyPlik := strIMG.Size;
//dodanie nowego pliku na końcu strumienia
strIMG.CopyFrom(strPlik, strPlik.size);
//poprawienie rozmiaru
while strIMG.Size mod 2048 > 0 do
strIMG.Write(b, 1);
//pozostało znaleźć i poprawić nagłówek (w sumie to należało rozpocząć od znalezienia nagłówka
//bo jak go nie ma to albo jest uszkodzony plik .img, albo nadano złą nazwę plikowi do zamiany)
strIMG.seek(SizeOf(NaglIMG), soFromBeginning);
for i := 1 to NaglIMG.iLiczbaPl do
begin
strIMG.ReadBuffer(NaglPliku, SizeOf(NaglPliku));
//znaleziony nagłówek
if NaglPliku.pNazwa = ExtractFileName(ScPlikuDoZamiany) then
begin
//poprawienie danych nagłówka
NaglPliku.pOffset := OffsetNowyPlik div 2048;
NaglPliku.pRozmiar := (strIMG.Size - OffsetNowyPlik) div 2048;
strIMG.Seek(strIMG.Position - SizeOf(NaglPliku), soFromBeginning);
//zapis poprawionego nagłówka
strIMG.WriteBuffer(NaglPliku, SizeOf(NaglPliku));
Break;
end;
end;
end;
finally
strIMG.Free;
strPlik.Free;
end;
end;
I moje pytanie jest takie: jak go przerobić, aby wyciągał pliki z pliku IMG?
Z góry dziękuję
Pozdrawiam