summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0bec5f3)
raw | patch | inline | side by side (parent: 0bec5f3)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Sat, 12 Oct 2019 00:55:59 +0000 (03:55 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Sat, 12 Oct 2019 15:54:12 +0000 (18:54 +0300) |
src/game/g_game.pas | patch | blob | history | |
src/game/g_res_downloader.pas | patch | blob | history | |
src/shared/utils.pas | patch | blob | history |
diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 46251bb7d3e2684ec69a340f2ad415de97f6f821..43ccf4ff22e1b3eb6ddce0e748c52477a87007e0 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
gGameSettings.Options := InMsg.ReadLongWord();
T := InMsg.ReadLongWord();
- newResPath := g_Res_SearchSameWAD(MapsDir, WadName, gWADHash);
- if newResPath = '' then
+ //newResPath := g_Res_SearchSameWAD(MapsDir, WadName, gWADHash);
+ //if newResPath = '' then
begin
- g_Game_SetLoadingText(_lc[I_LOAD_DL_RES], 0, False);
+ //g_Game_SetLoadingText(_lc[I_LOAD_DL_RES], 0, False);
newResPath := g_Res_DownloadMapWAD(WadName, gWADHash);
if newResPath = '' then
begin
var
gWAD: String;
begin
- if LowerCase(NewWAD) = LowerCase(gGameSettings.WAD) then
- Exit;
- if not g_Game_IsClient then
+ if not g_Game_IsClient then Exit;
+
+ gWAD := g_Res_DownloadMapWAD(ExtractFileName(NewWAD), WHash);
+ if gWAD = '' then
+ begin
+ g_Game_Free();
+ g_FatalError(Format(_lc[I_GAME_ERROR_MAP_WAD], [ExtractFileName(NewWAD)]));
Exit;
+ end;
+
+ NewWAD := ExtractRelativePath(MapsDir, gWAD);
+ g_Game_LoadWAD(NewWAD);
+
+ {
+ if LowerCase(NewWAD) = LowerCase(gGameSettings.WAD) then Exit;
gWAD := g_Res_SearchSameWAD(MapsDir, ExtractFileName(NewWAD), WHash);
if gWAD = '' then
begin
end;
NewWAD := ExtractRelativePath(MapsDir, gWAD);
g_Game_LoadWAD(NewWAD);
+ }
end;
procedure g_Game_RestartRound(NoMapRestart: Boolean = False);
index 72717573b0b9b39303a0d8f4d707891ac350c5b1..d9cf5684c508c43eed986b311e1dcad0aba5a6f9 100644 (file)
uses g_language, sfs, utils, wadreader, g_game, hashtable;
-const DOWNLOAD_DIR = 'downloads';
-
-type
- TFileInfo = record
- diskName: AnsiString; // lowercased
- baseName: AnsiString; // lowercased
- md5: TMD5Digest;
- md5valid: Boolean;
- nextBaseNameIndex: Integer;
- end;
+//const DOWNLOAD_DIR = 'downloads';
var
- knownFiles: array of TFileInfo;
- knownHash: THashStrInt = nil; // key: base name; value: index
- scannedDirs: THashStrInt = nil; // key: lowercased dir name
replacements: THashStrStr = nil;
-function findKnownFile (diskName: AnsiString): Integer;
-var
- idx: Integer;
- baseName: AnsiString;
-begin
- result := -1;
- if not assigned(knownHash) then exit;
- if (length(diskName) = 0) then exit;
- baseName := toLowerCase1251(ExtractFileName(diskName));
- if (not knownHash.get(baseName, idx)) then exit;
- if (idx < 0) or (idx >= length(knownFiles)) then raise Exception.Create('wutafuck?');
- while (idx >= 0) do
- begin
- if (strEquCI1251(knownFiles[idx].diskName, diskName)) then begin result := idx; exit; end; // i found her!
- idx := knownFiles[idx].nextBaseNameIndex;
- end;
-end;
-
-
-function addKnownFile (diskName: AnsiString): Integer;
-var
- idx: Integer;
- lastIdx: Integer = -1;
- baseName: AnsiString;
- fi: ^TFileInfo;
-begin
- result := -1;
- if not assigned(knownHash) then knownHash := THashStrInt.Create();
- if (length(diskName) = 0) then exit;
- baseName := toLowerCase1251(ExtractFileName(diskName));
- if (length(baseName) = 0) then exit;
- // check if we already have this file
- if (knownHash.get(baseName, idx)) then
- begin
- if (idx < 0) or (idx >= length(knownFiles)) then raise Exception.Create('wutafuck?');
- while (idx >= 0) do
- begin
- if (strEquCI1251(knownFiles[idx].diskName, diskName)) then
- begin
- // already here
- result := idx;
- exit;
- end;
- lastIdx := idx;
- idx := knownFiles[idx].nextBaseNameIndex;
- end;
- end;
- // this file is not there, append it
- idx := length(knownFiles);
- result := idx;
- SetLength(knownFiles, idx+1); // sorry
- fi := @knownFiles[idx];
- fi.diskName := diskName;
- fi.baseName := baseName;
- fi.md5valid := false;
- fi.nextBaseNameIndex := -1;
- if (lastIdx < 0) then
- begin
- // totally new one
- knownHash.put(baseName, idx);
- end
- else
- begin
- knownFiles[lastIdx].nextBaseNameIndex := idx;
- end;
-end;
-
-
-function getKnownFileWithMD5 (diskDir: AnsiString; baseName: AnsiString; const md5: TMD5Digest): AnsiString;
-var
- idx: Integer;
-begin
- result := '';
- if not assigned(knownHash) then exit;
- if (not knownHash.get(toLowerCase1251(baseName), idx)) then exit;
- if (idx < 0) or (idx >= length(knownFiles)) then raise Exception.Create('wutafuck?');
- while (idx >= 0) do
- begin
- if (strEquCI1251(knownFiles[idx].diskName, IncludeTrailingPathDelimiter(diskDir)+baseName)) then
- begin
- if (not knownFiles[idx].md5valid) then
- begin
- knownFiles[idx].md5 := MD5File(knownFiles[idx].diskName);
- knownFiles[idx].md5valid := true;
- end;
- if (MD5Match(knownFiles[idx].md5, md5)) then
- begin
- result := knownFiles[idx].diskName;
- exit;
- end;
- end;
- idx := knownFiles[idx].nextBaseNameIndex;
- end;
-end;
-
-
// call this before downloading a new map from a server
procedure g_Res_ClearReplacementWads ();
begin
end;
-procedure scanDir (const dirName: AnsiString; calcMD5: Boolean);
+function scanDir (dirName: AnsiString; baseName: AnsiString; const resMd5: TMD5Digest): AnsiString;
var
searchResult: TSearchRec;
dfn: AnsiString;
- idx: Integer;
+ md5: TMD5Digest;
+ dirs: array of AnsiString;
+ f: Integer;
begin
- if not assigned(scannedDirs) then scannedDirs := THashStrInt.Create();
- dfn := toLowerCase1251(IncludeTrailingPathDelimiter(dirName));
- if scannedDirs.has(dfn) then exit;
- scannedDirs.put(dfn, 42);
+ result := '';
+ SetLength(dirs, 0);
+ if (length(baseName) = 0) then exit;
+ dirName := IncludeTrailingPathDelimiter(dirName);
+ e_LogWritefln('scanning dir `%s` for file `%s`...', [dirName, baseName]);
- if (FindFirst(dirName+'/*', faAnyFile, searchResult) <> 0) then exit;
+ // scan files
+ if (FindFirst(dirName+'*', faAnyFile, searchResult) <> 0) then exit;
try
repeat
- if (searchResult.Attr and faDirectory) = 0 then
+ if ((searchResult.Attr and faDirectory) = 0) then
begin
- dfn := dirName+'/'+searchResult.Name;
- idx := addKnownFile(dfn);
- if (calcMD5) and (idx >= 0) then
+ if (isWadNamesEqu(searchResult.Name, baseName)) then
begin
- if (not knownFiles[idx].md5valid) then
+ dfn := dirName+searchResult.Name;
+ if FileExists(dfn) then
begin
- knownFiles[idx].md5 := MD5File(knownFiles[idx].diskName);
- knownFiles[idx].md5valid := true;
+ e_LogWritefln(' found `%s`...', [dfn]);
+ md5 := MD5File(dfn);
+ if MD5Match(md5, resMd5) then
+ begin
+ e_LogWritefln(' MATCH `%s`...', [dfn]);
+ SetLength(dirs, 0);
+ result := dfn;
+ exit;
+ end;
end;
end;
end
- else if (searchResult.Name <> '.') and (searchResult.Name <> '..') then
+ else
begin
- scanDir(IncludeTrailingPathDelimiter(dirName)+searchResult.Name, calcMD5);
+ if (searchResult.Name <> '.') and (searchResult.Name <> '..') then
+ begin
+ dfn := dirName+searchResult.Name;
+ SetLength(dirs, Length(dirs)+1);
+ dirs[length(dirs)-1] := dfn;
+ end;
end;
until (FindNext(searchResult) <> 0);
finally
FindClose(searchResult);
end;
-end;
-
-function CompareFileHash(const filename: AnsiString; const resMd5: TMD5Digest): Boolean;
-var
- gResHash: TMD5Digest;
- fname: AnsiString;
-begin
- fname := findDiskWad(filename);
- if length(fname) = 0 then begin result := false; exit; end;
- gResHash := MD5File(fname);
- Result := MD5Match(gResHash, resMd5);
-end;
-
-function CheckFileHash(const path, filename: AnsiString; const resMd5: TMD5Digest): Boolean;
-var
- fname: AnsiString;
-begin
- fname := findDiskWad(path+filename);
- if length(fname) = 0 then begin result := false; exit; end;
- Result := FileExists(fname) and CompareFileHash(fname, resMd5);
+ // scan subdirs
+ for f := 0 to High(dirs) do
+ begin
+ dfn := dirs[f];
+ result := scanDir(dfn, baseName, resMd5);
+ if (length(result) <> 0) then begin SetLength(dirs, 0); exit; end;
+ end;
+ SetLength(dirs, 0);
end;
function g_Res_SearchResWad (asMap: Boolean; fname: AnsiString; const resMd5: TMD5Digest): AnsiString;
-var
- f: Integer;
begin
result := '';
//if not assigned(scannedDirs) then scannedDirs := THashStrInt.Create();
if (asMap) then
begin
- if CheckFileHash(GameDir+'/maps', fname, resMd5) then
- begin
- result := findDiskWad(GameDir+'/maps/'+fname);
- if (length(result) <> 0) then exit;
- end;
- scanDir(GameDir+'/maps/downloads', true);
+ result := scanDir(GameDir+'/maps', ExtractFileName(fname), resMd5);
end
else
begin
- if CheckFileHash(GameDir+'/wads', fname, resMd5) then
- begin
- result := findDiskWad(GameDir+'/wads/'+fname);
- if (length(result) <> 0) then exit;
- end;
- scanDir(GameDir+'/wads/downloads', true);
+ result := scanDir(GameDir+'/wads', ExtractFileName(fname), resMd5);
end;
- for f := Low(knownFiles) to High(knownFiles) do
- begin
- if (not knownFiles[f].md5valid) then continue;
- if (MD5Match(knownFiles[f].md5, resMd5)) then
- begin
- result := knownFiles[f].diskName;
- exit;
- end;
- end;
- //resStream := createDiskFile(GameDir+'/wads/'+mapData.ExternalResources[i].Name);
end;
function g_Res_SearchSameWAD (const path, filename: AnsiString; const resMd5: TMD5Digest): AnsiString;
begin
- scanDir(path, false);
- result := getKnownFileWithMD5(path, filename, resMd5);
+ result := scanDir(path, filename, resMd5);
end;
resList: TStringList;
f, res: Integer;
strm: TStream;
- mmd5: TMD5Digest;
fname: AnsiString;
- idx: Integer;
wadname: AnsiString;
begin
//SetLength(mapData.ExternalResources, 0);
result := '';
exit;
end;
- mmd5 := MD5File(fname);
- if (not MD5Match(mmd5, mapHash)) then
- begin
- e_WriteLog('error downloading map file `'+FileName+'` (bad hash)', TMsgType.Fatal);
- result := '';
- exit;
- end;
- idx := addKnownFile(fname);
- if (idx < 0) then
- begin
- e_WriteLog('error downloading map file `'+FileName+'`', TMsgType.Fatal);
- result := '';
- exit;
- end;
- knownFiles[idx].md5 := mmd5;
- knownFiles[idx].md5valid := true;
result := fname;
end;
else
begin
fname := GameDir+'/wads/downloads/'+tf.diskName;
+ e_LogWritefln('downloading resource `%s` to `%s`...', [tf.diskName, fname]);
try
strm := createDiskFile(fname);
except
result := '';
exit;
end;
- idx := addKnownFile(fname);
- if (idx < 0) then
- begin
- e_WriteLog('error downloading map file `'+FileName+'`', TMsgType.Fatal);
- result := '';
- exit;
- end;
- knownFiles[idx].md5 := tf.hash;
- knownFiles[idx].md5valid := true;
g_Res_PutReplacementWad(tf.diskName, fname);
end;
end;
diff --git a/src/shared/utils.pas b/src/shared/utils.pas
index 5cd2af8831b8e7a1673338b1895691610f7f463a..a854ca45bc922f155465ed98a32daad0710ced8c 100644 (file)
--- a/src/shared/utils.pas
+++ b/src/shared/utils.pas
@@ -104,6 +104,8 @@ function findFileCI (var pathname: AnsiString; lastIsDir: Boolean=false): Boolea
// return fixed AnsiString or empty AnsiString
function findDiskWad (fname: AnsiString): AnsiString;
+// slashes must be normalized!
+function isWadNamesEqu (wna, wnb: AnsiString): Boolean;
// they throws
function openDiskFileRO (pathname: AnsiString): TStream;
const fileExtensions: array [0..6] of AnsiString = ('.dfz', '.wad', '.dfwad', '.pk3', '.pak', '.zip', '.dfzip');
+function isWadNamesEqu (wna, wnb: AnsiString): Boolean;
+var
+ ext, newExt: AnsiString;
+ found: Boolean;
+begin
+ result := StrEquCI1251(wna, wnb);
+ if result then exit;
+ // check first ext
+ ext := getFilenameExt(wna);
+ found := false;
+ for newExt in fileExtensions do if (StrEquCI1251(ext, newExt)) then begin found := true; break; end;
+ if not found then exit;
+ // check second ext
+ ext := getFilenameExt(wnb);
+ found := false;
+ for newExt in fileExtensions do if (StrEquCI1251(ext, newExt)) then begin found := true; break; end;
+ if not found then exit;
+ wna := forceFilenameExt(wna, '');
+ wnb := forceFilenameExt(wnb, '');
+ result := StrEquCI1251(wna, wnb);
+end;
+
function findDiskWad (fname: AnsiString): AnsiString;
var
origExt: AnsiString = '';