DEADSOFTWARE

put "{$MODE ...}" directive in each source file; removed trailing spaces, and convert...
[d2df-sdl.git] / src / game / g_res_downloader.pas
1 {$MODE DELPHI}
2 unit g_res_downloader;
4 interface
6 uses sysutils, Classes, md5, g_net, g_netmsg, g_console, g_main, e_log;
8 function g_Res_SearchSameWAD(const path, filename: string; const resMd5: TMD5Digest): string;
9 function g_Res_DownloadWAD(const FileName: string): string;
11 implementation
13 uses g_language, sfs, utils, wadreader;
15 const DOWNLOAD_DIR = 'downloads';
17 procedure FindFiles(const dirName, filename: string; var files: TStringList);
18 var
19 searchResult: TSearchRec;
20 begin
21 if FindFirst(dirName+'/*', faAnyFile, searchResult) = 0 then
22 begin
23 try
24 repeat
25 if (searchResult.Attr and faDirectory) = 0 then
26 begin
27 if StrEquCI1251(searchResult.Name, filename) then
28 begin
29 files.Add(dirName+'/'+filename);
30 Exit;
31 end;
32 end
33 else if (searchResult.Name <> '.') and (searchResult.Name <> '..') then
34 FindFiles(IncludeTrailingPathDelimiter(dirName)+searchResult.Name, filename, files);
35 until FindNext(searchResult) <> 0;
36 finally
37 FindClose(searchResult);
38 end;
39 end;
40 end;
42 function CompareFileHash(const filename: string; const resMd5: TMD5Digest): Boolean;
43 var
44 gResHash: TMD5Digest;
45 fname: string;
46 begin
47 fname := findDiskWad(filename);
48 if length(fname) = 0 then begin result := false; exit; end;
49 gResHash := MD5File(fname);
50 Result := MD5Match(gResHash, resMd5);
51 end;
53 function CheckFileHash(const path, filename: string; const resMd5: TMD5Digest): Boolean;
54 var
55 fname: string;
56 begin
57 fname := findDiskWad(path+filename);
58 if length(fname) = 0 then begin result := false; exit; end;
59 Result := FileExists(fname) and CompareFileHash(fname, resMd5);
60 end;
62 function g_Res_SearchSameWAD(const path, filename: string; const resMd5: TMD5Digest): string;
63 var
64 res: string;
65 files: TStringList;
66 i: Integer;
67 begin
68 Result := '';
70 if CheckFileHash(path, filename, resMd5) then
71 begin
72 Result := path + filename;
73 Exit;
74 end;
76 files := TStringList.Create;
78 FindFiles(path, filename, files);
79 for i := 0 to files.Count - 1 do
80 begin
81 res := files.Strings[i];
82 if CompareFileHash(res, resMd5) then
83 begin
84 Result := res;
85 Break;
86 end;
87 end;
89 files.Free;
90 end;
92 function SaveWAD(const path, filename: string; const data: array of Byte): string;
93 var
94 resFile: TStream;
95 dpt: string;
96 begin
97 try
98 result := path+DOWNLOAD_DIR+'/'+filename;
99 dpt := path+DOWNLOAD_DIR;
100 if not findFileCI(dpt, true) then CreateDir(dpt);
101 resFile := createDiskFile(result);
102 resFile.WriteBuffer(data[0], Length(data));
103 resFile.Free
104 except
105 Result := '';
106 end;
107 end;
109 function g_Res_DownloadWAD(const FileName: string): string;
110 var
111 msgStream: TMemoryStream;
112 resStream: TStream;
113 mapData: TMapDataMsg;
114 i: Integer;
115 resData: TResDataMsg;
116 begin
117 SetLength(mapData.ExternalResources, 0);
118 g_Console_Add(Format(_lc[I_NET_MAP_DL], [FileName]));
119 e_WriteLog('Downloading map `' + FileName + '` from server', MSG_NOTIFY);
120 MC_SEND_MapRequest();
122 msgStream := g_Net_Wait_Event(NET_MSG_MAP_RESPONSE);
123 if msgStream <> nil then
124 begin
125 mapData := MapDataFromMsgStream(msgStream);
126 msgStream.Free;
127 end;
129 for i := 0 to High(mapData.ExternalResources) do
130 begin
131 if not CheckFileHash(GameDir + '/wads/',
132 mapData.ExternalResources[i].Name,
133 mapData.ExternalResources[i].md5) then
134 begin
135 g_Console_Add(Format(_lc[I_NET_WAD_DL],
136 [mapData.ExternalResources[i].Name]));
137 e_WriteLog('Downloading Wad `' + mapData.ExternalResources[i].Name +
138 '` from server', MSG_NOTIFY);
139 MC_SEND_ResRequest(mapData.ExternalResources[i].Name);
141 msgStream := g_Net_Wait_Event(NET_MSG_RES_RESPONSE);
142 resData := ResDataFromMsgStream(msgStream);
144 resStream := createDiskFile(GameDir+'/wads/'+mapData.ExternalResources[i].Name);
145 resStream.WriteBuffer(resData.FileData[0], resData.FileSize);
147 resData.FileData := nil;
148 resStream.Free;
149 msgStream.Free;
150 end;
151 end;
153 Result := SaveWAD(MapsDir, ExtractFileName(FileName), mapData.FileData);
154 end;
156 end.