04048b693c983c558af1c61168f3948eee2c5823
1 (* Copyright (C) Doom 2D: Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License ONLY.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 {$INCLUDE ../shared/a_modes.inc}
16 unit g_res_downloader
;
20 uses sysutils
, Classes
, md5
, g_net
, g_netmsg
, g_console
, g_main
, e_log
;
22 function g_Res_SearchSameWAD(const path
, filename
: string; const resMd5
: TMD5Digest
): string;
23 function g_Res_DownloadWAD(const FileName
: string): string;
27 uses g_language
, sfs
, utils
, wadreader
, g_game
;
29 const DOWNLOAD_DIR
= 'downloads';
31 procedure FindFiles(const dirName
, filename
: string; var files
: TStringList
);
33 searchResult
: TSearchRec
;
35 if FindFirst(dirName
+'/*', faAnyFile
, searchResult
) = 0 then
39 if (searchResult
.Attr
and faDirectory
) = 0 then
41 if StrEquCI1251(searchResult
.Name
, filename
) then
43 files
.Add(dirName
+'/'+filename
);
47 else if (searchResult
.Name
<> '.') and (searchResult
.Name
<> '..') then
48 FindFiles(IncludeTrailingPathDelimiter(dirName
)+searchResult
.Name
, filename
, files
);
49 until FindNext(searchResult
) <> 0;
51 FindClose(searchResult
);
56 function CompareFileHash(const filename
: string; const resMd5
: TMD5Digest
): Boolean;
61 fname
:= findDiskWad(filename
);
62 if length(fname
) = 0 then begin result
:= false; exit
; end;
63 gResHash
:= MD5File(fname
);
64 Result
:= MD5Match(gResHash
, resMd5
);
67 function CheckFileHash(const path
, filename
: string; const resMd5
: TMD5Digest
): Boolean;
71 fname
:= findDiskWad(path
+filename
);
72 if length(fname
) = 0 then begin result
:= false; exit
; end;
73 Result
:= FileExists(fname
) and CompareFileHash(fname
, resMd5
);
76 function g_Res_SearchSameWAD(const path
, filename
: string; const resMd5
: TMD5Digest
): string;
84 if CheckFileHash(path
, filename
, resMd5
) then
86 Result
:= path
+ filename
;
90 files
:= TStringList
.Create
;
92 FindFiles(path
, filename
, files
);
93 for i
:= 0 to files
.Count
- 1 do
95 res
:= files
.Strings
[i
];
96 if CompareFileHash(res
, resMd5
) then
106 function SaveWAD(const path
, filename
: string; const data
: array of Byte): string;
112 result
:= path
+DOWNLOAD_DIR
+'/'+filename
;
113 dpt
:= path
+DOWNLOAD_DIR
;
114 if not findFileCI(dpt
, true) then CreateDir(dpt
);
115 resFile
:= createDiskFile(result
);
116 resFile
.WriteBuffer(data
[0], Length(data
));
123 function g_Res_DownloadWAD(const FileName
: string): string;
125 msgStream
: TMemoryStream
;
127 mapData
: TMapDataMsg
;
129 resData
: TResDataMsg
;
131 SetLength(mapData
.ExternalResources
, 0);
132 g_Console_Add(Format(_lc
[I_NET_MAP_DL
], [FileName
]));
133 e_WriteLog('Downloading map `' + FileName
+ '` from server', TMsgType
.Notify
);
134 g_Game_SetLoadingText(FileName
+ '...', 0, False);
135 MC_SEND_MapRequest();
137 msgStream
:= g_Net_Wait_Event(NET_MSG_MAP_RESPONSE
);
138 if msgStream
<> nil then
140 mapData
:= MapDataFromMsgStream(msgStream
);
143 mapData
.FileSize
:= 0;
145 for i
:= 0 to High(mapData
.ExternalResources
) do
147 if not CheckFileHash(GameDir
+ '/wads/',
148 mapData
.ExternalResources
[i
].Name
,
149 mapData
.ExternalResources
[i
].md5
) then
151 g_Console_Add(Format(_lc
[I_NET_WAD_DL
],
152 [mapData
.ExternalResources
[i
].Name
]));
153 e_WriteLog('Downloading Wad `' + mapData
.ExternalResources
[i
].Name
+
154 '` from server', TMsgType
.Notify
);
155 g_Game_SetLoadingText(mapData
.ExternalResources
[i
].Name
+ '...', 0, False);
156 MC_SEND_ResRequest(mapData
.ExternalResources
[i
].Name
);
158 msgStream
:= g_Net_Wait_Event(NET_MSG_RES_RESPONSE
);
159 if msgStream
= nil then
162 resData
:= ResDataFromMsgStream(msgStream
);
164 resStream
:= createDiskFile(GameDir
+'/wads/'+mapData
.ExternalResources
[i
].Name
);
165 resStream
.WriteBuffer(resData
.FileData
[0], resData
.FileSize
);
167 resData
.FileData
:= nil;
173 Result
:= SaveWAD(MapsDir
, ExtractFileName(FileName
), mapData
.FileData
);
174 if mapData
.FileSize
= 0 then