From: DeaDDooMER Date: Sun, 6 Jan 2019 14:35:49 +0000 (+0300) Subject: more zip related fixes for packmap X-Git-Url: http://deadsoftware.ru/gitweb?p=d2df-editor.git;a=commitdiff_plain;h=a140ef8433c5e5cdf3d2ec4a6343c5380535e200 more zip related fixes for packmap --- diff --git a/src/editor/f_packmap.pas b/src/editor/f_packmap.pas index 0c361c5..cdbe105 100644 --- a/src/editor/f_packmap.pas +++ b/src/editor/f_packmap.pas @@ -53,7 +53,7 @@ implementation uses BinEditor, WADEDITOR, g_map, MAPREADER, MAPWRITER, MAPSTRUCT, - f_main, math, g_language, g_resources; + f_main, math, g_language, g_resources, e_log; {$R *.lfm} @@ -74,11 +74,16 @@ function ProcessResource(wad_to, section_to, filename, section, resource: String var data: Pointer; res, len: Integer; + us, un: String; begin + Result := True; if filename = '' then - g_ProcessResourceStr(OpenedMap, @filename, nil, nil) + g_GetResourceSection(OpenedMap, filename, us, un) else filename := EditorDir + 'wads/' + filename; + e_WriteLog('ProcessResource: "' + wad_to + '" "' + section_to + '" "' + filename + '" "' + section + '" "' + resource + '"', MSG_NOTIFY); + + if resource = '' then Exit; g_ReadResource(filename, section, resource, data, len); if data <> nil then @@ -91,7 +96,6 @@ begin ASSERT(res = 0) end; FreeMem(data); - Result := True end else begin @@ -103,6 +107,7 @@ end; procedure TPackMapForm.bPackClick(Sender: TObject); var + WadFile: String; mr: TMapReader_1; mw: TMapWriter_1; data: Pointer; @@ -127,9 +132,9 @@ begin if data = nil then Exit; -// Не перезаписывать WAD, а дополнить: if not cbAdd.Checked then begin + (* Overwrite wad *) if FileExists(eWAD.Text) then begin if FileExists(eWAD.Text + '.bak0') then @@ -154,7 +159,7 @@ begin if IsSpecialTexture(res) then Continue; - g_ProcessResourceStr(res, @filename, @section, @resource); + g_GetResourceSection(res, filename, section, resource); // Не записывать стандартные текстуры: if (not cbNonStandart.Checked) or @@ -182,7 +187,7 @@ begin if cbSky.Checked then begin res := win2utf(header.SkyName); - g_ProcessResourceStr(res, @filename, @section, @resource); + g_GetResourceSection(res, filename, section, resource); // Не записывать стандартное небо: if (not cbNonStandart.Checked) or @@ -207,7 +212,7 @@ begin if cbMusic.Checked then begin res := win2utf(header.MusicName); - g_ProcessResourceStr(res, @filename, @section, @resource); + g_GetResourceSection(res, filename, section, resource); // Не записывать стандартную музыку: if (not cbNonStandart.Checked) or @@ -267,7 +272,7 @@ begin if res = '' then Break; - g_ProcessResourceStr(res, @filename, @section, @resource); + g_GetResourceSection(res, @filename, @section, @resource); // Не записывать стандартные дополнительные текстуры: if (not cbNonStandart.Checked) or diff --git a/src/editor/g_resources.pas b/src/editor/g_resources.pas index 880b727..9605b1a 100644 --- a/src/editor/g_resources.pas +++ b/src/editor/g_resources.pas @@ -26,6 +26,8 @@ interface res = 0 when ok **) + procedure g_GetResourceSection (path: String; out wad, section, name: String); + procedure g_ReadResource (wad, section, name: String; out data: PByte; out len: Integer); procedure g_ReadSubResource (wad, section0, name0, section1, name1: String; out data: PByte; out len: Integer); procedure g_DeleteResource (wad, section, name: String; out res: Integer); @@ -34,15 +36,62 @@ interface implementation - uses sfs, xstreams, dfzip, utils, Classes, SysUtils, WADEDITOR; + uses sfs, xstreams, dfzip, utils, Classes, SysUtils, WADEDITOR, e_log; + + function NoTrailing (path: String): String; + var i: Integer; + begin + i := Length(path); + while (i > 0) and ((path[i] = '/') or (path[i] = '\')) do dec(i); + result := Copy(path, 1, i) + end; + + function g_CleanPath (path: String; sys: Boolean = False): String; + var i, len: Integer; + begin + i := 1; + result := ''; + len := Length(path); + (* drop separators at the end *) + while (len > 1) and ((path[i] = '/') or (path[i] = '\')) do dec(len); + while i <= len do + begin + while (i <= len) and (path[i] <> '/') and (path[i] <> '\') do + begin + result := result + path[i]; + inc(i) + end; + if i <= len then + if sys then + result := result + DirectorySeparator + else + result := result + '/'; + inc(i); + while (i <= len) and ((path[i] = '/') or (path[i] = '\')) do inc(i) + end; + end; + + procedure g_GetResourceSection (path: String; out wad, section, name: String); + var i, j, len: Integer; + begin + len := Length(path); + i := len; + while (i > 0) and (path[i] <> '/') and (path[i] <> '\') do dec(i); + name := Copy(path, i + 1, len); + j := i; + while (i > 0) and (path[i] <> ':') do dec(i); + section := Copy(path, i + 1, j - i - 1); + wad := Copy(path, 1, i - 1); + end; procedure g_AddResourceToDFWAD (wad, section, name: String; const data: PByte; len: Integer; out res: Integer); var f: TWADEditor_1; begin res := 1; (* error *) wad := utf2win(wad); - section := utf2win(section); + section := utf2win(NoTrailing(section)); name := utf2win(name); + ASSERT(name <> ''); f := TWADEditor_1.Create(); if not f.ReadFile(wad) then begin @@ -67,7 +116,7 @@ implementation i, n, len0: Integer; data0: PByte; list: TSFSFileList; - tmp, entry: String; + tmp, path: String; ts: TFileStream; dir: array of TFileInfo; @@ -84,8 +133,9 @@ implementation begin res := 1; wad := ExpandFileName(wad); - section := utf2win(section); + section := utf2win(NoTrailing(section)); name := utf2win(name); + ASSERT(name <> ''); list := SFSFileList(wad); tmp := wad + '.tmp' + IntToStr(Random(100000)); ts := TFileStream.Create(tmp, fmCreate); @@ -95,14 +145,16 @@ implementation begin for i := 0 to list.Count - 1 do begin - if (list.Files[i].path <> section) or (list.Files[i].name <> section) then + path := NoTrailing(list.Files[i].path); + if (path <> section) or (list.Files[i].name <> section) then begin - g_ReadResource(wad, list.Files[i].path, list.Files[i].name, data0, len0); - if list.Files[i].path = '' then - entry := list.Files[i].name + g_ReadResource(wad, path, list.Files[i].name, data0, len0); + ASSERT(data0 <> nil); + if path = '' then + path := list.Files[i].name else - entry := list.Files[i].path + '/' + list.Files[i].name; - Add(entry, data0, len0); + path := path + '/' + list.Files[i].name; + Add(path, data0, len0); FreeMem(data0) end end; @@ -110,11 +162,11 @@ implementation end; if section = '' then - entry := name + path := name else - entry := section + '/' + name; + path := section + '/' + name; + Add(path, data, len); - Add(entry, data, len); dfzip.writeCentralDir(ts, dir); ts.Free; @@ -131,8 +183,10 @@ implementation procedure g_AddResource (wad, section, name: String; const data: PByte; len: Integer; out res: Integer); var ext: String; begin + ASSERT(name <> ''); res := 2; (* unknown type *) ext := LowerCase(SysUtils.ExtractFileExt(wad)); + e_WriteLog('g_AddResource "' + wad + '" "' + section + '" "' + name + '"', MSG_NOTIFY); if ext = '.wad' then g_AddResourceToDFWAD(wad, section, name, data, len, res) else if (ext = '.pk3') or (ext = '.zip') or (ext = '.dfzip') then @@ -142,8 +196,9 @@ implementation procedure g_DeleteResourceFromDFWAD (wad, section, name: String; out res: Integer); var f: TWADEditor_1; begin + ASSERT(name <> ''); res := 1; (* error *) - section := utf2win(section); + section := utf2win(NoTrailing(section)); name := utf2win(name); f := TWADEditor_1.Create; if not f.ReadFile(wad) then @@ -163,7 +218,7 @@ implementation data0: PByte; i, n, len0: Integer; list: TSFSFileList; - tmp, entry: String; + tmp, path: String; ts: TFileStream; dir: array of TFileInfo; @@ -180,8 +235,9 @@ implementation begin res := 1; wad := ExpandFileName(wad); - section := utf2win(section); + section := utf2win(NoTrailing(section)); name := utf2win(name); + ASSERT(name <> ''); list := SFSFileList(wad); tmp := wad + '.tmp' + IntToStr(Random(100000)); ts := TFileStream.Create(tmp, fmCreate); @@ -191,14 +247,16 @@ implementation begin for i := 0 to list.Count - 1 do begin - if (list.Files[i].path <> section) or (list.Files[i].name <> section) then + path := NoTrailing(list.Files[i].path); + if (path <> section) or (list.Files[i].name <> section) then begin - g_ReadResource(wad, list.Files[i].path, list.Files[i].name, data0, len0); - if list.Files[i].path = '' then - entry := list.Files[i].name + g_ReadResource(wad, path, list.Files[i].name, data0, len0); + ASSERT(data0 <> nil); + if path = '' then + path := list.Files[i].name else - entry := list.Files[i].path + '/' + list.Files[i].name; - Add(entry, data0, len0); + path := path + '/' + list.Files[i].name; + Add(path, data0, len0); FreeMem(data0) end end; @@ -221,11 +279,12 @@ implementation procedure g_DeleteResource (wad, section, name: String; out res: Integer); var ext: String; begin + ASSERT(name <> ''); res := 2; (* unknown type *) ext := LowerCase(SysUtils.ExtractFileExt(wad)); if ext = '.wad' then g_DeleteResourceFromDFWAD(wad, section, name, res) - else if (ext = '.pk3') or (ext = '.zip') or (ext = '.dfzip') then + else if (ext = '.dfz') or (ext = '.pk3') or (ext = '.zip') or (ext = '.dfzip') then g_DeleteResourceFromZip(wad, section, name, res) end; @@ -233,8 +292,9 @@ implementation var str: String; stream: TStream; begin res := 1; - section := utf2win(section); + section := utf2win(NoTrailing(section)); name := utf2win(name); + ASSERT(name <> ''); if SFSAddDataFileTemp(wad, TRUE) then begin str := SFSGetLastVirtualName(section + '\' + name); @@ -251,13 +311,16 @@ implementation procedure g_ReadResource (wad, section, name: String; out data: PByte; out len: Integer); var stream: TStream; str: String; i: Integer; begin - section := utf2win(section); + e_WriteLog('g_ReadResource: "' + wad + '" "' + section + '" "' + name + '"', MSG_NOTIFY); + section := utf2win(NoTrailing(section)); name := utf2win(name); data := nil; len := 0; + //ASSERT(name <> ''); + if name = '' then Exit; (* SKY can be void *) if SFSAddDataFileTemp(wad, TRUE) then begin - str := SFSGetLastVirtualName(section + '\' + name); + str := SFSGetLastVirtualName(section + '/' + name); stream := SFSFileOpen(wad + '::' + str); if stream <> nil then begin @@ -278,11 +341,13 @@ implementation begin data := nil; len := 0; - if (wad = '') OR (section0 = '') OR (name0 = '') OR (section1 = '') OR (name1 = '') then Exit; - section0 := utf2win(section0); + section0 := utf2win(NoTrailing(section0)); name0 := utf2win(name0); - section1 := utf2win(section1); + section1 := utf2win(NoTrailing(section1)); name1 := utf2win(name1); + //ASSERT(name0 <> ''); + //ASSERT(name1 <> ''); + if (wad = '') OR (name0 = '') OR (name1 = '') then Exit; (* ??? *) if SFSAddDataFileTemp(wad, TRUE) then begin str0 := SFSGetLastVirtualName(section0 + '\' + name0); diff --git a/src/shared/dfzip.pas b/src/shared/dfzip.pas index ade97a5..5b00a3b 100644 --- a/src/shared/dfzip.pas +++ b/src/shared/dfzip.pas @@ -328,7 +328,7 @@ begin ds.position := nfoofs; writeInt(ds, LongWord(result.crc)); // crc32 ds.position := oldofs; - write('(S) '); + //write('(S) '); end; end;