Zapis pliku w IMG - jak zrobić odczyt?

0

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

0

Po pierwsze, powinno być raczej "packed record" a nie "record".
Po drugie, w czym dokładnie problem?

0

Było record, więc nie zmieniałem. W czym problem?
"Zapis pliku w IMG - jak zrobić odczyt?"
"I moje pytanie jest takie: jak go przerobić, aby wyciągał pliki z pliku IMG?"

Czyli mam kod zapisujący plik do IMG i potrzebuję kodu, który robi odwrotnie - odczytuje dowolny plik z pliku IMG, a dokładniej pliku z GTA SA - gta3.img.

1 użytkowników online, w tym zalogowanych: 0, gości: 1